Open pseudo-programmer42 opened 1 year ago
using namespace std::string_literals;
using namespace std::chrono_literals;
Window window = Window::Builder{
.window_size = {1920*2, 1080*2},
.full_screen = false,
}.create();
Shader skycube(root_path / "./shader/skycube.vert", root_path / "./shader/skycube.frag");
Shader skybox(root_path / "./shader/skybox.vert", root_path / "./shader/skybox.frag");
std::vector<std::filesystem::path> input_path = {
root_path / "./resource/skybox/right.jpg",
root_path / "./resource/skybox/left.jpg",
root_path / "./resource/skybox/top.jpg",
root_path / "./resource/skybox/bottom.jpg",
root_path / "./resource/skybox/front.jpg",
root_path / "./resource/skybox/back.jpg",
};
int w, h, c;
std::array<unsigned char*, 6> buffers;
// stbi_set_flip_vertically_on_load(true);
buffers[0] = stbi_load(input_path[0].string().data(), &w, &h, &c, 4);
buffers[1] = stbi_load(input_path[1].string().data(), &w, &h, &c, 4);
buffers[2] = stbi_load(input_path[2].string().data(), &w, &h, &c, 4);
buffers[3] = stbi_load(input_path[3].string().data(), &w, &h, &c, 4);
buffers[4] = stbi_load(input_path[4].string().data(), &w, &h, &c, 4);
buffers[5] = stbi_load(input_path[5].string().data(), &w, &h, &c, 4);
GLuint tx;
glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tx);
glTextureStorage2D(tx, 1, GL_RGBA8, w, h);
glTextureParameteri(tx, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteri(tx, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTextureParameteri(tx, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTextureParameteri(tx, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTextureParameteri(tx, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTextureSubImage3D(tx, 0, 0, 0, 0, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffers[0]);
glTextureSubImage3D(tx, 0, 0, 0, 1, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffers[1]);
glTextureSubImage3D(tx, 0, 0, 0, 2, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffers[2]);
glTextureSubImage3D(tx, 0, 0, 0, 3, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffers[3]);
glTextureSubImage3D(tx, 0, 0, 0, 4, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffers[4]);
glTextureSubImage3D(tx, 0, 0, 0, 5, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffers[5]);
glGenerateMipmap(tx);
stbi_image_free(buffers[0]);
stbi_image_free(buffers[1]);
stbi_image_free(buffers[2]);
stbi_image_free(buffers[3]);
stbi_image_free(buffers[4]);
stbi_image_free(buffers[5]);
Mesh box;
box.position.emplace_back(-1, -1, -1);
box.position.emplace_back( 1, -1, -1);
box.position.emplace_back( 1, 1, -1);
box.position.emplace_back(-1, 1, -1);
box.position.emplace_back(-1, -1, 1);
box.position.emplace_back( 1, -1, 1);
box.position.emplace_back( 1, 1, 1);
box.position.emplace_back(-1, 1, 1);
box.indices = {
0, 1, 2,
0, 2, 3,
3, 2, 6,
3, 6, 7,
0, 3, 7,
0, 7, 4,
0, 4, 5,
0, 5, 1,
1, 2, 6,
1, 6, 5,
4, 7, 6,
4, 6, 5,
};
box.normal = box.position;
box.enable_attrib();
float size = 2.0f;
Camera camera(
// {0.0f, 0.0f, 0.0f},
-UNIT_X * 5,
UNIT_X,
UNIT_Z,
{1280, 720},
size * 0.01f,
size * 100.0f
);
Mesh sphere = create_sphere(1, 30, 30);
Microseconds time(0);
std::chrono::time_point tp = std::chrono::high_resolution_clock::now();
Microseconds delta_time = 20ms;
window.loop(
[&]()
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE)) glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_W)) camera.move_forward(size * 0.05f);
if (glfwGetKey(window, GLFW_KEY_S)) camera.move_backward(size * 0.05f);
if (glfwGetKey(window, GLFW_KEY_A)) camera.move_left(size * 0.05f);
if (glfwGetKey(window, GLFW_KEY_D)) camera.move_right(size * 0.05f);
if (glfwGetKey(window, GLFW_KEY_SPACE)) camera.move_up(size * 0.05f);
if (glfwGetKey(window, GLFW_KEY_X)) camera.move_down(size * 0.05f);
if (glfwGetKey(window, GLFW_KEY_UP)) camera.pitch_up(0.05f);
if (glfwGetKey(window, GLFW_KEY_DOWN)) camera.pitch_down(0.05f);
if (glfwGetKey(window, GLFW_KEY_LEFT)) camera.turn_left(0.05f);
if (glfwGetKey(window, GLFW_KEY_RIGHT)) camera.turn_right(0.05f);
camera.update_all();
glClearColor(0.4f, 0.4f, 0.9f, 1.0f);
skybox.use();
glBindTextureUnit(1, tx);
skybox.set(1, 1);
skybox.set("view", glm::lookAt({0.0f, 0.0f, 0.0f}, camera.direction, camera.up));
skybox.set("projection", camera.projection);
skybox.set("model", glm::mat4(1.0f));
box.draw();
glClear(GL_DEPTH_BUFFER_BIT);
skycube.use();
glBindTextureUnit(1, tx);
skycube.set(1, 1);
camera.set_uniform(skycube);
skycube.set("model", glm::mat4(1.0f));
sphere.draw();
time += delta_time;
tp += delta_time;
std::this_thread::sleep_until(tp);
}
);
cube
#version 460 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
// model
layout (location = 11) uniform mat4 model;
// camera
layout (location = 21) uniform mat4 view;
layout (location = 22) uniform mat4 projection;
out vec3 v_normal;
out vec3 v_position;
const mat3 tr = mat3(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
v_normal = (model * vec4(position, 0.0f)).xyz;
v_position = (model * vec4(position, 1.0f)).xyz;
}
#version 460 core
layout (location = 1, binding = 1) uniform samplerCube cubemap;
out vec4 FragColor;
in vec3 v_normal;
in vec3 v_position;
layout (location = 52) uniform vec3 eye;
const float zero = 0.0f;
const float one = 1.0f;
const mat3 tr = mat3(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);
void main()
{
vec3 direction = tr * reflect(v_position - eye, normalize(v_normal));
FragColor = texture(cubemap, direction);
// FragColor = vec4(1, 1, 0, 1);
}
box
#version 460 core
layout (location = 0) in vec3 position;
// model
layout (location = 11) uniform mat4 model;
// camera
layout (location = 21) uniform mat4 view;
layout (location = 22) uniform mat4 projection;
out vec3 direction;
const mat3 tr = mat3(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
direction = tr * position;
}
#version 460 core
layout (location = 1, binding = 1) uniform samplerCube cubemap;
out vec4 FragColor;
in vec3 direction;
const float zero = 0.0f;
const float one = 1.0f;
void main()
{
FragColor = texture(cubemap, direction);
// FragColor = vec4(1, 1, 0, 1);
}
vertex shader:
fragment shader