pseudo-programmer42 / quasi-engine

0 stars 0 forks source link

cube map #4

Open pseudo-programmer42 opened 1 year ago

pseudo-programmer42 commented 1 year ago
using namespace std::string_literals;
using namespace std::chrono_literals;

Window window = Window::Builder{.full_screen = false}.create();
Shader shader(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 mesh;
mesh.position.emplace_back(-1, -1, -1);
mesh.position.emplace_back( 1, -1, -1);
mesh.position.emplace_back( 1,  1, -1);
mesh.position.emplace_back(-1,  1, -1);
mesh.position.emplace_back(-1, -1,  1);
mesh.position.emplace_back( 1, -1,  1);
mesh.position.emplace_back( 1,  1,  1);
mesh.position.emplace_back(-1,  1,  1);
mesh.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,
};
mesh.enable_attrib();
float size = 2.0f;
Camera camera(
    // {0.0f, 0.0f, 0.0f},
    -UNIT_X * 5,
    UNIT_X,
    UNIT_Y,
    {1280, 720},
    size * 0.01f,
    size * 100.0f
);

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);
        shader.use();
        glBindTextureUnit(1, tx);
        shader.set(1, 1);
        camera.set_uniform(shader);
        shader.set("model", glm::mat4(1.0f));
        mesh.draw();
        time += delta_time;
        tp += delta_time;
        std::this_thread::sleep_until(tp);
    }
);

vertex shader:

#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;

void main()
{
    gl_Position = projection * view * model * vec4(position, 1.0f);
    direction = position;
}

fragment shader

#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);
}
pseudo-programmer42 commented 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);
}