Support complex powers of z

This commit is contained in:
2025-01-18 15:17:47 +00:00
parent 2037786319
commit 9c903179cf
3 changed files with 106 additions and 35 deletions

81
main.c
View File

@@ -10,6 +10,7 @@
#include <GLFW/glfw3.h>
#include <assert.h>
#include <complex.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
@@ -26,6 +27,10 @@
#define MAX_SHADER_SIZE (8 * 1024)
#if defined(CPOW_DTHETA) && defined(POWRATE)
#error "Cannot define CPOW_DTHETA and POWRATE simulataneously"
#endif
typedef struct {
float width, height;
#ifdef JULIA
@@ -36,14 +41,23 @@ typedef struct {
struct {
float re, im;
} centre;
float scale;
#ifdef CPOW_DTHETA
struct {
float re, im;
} cpow;
#endif
#ifdef POWRATE
float zpow;
#endif
float scale;
} params_t;
static const char *layers[] = { "VK_LAYER_KHRONOS_validation" };
static const char *swapchain_ext_name = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
static const char *extensions[] = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
};
#define NEXTENSIONS (sizeof(extensions) / sizeof(extensions[0]))
// Initial parameters
static params_t params = {
@@ -67,10 +81,13 @@ static params_t params = {
#endif
},
#endif
.scale = 1.0,
#ifdef CPOW_DTHETA
.cpow = { .re = 2.0, .im = 0.0 },
#endif
#ifdef POWRATE
.zpow = 2.0,
#endif
.scale = 1.0,
};
static void
@@ -89,7 +106,7 @@ mouse_button_callback(GLFWwindow *window, int button, int action, int mods)
double zx = 4.0 * (x / params.width - 0.5);
double zy = 4.0 * (y / params.height - 0.5);
zx *= params.width / params.height;
zx = params.scale * zx + params.centre.re;
zy = params.scale * zy + params.centre.im;
@@ -192,6 +209,28 @@ int main(void)
}
assert(found_queue_family);
// Check that the physical device supports all extensions
uint32_t ext_count = EXT_PROP_BUFFER_SIZE;
VkExtensionProperties ext_props[EXT_PROP_BUFFER_SIZE];
result = vkEnumerateDeviceExtensionProperties(
physical_dev, NULL, &ext_count, ext_props);
assert(result == VK_SUCCESS);
bool supported[NEXTENSIONS] = { 0 };
for (unsigned i = 0; i < ext_count; ++i) {
for (unsigned j = 0; j < NEXTENSIONS; ++j) {
if (strcmp(extensions[j], ext_props[i].extensionName) == 0) {
supported[j] = true;
break;
}
}
}
for (unsigned j = 0; j < NEXTENSIONS; ++j) {
if (!supported[j]) {
fprintf(stderr, "Unsupported: %s\n", extensions[j]);
assert(false);
}
}
// Create the logical device and get the queue handle.
float queue_priority = 1.0;
const VkDeviceQueueCreateInfo queue_create_info = {
@@ -204,8 +243,8 @@ int main(void)
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pQueueCreateInfos = &queue_create_info,
.queueCreateInfoCount = 1,
.enabledExtensionCount = 1,
.ppEnabledExtensionNames = &swapchain_ext_name,
.enabledExtensionCount = NEXTENSIONS,
.ppEnabledExtensionNames = extensions,
};
VkDevice dev;
result = vkCreateDevice(physical_dev, &dev_create_info, NULL, &dev);
@@ -213,21 +252,6 @@ int main(void)
VkQueue queue;
vkGetDeviceQueue(dev, queue_family, 0, &queue);
// Check that the physical device has swap chain support
uint32_t ext_count = EXT_PROP_BUFFER_SIZE;
VkExtensionProperties ext_props[EXT_PROP_BUFFER_SIZE];
result = vkEnumerateDeviceExtensionProperties(
physical_dev, NULL, &ext_count, ext_props);
assert(result == VK_SUCCESS);
bool swapchain_support = false;
for (unsigned i = 0; i < ext_count; ++i) {
if (strcmp(swapchain_ext_name, ext_props[i].extensionName) == 0) {
swapchain_support = true;
break;
}
}
assert(swapchain_support);
// Select a surface format, preferring R8G8B8A8_SRGB with
// SRGB_NONLINEAR colour space.
uint32_t surface_fmt_count = SURFACE_FMT_BUFFER_SIZE;
@@ -534,8 +558,10 @@ int main(void)
params.width = (float)swapchain_extent.width;
params.height = (float)swapchain_extent.height;
#ifdef JULIA_DTHETA
const double dtheta = JULIA_DTHETA;
const double complex rotz = cexp(I * dtheta);
const double complex julia_rotz = cexp(I * JULIA_DTHETA);
#endif
#ifdef CPOW_DTHETA
const double complex cpow_rotz = cexp(I * CPOW_DTHETA);
#endif
while (!glfwWindowShouldClose(window)) {
@@ -617,7 +643,7 @@ int main(void)
#ifdef JULIA_DTHETA
double complex julia = params.julia.re + I * params.julia.im;
julia *= rotz;
julia *= julia_rotz;
params.julia.re = (float)creal(julia);
params.julia.im = (float)cimag(julia);
#endif
@@ -626,6 +652,13 @@ int main(void)
params.scale *= (1 - ZOOMRATE);
#endif
#ifdef CPOW_DTHETA
double complex cpow = params.cpow.re + I * params.cpow.im;
cpow *= cpow_rotz;
params.cpow.re = (float)creal(cpow);
params.cpow.im = (float)cimag(cpow);
#endif
#ifdef POWRATE
params.zpow += POWRATE;
#endif