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
assets/shaders/*.frag
assets/shaders/*.vert
assets/shaders/*.geom
)
foreach(SHADER_SOURCE ${SHADER_SOURCE_FILES})

View File

@ -77,7 +77,11 @@ void Input::handleMovementKeys(Renderer& ren) {
if (ImGui::GetIO().WantCaptureKeyboard)
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 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 {
.depthClampEnable = vk::False,
.polygonMode = vk::PolygonMode::eFill,
.cullMode = vk::CullModeFlagBits::eBack,
.cullMode = vk::CullModeFlagBits::eNone,
.frontFace = vk::FrontFace::eCounterClockwise,
.depthBiasEnable = vk::False,
.lineWidth = 1.0,

View File

@ -122,10 +122,10 @@ Renderer::Renderer(Window& win) : win(win) {
.pQueuePriorities = priorities,
};
/* enumerate available device features */
std::vector<const char*> req_dev_extensions;
req_dev_extensions.push_back("VK_KHR_swapchain");
req_dev_extensions.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
auto dev_extentions = phys_dev.enumerateDeviceExtensionProperties();
Log::info("%zu available device extensions\n", dev_extentions.size());
for (const auto& ext : dev_extentions) {
@ -141,6 +141,10 @@ Renderer::Renderer(Window& win) : win(win) {
"VK_LAYER_KHRONOS_validation"
};
const auto features = vk::PhysicalDeviceFeatures {
.geometryShader = vk::True,
};
auto dev_info = vk::DeviceCreateInfo {
.flags = vk::DeviceCreateFlagBits(0),
.queueCreateInfoCount = 1,
@ -149,6 +153,7 @@ Renderer::Renderer(Window& win) : win(win) {
.ppEnabledLayerNames = dev_layer_names.data(),
.enabledExtensionCount = static_cast<u32>(req_dev_extensions.size()),
.ppEnabledExtensionNames = req_dev_extensions.data(),
.pEnabledFeatures = &features,
};
dev = phys_dev.createDevice(dev_info);
@ -181,6 +186,7 @@ Renderer::Renderer(Window& win) : win(win) {
std::vector<Shader> shaders = {
{ 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 },
};
@ -191,17 +197,19 @@ Renderer::Renderer(Window& win) : win(win) {
/* initialize models */
// 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"));
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->update(0, *uniform_buffer);
pipeline->update(1, textures[0]);
shaders[0].cleanup();
shaders[1].cleanup();
for (auto& shader : shaders)
shader.cleanup();
ui = std::make_unique<UI>(this);
}
@ -263,7 +271,7 @@ void Renderer::draw() {
command_buffer->begin();
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}
};

View File

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

View File

@ -11,7 +11,7 @@
#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::CreateContext();
@ -90,6 +90,8 @@ void UI::newFrame() {
ImGui::Begin("Rendering Info", nullptr);
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("Phi", &info.cam.phi, 0.0, 360.0, "%.0f def");
ImGui::SliderFloat("cam.x", &info.cam.pos.x, -1e2, 1e2);

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

View File

@ -12,7 +12,8 @@ layout (set = 0, binding = 0) uniform Matrices {
};
void main() {
gl_Position = mvp * vec4(aPos, 1.0);
//gl_Position = mvp * vec4(aPos, 1.0);
gl_Position = vec4(aPos, 1.0);
texCoord = aTexCoord;
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[]) {
try {
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();
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
* 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;
case InputEvent::Tag::eEXIT:
win.close();
@ -41,9 +56,15 @@ int main(int argc, char* argv[]) {
case InputEvent::Tag::eBUTTON:
break;
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;
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;
}

View File

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