Created working geometry shader

This commit is contained in:
connellpaxton 2024-01-31 16:44:45 -05:00
parent 703fe88fa6
commit b6cf6c08c3
17 changed files with 99 additions and 20 deletions

View File

@ -27,6 +27,7 @@ add_executable (pleascach ${SOURCES})
file(GLOB SHADER_SOURCE_FILES file(GLOB SHADER_SOURCE_FILES
assets/shaders/*.frag assets/shaders/*.frag
assets/shaders/*.vert assets/shaders/*.vert
assets/shaders/*.geom
) )
foreach(SHADER_SOURCE ${SHADER_SOURCE_FILES}) foreach(SHADER_SOURCE ${SHADER_SOURCE_FILES})

View File

@ -77,7 +77,11 @@ void Input::handleMovementKeys(Renderer& ren) {
if (ImGui::GetIO().WantCaptureKeyboard) if (ImGui::GetIO().WantCaptureKeyboard)
return; return;
const auto forward = glm::vec3(glm::cos(ren.cam.phi), 0.0, glm::sin(ren.cam.phi)); glm::vec3 forward;
if (ren.flycam)
forward = glm::vec3(glm::sin(ren.cam.theta)*glm::cos(ren.cam.phi), glm::cos(ren.cam.theta), glm::sin(ren.cam.theta)*glm::sin(ren.cam.phi));
else
forward = glm::vec3(glm::cos(ren.cam.phi), 0.0, glm::sin(ren.cam.phi));
const auto right = glm::cross(forward, glm::vec3(0.0, 1.0, 0.0)); const auto right = glm::cross(forward, glm::vec3(0.0, 1.0, 0.0));
const auto speed = glfwGetKey(in, GLFW_KEY_LEFT_SHIFT)? 2.0f : 1.0f; const auto speed = glfwGetKey(in, GLFW_KEY_LEFT_SHIFT)? 2.0f : 1.0f;

View File

@ -83,7 +83,7 @@ GraphicsPipeline::GraphicsPipeline(vk::Device dev, const std::vector<Shader>& sh
const auto raster_info = vk::PipelineRasterizationStateCreateInfo { const auto raster_info = vk::PipelineRasterizationStateCreateInfo {
.depthClampEnable = vk::False, .depthClampEnable = vk::False,
.polygonMode = vk::PolygonMode::eFill, .polygonMode = vk::PolygonMode::eFill,
.cullMode = vk::CullModeFlagBits::eBack, .cullMode = vk::CullModeFlagBits::eNone,
.frontFace = vk::FrontFace::eCounterClockwise, .frontFace = vk::FrontFace::eCounterClockwise,
.depthBiasEnable = vk::False, .depthBiasEnable = vk::False,
.lineWidth = 1.0, .lineWidth = 1.0,

View File

@ -122,10 +122,10 @@ Renderer::Renderer(Window& win) : win(win) {
.pQueuePriorities = priorities, .pQueuePriorities = priorities,
}; };
/* enumerate available device features */
std::vector<const char*> req_dev_extensions; std::vector<const char*> req_dev_extensions;
req_dev_extensions.push_back("VK_KHR_swapchain"); req_dev_extensions.push_back("VK_KHR_swapchain");
req_dev_extensions.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME); req_dev_extensions.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
auto dev_extentions = phys_dev.enumerateDeviceExtensionProperties(); auto dev_extentions = phys_dev.enumerateDeviceExtensionProperties();
Log::info("%zu available device extensions\n", dev_extentions.size()); Log::info("%zu available device extensions\n", dev_extentions.size());
for (const auto& ext : dev_extentions) { for (const auto& ext : dev_extentions) {
@ -141,7 +141,11 @@ Renderer::Renderer(Window& win) : win(win) {
"VK_LAYER_KHRONOS_validation" "VK_LAYER_KHRONOS_validation"
}; };
auto dev_info = vk::DeviceCreateInfo{ const auto features = vk::PhysicalDeviceFeatures {
.geometryShader = vk::True,
};
auto dev_info = vk::DeviceCreateInfo {
.flags = vk::DeviceCreateFlagBits(0), .flags = vk::DeviceCreateFlagBits(0),
.queueCreateInfoCount = 1, .queueCreateInfoCount = 1,
.pQueueCreateInfos = &queue_info, .pQueueCreateInfos = &queue_info,
@ -149,6 +153,7 @@ Renderer::Renderer(Window& win) : win(win) {
.ppEnabledLayerNames = dev_layer_names.data(), .ppEnabledLayerNames = dev_layer_names.data(),
.enabledExtensionCount = static_cast<u32>(req_dev_extensions.size()), .enabledExtensionCount = static_cast<u32>(req_dev_extensions.size()),
.ppEnabledExtensionNames = req_dev_extensions.data(), .ppEnabledExtensionNames = req_dev_extensions.data(),
.pEnabledFeatures = &features,
}; };
dev = phys_dev.createDevice(dev_info); dev = phys_dev.createDevice(dev_info);
@ -181,6 +186,7 @@ Renderer::Renderer(Window& win) : win(win) {
std::vector<Shader> shaders = { std::vector<Shader> shaders = {
{ dev, "assets/shaders/basic.vert.spv", vk::ShaderStageFlagBits::eVertex }, { dev, "assets/shaders/basic.vert.spv", vk::ShaderStageFlagBits::eVertex },
{ dev, "assets/shaders/explode.geom.spv", vk::ShaderStageFlagBits::eGeometry },
{ dev, "assets/shaders/basic.frag.spv", vk::ShaderStageFlagBits::eFragment }, { dev, "assets/shaders/basic.frag.spv", vk::ShaderStageFlagBits::eFragment },
}; };
@ -191,17 +197,19 @@ Renderer::Renderer(Window& win) : win(win) {
/* initialize models */ /* initialize models */
// models.push_back(std::make_shared<Model>(phys_dev, dev, "assets/models/dragon.gltf")); // models.push_back(std::make_shared<Model>(phys_dev, dev, "assets/models/dragon.gltf"));
Timer model_timer;
models.push_back(std::make_shared<Model>(phys_dev, dev, "assets/models/dragon.gltf")); models.push_back(std::make_shared<Model>(phys_dev, dev, "assets/models/dragon.gltf"));
auto t = model_timer.stop();
Log::debug("#%zu vertex indices\n", models[0]->indices.size()); Log::debug("Models loaded in %lf milliseconds\n", model_timer.read());
pipeline = std::make_unique<GraphicsPipeline>(dev, shaders, swapchain->extent, *render_pass, bindings, *models[0]->vertex_buffer); pipeline = std::make_unique<GraphicsPipeline>(dev, shaders, swapchain->extent, *render_pass, bindings, *models[0]->vertex_buffer);
pipeline->update(0, *uniform_buffer); pipeline->update(0, *uniform_buffer);
pipeline->update(1, textures[0]); pipeline->update(1, textures[0]);
shaders[0].cleanup(); for (auto& shader : shaders)
shaders[1].cleanup(); shader.cleanup();
ui = std::make_unique<UI>(this); ui = std::make_unique<UI>(this);
} }
@ -263,7 +271,7 @@ void Renderer::draw() {
command_buffer->begin(); command_buffer->begin();
vk::ClearValue clear_values[] = { vk::ClearValue clear_values[] = {
vk::ClearColorValue(0.0f, 0.0f, 0.0f, 1.0f), vk::ClearColorValue(1.0f, 1.0f, 1.0f, 1.0f),
vk::ClearDepthStencilValue {.depth = 1.0f} vk::ClearDepthStencilValue {.depth = 1.0f}
}; };

View File

@ -63,4 +63,5 @@ struct Renderer {
Camera cam {}; Camera cam {};
bool capture_mouse = false; bool capture_mouse = false;
bool flycam = false;
}; };

View File

@ -11,7 +11,7 @@
#include <Scene/Camera.hpp> #include <Scene/Camera.hpp>
UI::UI(Renderer* ren) : info{ .cam = ren->cam }, dev(ren->dev) { UI::UI(Renderer* ren) : info{ .flycam = ren->flycam, .cam = ren->cam }, dev(ren->dev) {
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
@ -90,6 +90,8 @@ void UI::newFrame() {
ImGui::Begin("Rendering Info", nullptr); ImGui::Begin("Rendering Info", nullptr);
ImGui::Text("FPS: %f", info.fps); ImGui::Text("FPS: %f", info.fps);
ImGui::Checkbox("Fly Camera", &info.flycam);
ImGui::Text("Fly Camera mode: %b");
ImGui::SliderAngle("Theta", &info.cam.theta, 0.01, 179.9); ImGui::SliderAngle("Theta", &info.cam.theta, 0.01, 179.9);
ImGui::SliderAngle("Phi", &info.cam.phi, 0.0, 360.0, "%.0f def"); ImGui::SliderAngle("Phi", &info.cam.phi, 0.0, 360.0, "%.0f def");
ImGui::SliderFloat("cam.x", &info.cam.pos.x, -1e2, 1e2); ImGui::SliderFloat("cam.x", &info.cam.pos.x, -1e2, 1e2);

View File

@ -11,6 +11,7 @@ struct Camera;
struct UI { struct UI {
struct UI_Info { struct UI_Info {
float fps = 0.0; float fps = 0.0;
bool& flycam;
/* camera stuff */ /* camera stuff */
Camera& cam; Camera& cam;
} info; } info;

View File

@ -2,7 +2,6 @@
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#define WINDOW_PTR GLFWwindow*
#define INPUT_PTR GLFWwindow* #define INPUT_PTR GLFWwindow*
#include <Window/Window.hpp> #include <Window/Window.hpp>
#include <Input/Input.hpp> #include <Input/Input.hpp>

View File

@ -9,13 +9,11 @@
#include <Input/Input.hpp> #include <Input/Input.hpp>
#ifndef WINDOW_PTR
#define WINDOW_PTR void*
#endif
#define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS #define VULKAN_HPP_NO_STRUCT_CONSTRUCTORS
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
#include <GLFW/glfw3.h>
/* /*
* Window class - abstracts away implementation/platform-specific realities of window * Window class - abstracts away implementation/platform-specific realities of window
* *
@ -37,7 +35,7 @@ struct Window {
vk::SurfaceKHR getSurface(vk::Instance& inst); vk::SurfaceKHR getSurface(vk::Instance& inst);
std::unique_ptr<Input> getInput(); std::unique_ptr<Input> getInput();
WINDOW_PTR win = nullptr; GLFWwindow* win = nullptr;
private: private:
u32 width, height; u32 width, height;

View File

@ -12,7 +12,5 @@ layout (set = 0, binding = 0) uniform Matrices {
layout (set = 0, binding = 1) uniform sampler2D tex; layout (set = 0, binding = 1) uniform sampler2D tex;
void main() { void main() {
//FragColor = vec4(1.0); FragColor = vec4(0.0, 0.0, 0.0, 1.0);
FragColor = texture(tex, texCoord) * vec4(norm, 1.0);
// FragColor = vec4(texCoord, 0.0, 1.0);
} }

Binary file not shown.

View File

@ -12,7 +12,8 @@ layout (set = 0, binding = 0) uniform Matrices {
}; };
void main() { void main() {
gl_Position = mvp * vec4(aPos, 1.0); //gl_Position = mvp * vec4(aPos, 1.0);
gl_Position = vec4(aPos, 1.0);
texCoord = aTexCoord; texCoord = aTexCoord;
norm = aNorm; norm = aNorm;
} }

Binary file not shown.

View File

@ -0,0 +1,44 @@
#version 450 core
layout (triangles) in;
layout (triangle_strip) out;
layout (max_vertices = 3) out;
layout (location = 0) in vec3 norm[];
layout (location = 1) in vec2 texCoord[];
layout (location = 0) out vec3 _norm;
layout (location = 1) out vec2 _texCoord;
layout (set = 0, binding = 0) uniform Matrices {
mat4 mvp;
float time;
};
vec4 explode(vec4 pos, vec3 n) {
float mag = 2.0;
vec3 dir = n * (time-3.0)/10.0 * mag;
return pos + vec4(dir, 0.0);
}
void main(void) {
if (time < 3.0) {
for(int i = 0; i < gl_in.length(); i++) {
gl_Position = mvp * gl_in[i].gl_Position;
_norm = norm[i];
_texCoord = texCoord[i];
EmitVertex();
}
EndPrimitive();
return;
}
vec3 n = norm[0] + norm[1] + norm[2];
n/=3;
for(int i = 0; i < gl_in.length(); i++) {
gl_Position = mvp * explode(gl_in[i].gl_Position, n);
_texCoord = texCoord[i];
_norm = n;
EmitVertex();
}
EndPrimitive();
}

Binary file not shown.

View File

@ -13,6 +13,11 @@
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
try { try {
Window win(argv[0], 256, 512); Window win(argv[0], 256, 512);
auto mon = glfwGetPrimaryMonitor();
auto v = glfwGetVideoMode(mon);
glfwSetWindowMonitor(win.win, mon, 0, 0, v->width, v->height, v->refreshRate);
auto in = win.getInput(); auto in = win.getInput();
Renderer ren(win); Renderer ren(win);
@ -31,6 +36,16 @@ int main(int argc, char* argv[]) {
/* no need to have a resize() function in the renderer, b/c swapchain images will be /* no need to have a resize() function in the renderer, b/c swapchain images will be
* automatically marked out-of-date, and recreation will be triggered in our code * automatically marked out-of-date, and recreation will be triggered in our code
*/ */
/* but still block while waiting for window to be opened again */
if (event.resize.height == 0 || event.resize.width == 0) {
int h = event.resize.height;
int w = event.resize.width;
do {
glfwPollEvents();
glfwGetWindowSize(win.win, &w, &h);
} while (h * w == 0);
}
break; break;
case InputEvent::Tag::eEXIT: case InputEvent::Tag::eEXIT:
win.close(); win.close();
@ -41,9 +56,15 @@ int main(int argc, char* argv[]) {
case InputEvent::Tag::eBUTTON: case InputEvent::Tag::eBUTTON:
break; break;
case InputEvent::Tag::eKEY: case InputEvent::Tag::eKEY:
if (event.key.key == GLFW_KEY_ESCAPE && event.key.state == GLFW_PRESS) { if (event.key.key == GLFW_KEY_Q) {
return 0;
} else if (event.key.key == GLFW_KEY_ESCAPE && event.key.state == GLFW_PRESS) {
ren.capture_mouse = !ren.capture_mouse; ren.capture_mouse = !ren.capture_mouse;
in->setCursor(!ren.capture_mouse); in->setCursor(!ren.capture_mouse);
} else if (event.key.key == GLFW_KEY_R && event.key.state == GLFW_PRESS) {
ren.frame = 0;
} else if (event.key.key == GLFW_KEY_C && event.key.state == GLFW_PRESS) {
ren.flycam = !ren.flycam;
} }
break; break;
} }

View File

@ -21,6 +21,7 @@ struct Timer {
start(); start();
} }
/* returns time in milliseconds */
inline double read() { inline double read() {
if (running) { if (running) {
auto end = std::chrono::steady_clock::now(); auto end = std::chrono::steady_clock::now();