Skip to content
Snippets Groups Projects
Commit 3e56c80c authored by Simon Oehrl's avatar Simon Oehrl
Browse files

Implement screen-tearing test

parent 986d8c4f
No related branches found
No related tags found
No related merge requests found
...@@ -666,7 +666,7 @@ option(LIBLAVA_TEMPLATE "Enable Template" TRUE) ...@@ -666,7 +666,7 @@ option(LIBLAVA_TEMPLATE "Enable Template" TRUE)
if(LIBLAVA_TEMPLATE) if(LIBLAVA_TEMPLATE)
message("========================================================================") message("========================================================================")
set(LIBLAVA_TEMPLATE_NAME "template" CACHE STRING "Name of template using liblava") set(LIBLAVA_TEMPLATE_NAME "screen-tearer" CACHE STRING "Name of template using liblava")
message("> ${LIBLAVA_TEMPLATE_NAME}") message("> ${LIBLAVA_TEMPLATE_NAME}")
......
...@@ -150,6 +150,12 @@ bool app::setup() { ...@@ -150,6 +150,12 @@ bool app::setup() {
update(); update();
render(); render();
bool fullscreen = false;
cmd_line({ "-fs", "--fullscreen" }) >> fullscreen;
spdlog::info("Fullscreen: {}", fullscreen);
window.set_fullscreen(fullscreen);
add_run_end([&]() { add_run_end([&]() {
camera.destroy(); camera.destroy();
......
/** /**
* @file main.cpp * @file liblava-demo/shapes.cpp
* @brief Template * @brief Shapes demo
* @authors Lava Block OÜ and contributors * @authors Lava Block OÜ and contributors
* @copyright Copyright (c) 2018-present, MIT License * @copyright Copyright (c) 2018-present, MIT License
*/ */
#include <imgui.h> #include <imgui.h>
#include <GLFW/glfw3.h>
#include <liblava/lava.hpp> #include <liblava/lava.hpp>
using namespace lava; using namespace lava;
std::string get_video_mode_string(const GLFWvidmode& mode) {
return fmt::format("{}x{}@{}Hz Bit Depth(R/G/B): {}/{}/{}", mode.width, mode.height, mode.refreshRate, mode.redBits, mode.greenBits, mode.blueBits);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
app app("template", { argc, argv }); app app("lava shapes", { argc, argv });
if (!app.setup()) if (!app.setup())
return error::not_ready; return error::not_ready;
int monitor_count;
GLFWmonitor** monitors = glfwGetMonitors(&monitor_count);
spdlog::info("------");
for (int i = 0; i < monitor_count; ++i) {
const auto monitor = monitors[i];
spdlog::info("Monitor {}", glfwGetMonitorName(monitor));
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
spdlog::info("Active mode: {}", get_video_mode_string(*mode));
int video_mode_count;
const GLFWvidmode* modes = glfwGetVideoModes(monitor, &video_mode_count);
spdlog::info("Supported video modes:");
for (int j = 0; j < video_mode_count; ++j) {
spdlog::info("- {}", get_video_mode_string(modes[j]));
}
spdlog::info("------");
}
// app.window.set_fullscreen(true);
// Initialize camera
app.camera.position = v3(0.f, -2.f, 8.f);
app.camera.rotation = v3(0.f, 0.f, 0.f); // Degrees
// All shapes will share the same world-space matrix in this example
mat4 world_matrix = glm::identity<mat4>();
// world_matrix = glm::translate(world_matrix, v3(0, 1, 0));
world_matrix = glm::scale(world_matrix, v3(1, 50, 1));
v3 rotation_vector = v3{ 0, 0, 0 };
buffer world_matrix_buffer;
if (!world_matrix_buffer.create_mapped(app.device, &world_matrix, sizeof(world_matrix),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT))
return error::create_failed;
// All shapes will share the same rotation value
buffer rotation_buffer;
if (!rotation_buffer.create_mapped(app.device, &rotation_vector, sizeof(rotation_vector),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT))
return error::create_failed;
mesh::ptr quad;
quad = create_mesh(app.device, mesh_type::quad);
for (auto& vertex : quad->get_vertices()) {
vertex.color = v4(1.0, 1.0, 1.0, 1.0);
}
if (!quad)
return error::create_failed;
quad->reload();
// A descriptor is needed for representing the world-space matrix
descriptor::ptr descriptor;
descriptor::pool::ptr descriptor_pool;
VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
graphics_pipeline::ptr pipeline;
pipeline_layout::ptr layout;
app.on_create = [&]() {
pipeline = make_graphics_pipeline(app.device);
pipeline->add_color_blend_attachment();
pipeline->set_depth_test_and_write();
pipeline->set_depth_compare_op(VK_COMPARE_OP_LESS_OR_EQUAL);
// All shapes use the same simple shaders
if (!pipeline->add_shader(file_data("shapes/vertex.spirv"), VK_SHADER_STAGE_VERTEX_BIT))
return false;
if (!pipeline->add_shader(file_data("shapes/fragment.spirv"), VK_SHADER_STAGE_FRAGMENT_BIT))
return false;
pipeline->set_vertex_input_binding({ 0, sizeof(vertex), VK_VERTEX_INPUT_RATE_VERTEX });
// Only send position and color to shaders for this demo
// TODO: Update this comment
pipeline->set_vertex_input_attributes({
{ 0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(vertex, position) },
{ 1, 0, VK_FORMAT_R32G32B32A32_SFLOAT, offsetof(vertex, color) },
{ 2, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(vertex, normal) },
});
// Descriptor sets must be made to transfer the shapes' world matrix and the camera's
// view matrix to the physical device
descriptor = make_descriptor();
descriptor->add_binding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_SHADER_STAGE_VERTEX_BIT); // View matrix
descriptor->add_binding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_SHADER_STAGE_VERTEX_BIT); // World matrix
descriptor->add_binding(2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_SHADER_STAGE_VERTEX_BIT); // Rotation vector
if (!descriptor->create(app.device))
return false;
descriptor_pool = make_descriptor_pool();
if (!descriptor_pool->create(app.device, { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3 } }))
return false;
layout = make_pipeline_layout();
layout->add(descriptor);
if (!layout->create(app.device))
return false;
pipeline->set_layout(layout);
descriptor_set = descriptor->allocate(descriptor_pool->get());
VkWriteDescriptorSet const write_desc_ubo_camera{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = descriptor_set,
.dstBinding = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = app.camera.get_descriptor_info(),
};
VkWriteDescriptorSet const write_desc_ubo_world{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = descriptor_set,
.dstBinding = 1,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = world_matrix_buffer.get_descriptor_info(),
};
VkWriteDescriptorSet const write_desc_ubo_rotation{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = descriptor_set,
.dstBinding = 2,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = rotation_buffer.get_descriptor_info(),
};
app.device->vkUpdateDescriptorSets({ write_desc_ubo_camera, write_desc_ubo_world,
write_desc_ubo_rotation });
render_pass::ptr render_pass = app.shading.get_pass();
if (!pipeline->create(render_pass->get()))
return false;
// Push this render pass to the pipeline
render_pass->add_front(pipeline);
pipeline->on_process = [&](VkCommandBuffer cmd_buf) {
layout->bind(cmd_buf, descriptor_set);
quad->bind_draw(cmd_buf);
return true;
};
return true;
};
app.on_destroy = [&]() {
descriptor->free(descriptor_set, descriptor_pool->get());
descriptor_pool->destroy();
descriptor->destroy();
pipeline->destroy();
layout->destroy();
};
app.imgui.on_draw = [&]() {
ImGui::Begin(app.get_name());
app.draw_about();
ImGui::End();
};
app.on_update = [&](delta dt) {
// rotation_vector += v3{ 0, 10.f, 0 } * dt;
// memcpy(as_ptr(rotation_buffer.get_mapped_data()), &rotation_vector, sizeof(rotation_vector));
app.camera.position.x += 50 * dt;
while (app.camera.position.x > 5) {
app.camera.position.x -= 10;
}
if (app.camera.activated())
app.camera.update_view(to_dt(app.run_time.delta), app.input.get_mouse_position());
return true;
};
app.add_run_end([&]() {
quad->destroy();
});
return app.run(); return app.run();
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment