Support complex powers of z
This commit is contained in:
81
main.c
81
main.c
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user