From 3e86e4207670c3c13d5bbcc3563e92543cd5edf5 Mon Sep 17 00:00:00 2001 From: itycodes Date: Mon, 20 May 2024 23:22:47 +0200 Subject: [PATCH] Initial commit --- Makefile | 26 ++ frag.frag | 19 + main.c | 1137 ++++++++++++++++++++++++++++++++++++++++++++++ vert-inline.vert | 42 ++ vert.vert | 109 +++++ 5 files changed, 1333 insertions(+) create mode 100644 Makefile create mode 100644 frag.frag create mode 100644 main.c create mode 100644 vert-inline.vert create mode 100644 vert.vert diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..05e745c --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +.PHONY: run clean + +SHADERS = vert.spv frag.spv +CC = gcc +LIBS = -lvulkan -lglfw -lm +CFLAGS = $(LIBS) +OUT = main +SRC = main.c + +all: $(SHADERS) $(OUT) + +$(OUT): $(SRC) + $(CC) $(CFLAGS) $(SRC) -o $(OUT) + +run: all + ./$(OUT) + +clean: + rm $(SHADERS) + rm $(OUT) + +%.spv: %.vert + glslc $< -o $@ + +%.spv: %.frag + glslc $< -o $@ diff --git a/frag.frag b/frag.frag new file mode 100644 index 0000000..fd240ff --- /dev/null +++ b/frag.frag @@ -0,0 +1,19 @@ +#version 450 + +layout(location = 0) out vec4 outColor; + +layout(location = 0) in vec4 normal; +layout(location = 1) in vec4 pos_pre; + +layout(push_constant, std430) uniform pc { + layout(offset=80) vec4 data; +}; + +void main() { + outColor = vec4(data.rgb*(1.0+dot(normal.xyz, normalize(vec3(-0.7, -0.5, -0.1))))/2.0, 1.0); +//if(pos_post.z <= 0.0) { +// outColor = vec4(1.0); +//} + //outColor = normal.xyz; + //outColor = vec4(vec3(1.0-gl_FragCoord.z), 1.0); +} diff --git a/main.c b/main.c new file mode 100644 index 0000000..f4c6f4b --- /dev/null +++ b/main.c @@ -0,0 +1,1137 @@ +#include +#include + +#include +#include + +#include + +#include + +#include + +#include + +#include + +#define MESH_SIZE 36*2*4*4 + +float pos_y = 0.0; +float pos_z = 0.0; +float pos_x = 0.0; +float rot_y = 0.0; +float rot_x = 0.0; +uint8_t key_pressed[10]; + +unsigned long long get_time() { + struct timeval tv; + gettimeofday(&tv, NULL); + unsigned long long unix_us = tv.tv_sec * 1000000 + tv.tv_usec; + return unix_us; +} + +void key_callback(GLFWwindow* win, int key, int scancode, int action, int mods) { + if(key == GLFW_KEY_SPACE) { + key_pressed[0] = action; + } + if(key == GLFW_KEY_LEFT_SHIFT) { + key_pressed[1] = action; + } + if(key == GLFW_KEY_Q) { + key_pressed[2] = action; + } + if(key == GLFW_KEY_E) { + key_pressed[3] = action; + } + if(key == GLFW_KEY_W) { + key_pressed[4] = action; + } + if(key == GLFW_KEY_S) { + key_pressed[5] = action; + } + if(key == GLFW_KEY_A) { + key_pressed[6] = action; + } + if(key == GLFW_KEY_D) { + key_pressed[7] = action; + } + if(key == GLFW_KEY_R) { + key_pressed[8] = action; + } + if(key == GLFW_KEY_F) { + key_pressed[9] = action; + } +} + +int main() { + //glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND); + uint32_t glfw_res = glfwInit(); + printf("glfwInit: (%d)\n", glfw_res); + //glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); + GLFWwindow* win = glfwCreateWindow(1920, 1080, "Hi!", NULL, NULL); + glfwSetKeyCallback(win, key_callback); +//printf("glfwCreateWindow: %s", win == NULL ? "NULL" : "SUCCESS"); + printf("Start App\n"); + printf("VK_API: %u\n", VK_API_VERSION_1_0); + + VkApplicationInfo application_info = { + VK_STRUCTURE_TYPE_APPLICATION_INFO, + NULL, + "Hello Vulkan", + VK_MAKE_VERSION( 1, 0, 0 ), + "Hello Engine", + VK_MAKE_VERSION( 1, 0, 0 ), + VK_API_VERSION_1_0 // 4194304, + }; + uint32_t glfw_exts_count = 0; + const char** glfw_exts = glfwGetRequiredInstanceExtensions(&glfw_exts_count); + for(int i = 0; i < glfw_exts_count; i++) { + printf("Using Ext %s\n", glfw_exts[i]); + } + VkInstanceCreateInfo instance_create_info = { + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + NULL, + 0, + &application_info, + 0, + NULL, + glfw_exts_count, + glfw_exts + }; + VkResult res; + + VkInstance vkins; + printf("CreateInstance: (%ld)\n", vkCreateInstance(&instance_create_info, NULL, &vkins)); + + VkSurfaceKHR surface; + { + res = glfwCreateWindowSurface(vkins, win, NULL, &surface); + printf("CreateWindowSurface: (%ld)\n", res); + } + + VkPhysicalDevice pdev; + { + uint32_t num_d = 0; + res = vkEnumeratePhysicalDevices(vkins, &num_d, NULL); + printf("EnumeratePhysicalDevices 1: (%ld) %lu\n", res, num_d); + + VkPhysicalDevice* phys_devs = malloc(sizeof(VkPhysicalDevice) * num_d); + res = vkEnumeratePhysicalDevices(vkins, &num_d, &phys_devs[0]); + printf("EnumeratePhysicalDevices 2: (%ld) %lu\n", res, num_d); + + pdev = phys_devs[1]; + } + + { + VkPhysicalDeviceProperties dev_props; + + vkGetPhysicalDeviceProperties(pdev, &dev_props); + printf("Vulkan v%lu.%lu.%lu at %s\n", + VK_VERSION_MAJOR(dev_props.apiVersion), + VK_VERSION_MINOR(dev_props.apiVersion), + VK_VERSION_PATCH(dev_props.apiVersion), + dev_props.deviceName); + } + + uint32_t q_graphic = 0; + { + uint32_t num_q = 0; + vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_q, NULL); + printf("GetPhysicalDeviceQueueFamilyProperties 1: %lu\n", num_q); + + VkQueueFamilyProperties* qfam_props = malloc(sizeof(VkQueueFamilyProperties) * num_q); + vkGetPhysicalDeviceQueueFamilyProperties(pdev, &num_q, &qfam_props[0]); + printf("GetPhysicalDeviceQueueFamilyProperties 2: %lu\n", num_q); + + for(int i = 0; i < num_q; i++) { + VkQueueFlags flags = qfam_props[i].queueFlags; + if((flags & VK_QUEUE_GRAPHICS_BIT) != 0) { + q_graphic = i; + } + printf("Queue Family %d: %lu Qs G:%d, C:%d, T:%d\n", i, qfam_props[i].queueCount, + (flags & VK_QUEUE_GRAPHICS_BIT) != 0, + (flags & VK_QUEUE_COMPUTE_BIT) != 0, + (flags & VK_QUEUE_TRANSFER_BIT) != 0); + } + } + + VkDevice dev; + { + float q_prio = 1.0f; + VkDeviceQueueCreateInfo q_creat_info = { + VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, + NULL, + 0, + q_graphic, + 1, + &q_prio + }; + const char* const dev_extensions[] = {"VK_KHR_swapchain"}; + VkPhysicalDeviceFeatures features = {}; + vkGetPhysicalDeviceFeatures(pdev, &features); + +// if(features.depthClamp == VK_FALSE) { +// fprintf(stderr, "depthClamp is not supported!\n"); +// exit(1); +// } + + VkDeviceCreateInfo dev_creat_info = { + VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + NULL, + 0, + 1, + &q_creat_info, + 0, + NULL, + 1, + dev_extensions, + &features + }; + + res = vkCreateDevice(pdev, &dev_creat_info, NULL, &dev); + printf("CreateDevice: (%ld)\n", res); + } + + VkQueue queue; + vkGetDeviceQueue(dev, q_graphic, 0, &queue); + + VkCommandPoolCreateInfo cmd_pool_info = { + VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + NULL, + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + q_graphic + }; + + VkCommandPool pool; + res = vkCreateCommandPool(dev, &cmd_pool_info, NULL, &pool); + + printf("CreateCommandPool: (%ld)\n", res); + + VkCommandBufferAllocateInfo cmd_alloc_info = { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + NULL, + pool, + VK_COMMAND_BUFFER_LEVEL_PRIMARY, + 1 + }; + + VkCommandBuffer cmd_buf; + res = vkAllocateCommandBuffers(dev, &cmd_alloc_info, &cmd_buf); + + printf("AllocateCommandBuffers: (%ld)\n", res); + + printf("Finding Host Visible Memory:"); + uint32_t mem_inx = 0; + { + uint8_t sel = 0; + VkPhysicalDeviceMemoryProperties mem_props; + vkGetPhysicalDeviceMemoryProperties(pdev, &mem_props); + printf("Memory Type Count: %03d\n", mem_props.memoryTypeCount); + printf("Memory Heap Count: %03d\n", mem_props.memoryHeapCount); + for(int i = 0; i < mem_props.memoryTypeCount; i++) { + VkMemoryType mem_type = mem_props.memoryTypes[i]; + VkMemoryPropertyFlags flags = mem_type.propertyFlags; + VkMemoryHeap heap = mem_props.memoryHeaps[mem_type.heapIndex]; + if((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0 && + (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0 && + (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0) { + if(!sel) { + mem_inx = i; + sel = 1; + } + printf("Found Memory Type: "); + } else { + printf(" "); + } + + printf("Memory Type (%018p) %03d: SIZE: %lluMiB DLO:%d, HVI:%d, HCO:%d, HCA:%d, LAL:%d, PRO:%d\n", flags, i, heap.size/1024/1024, + (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0, + (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0, + (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0, + (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0, + (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0, + (flags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0); + } + } + printf("Selected Host Visible Memory Type: %03d\n", mem_inx); + + printf("Finding Host Invisible Memory:"); + uint32_t mem_depth_inx = 0; + { + uint8_t sel = 0; + VkPhysicalDeviceMemoryProperties mem_props; + vkGetPhysicalDeviceMemoryProperties(pdev, &mem_props); + printf("Memory Type Count: %03d\n", mem_props.memoryTypeCount); + printf("Memory Heap Count: %03d\n", mem_props.memoryHeapCount); + for(int i = 0; i < mem_props.memoryTypeCount; i++) { + VkMemoryType mem_type = mem_props.memoryTypes[i]; + VkMemoryPropertyFlags flags = mem_type.propertyFlags; + VkMemoryHeap heap = mem_props.memoryHeaps[mem_type.heapIndex]; + if((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0 && + (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0 && + (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0) { + if(!sel) { + mem_depth_inx = i; + sel = 1; + } + printf("Found Memory Type: "); + } else { + printf(" "); + } + + printf("Memory Type (%018p) %03d: SIZE: %lluMiB DLO:%d, HVI:%d, HCO:%d, HCA:%d, LAL:%d, PRO:%d\n", flags, i, heap.size/1024/1024, + (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0, + (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0, + (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0, + (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0, + (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0, + (flags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0); + } + } + printf("Selected Host Invisible Memory Type: %03d\n", mem_depth_inx); + VkDeviceMemory dmem; + { + VkMemoryAllocateInfo mem_alloc_info = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + NULL, + MESH_SIZE, + mem_inx + }; + res = vkAllocateMemory(dev, &mem_alloc_info, NULL, &dmem); + printf("AllocateMemory 1: (%ld)\n", res); + } + VkDeviceMemory depth_mem; + { + VkMemoryAllocateInfo mem_alloc_info = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + NULL, + 1920*1080*8, // idk, apparently in Vulkan sizeof(VK_FORMAT_D32_SFLOAT) = 8. + mem_depth_inx + }; + res = vkAllocateMemory(dev, &mem_alloc_info, NULL, &depth_mem); + printf("AllocateMemory 2: (%ld)\n", res); + } + VkImage depth_img; + { + VkImageCreateInfo img_creat_info = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + VK_IMAGE_TYPE_2D, + VK_FORMAT_D32_SFLOAT, + {1920, 1080, 1}, + 1, + 1, + VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 1, + &q_graphic, + VK_IMAGE_LAYOUT_UNDEFINED + }; + res = vkCreateImage(dev, &img_creat_info, NULL, &depth_img); + printf("CreateImage: (%ld)\n", res); + } + + { + res = vkBindImageMemory(dev, depth_img, depth_mem, 0); + printf("BindImageMemory: (%ld)\n", res); + } + + VkImageView depth_view; + { + VkImageViewCreateInfo image_info = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + depth_img, + VK_IMAGE_VIEW_TYPE_2D, + VK_FORMAT_D32_SFLOAT, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, + {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1} + }; + res = vkCreateImageView(dev, &image_info, NULL, &depth_view); + printf("CreateImageView 1: (%ld)\n", res); + } + + VkBuffer vbuf; + { + VkBufferCreateInfo buf_creat_info = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + MESH_SIZE, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL + }; + res = vkCreateBuffer(dev, &buf_creat_info, NULL, &vbuf); + printf("CreateBuffer: (%ld)\n", res); + } + { + res = vkBindBufferMemory(dev, vbuf, dmem, 0); + printf("BindBufferMemory: (%ld)\n", res); + } + char* buf_mem = malloc(MESH_SIZE); + memset(buf_mem, 0, MESH_SIZE); + { + res = vkMapMemory(dev, dmem, 0, VK_WHOLE_SIZE, 0, (void**)&buf_mem); + printf("MapMemory: (%ld)\n", res); + } + float positions[] = { + // BOTTOM + -0.5, 0.5, 1.0, 1.0, + 0.0, 1.0, 0.0, 0.0, + + 0.5, 0.5, 2.0, 1.0, + 0.0, 1.0, 0.0, 0.0, + + -0.5, 0.5, 2.0, 1.0, + 0.0, 1.0, 0.0, 0.0, + + + 0.5, 0.5, 1.0, 1.0, + 0.0, 1.0, 0.0, 0.0, + + 0.5, 0.5, 2.0, 1.0, + 0.0, 1.0, 0.0, 0.0, + + -0.5, 0.5, 1.0, 1.0, + 0.0, 1.0, 0.0, 0.0, + + + // TOP + 0.5, -0.5, 2.0, 1.0, + 0.0, -1.0, 0.0, 0.0, + + -0.5, -0.5, 1.0, 1.0, + 0.0, -1.0, 0.0, 0.0, + + -0.5, -0.5, 2.0, 1.0, + 0.0, -1.0, 0.0, 0.0, + + + 0.5, -0.5, 2.0, 1.0, + 0.0, -1.0, 0.0, 0.0, + + 0.5, -0.5, 1.0, 1.0, + 0.0, -1.0, 0.0, 0.0, + + -0.5, -0.5, 1.0, 1.0, + 0.0, -1.0, 0.0, 0.0, + + + // FRONT + -0.5, -0.5, 1.0, 1.0, + 0.0, 0.0, -1.0, 0.0, + + 0.5, 0.5, 1.0, 1.0, + 0.0, 0.0, -1.0, 0.0, + + -0.5, 0.5, 1.0, 1.0, + 0.0, 0.0, -1.0, 0.0, + + + 0.5, -0.5, 1.0, 1.0, + 0.0, 0.0, -1.0, 0.0, + + 0.5, 0.5, 1.0, 1.0, + 0.0, 0.0, -1.0, 0.0, + + -0.5, -0.5, 1.0, 1.0, + 0.0, 0.0, -1.0, 0.0, + + + // BACK + 0.5, 0.5, 2.0, 1.0, + 0.0, 0.0, 1.0, 0.0, + + -0.5, -0.5, 2.0, 1.0, + 0.0, 0.0, 1.0, 0.0, + + -0.5, 0.5, 2.0, 1.0, + 0.0, 0.0, 1.0, 0.0, + + + 0.5, 0.5, 2.0, 1.0, + 0.0, 0.0, 1.0, 0.0, + + 0.5, -0.5, 2.0, 1.0, + 0.0, 0.0, 1.0, 0.0, + + -0.5, -0.5, 2.0, 1.0, + 0.0, 0.0, 1.0, 0.0, + + // LEFT + -0.5, -0.5, 1.0, 1.0, + -1.0, 0.0, 0.0, 0.0, + + -0.5, 0.5, 2.0, 1.0, + -1.0, 0.0, 0.0, 0.0, + + -0.5, -0.5, 2.0, 1.0, + -1.0, 0.0, 0.0, 0.0, + + + -0.5, 0.5, 1.0, 1.0, + -1.0, 0.0, 0.0, 0.0, + + -0.5, 0.5, 2.0, 1.0, + -1.0, 0.0, 0.0, 0.0, + + -0.5, -0.5, 1.0, 1.0, + -1.0, 0.0, 0.0, 0.0, + + // RIGHT + 0.5, 0.5, 2.0, 1.0, + 1.0, 0.0, 0.0, 0.0, + + 0.5, -0.5, 1.0, 1.0, + 1.0, 0.0, 0.0, 0.0, + + 0.5, -0.5, 2.0, 1.0, + 1.0, 0.0, 0.0, 0.0, + + + 0.5, 0.5, 2.0, 1.0, + 1.0, 0.0, 0.0, 0.0, + + 0.5, 0.5, 1.0, 1.0, + 1.0, 0.0, 0.0, 0.0, + + 0.5, -0.5, 1.0, 1.0, + 1.0, 0.0, 0.0, 0.0, + }; + memcpy(buf_mem, positions, sizeof(positions)); + + FILE* vert_shader_file = fopen("./vert.spv", "r"); + if(vert_shader_file == NULL) { + perror("Failed to read vertex shader"); + exit(1); + } + fseek(vert_shader_file, 0, SEEK_END); + long vert_shader_size = ftell(vert_shader_file); + fseek(vert_shader_file, 0, SEEK_SET); + uint8_t* vert_shader_bytes = malloc(vert_shader_size); + fread(vert_shader_bytes, 1, vert_shader_size, vert_shader_file); + printf("Vertex Shader Size: %db\n", vert_shader_size); + VkShaderModule vert_mod; + { + VkShaderModuleCreateInfo vert_shader_mod_info = { + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + NULL, + 0, + vert_shader_size, + (uint32_t*)vert_shader_bytes + }; + res = vkCreateShaderModule(dev, &vert_shader_mod_info, NULL, &vert_mod); + printf("CreateShaderModule: (%ld)\n", res); + } + free(vert_shader_bytes); + + FILE* frag_shader_file = fopen("./frag.spv", "r"); + if(frag_shader_file == NULL) { + perror("Failed to read fragment shader"); + exit(1); + } + fseek(frag_shader_file, 0, SEEK_END); + long frag_shader_size = ftell(frag_shader_file); + fseek(frag_shader_file, 0, SEEK_SET); + uint8_t* frag_shader_bytes = malloc(frag_shader_size); + fread(frag_shader_bytes, 1, frag_shader_size, frag_shader_file); + printf("Fragment Shader Size: %db\n", frag_shader_size); + VkShaderModule frag_mod; + { + VkShaderModuleCreateInfo frag_shader_mod_info = { + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + NULL, + 0, + frag_shader_size, + (uint32_t*)frag_shader_bytes + }; + res = vkCreateShaderModule(dev, &frag_shader_mod_info, NULL, &frag_mod); + printf("CreateShaderModule: (%ld)\n", res); + } + free(frag_shader_bytes); + + VkDescriptorSetLayout set_layouts[1]; + { + VkDescriptorSetLayoutBinding layout_bindings[] = { + { + 0, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + 1, + VK_SHADER_STAGE_VERTEX_BIT, + NULL + } + }; + + VkDescriptorSetLayoutCreateInfo layout_info = { + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + NULL, + 0, + sizeof(layout_bindings)/sizeof(layout_bindings[0]), + &layout_bindings[0] + }; + res = vkCreateDescriptorSetLayout(dev, &layout_info, NULL, &set_layouts[0]); + printf("CreateDescriptorSetLayout: (%ld)\n", res); + } + + VkPipelineLayout pipe_layout; + { + VkPushConstantRange push_range[] = {{VK_SHADER_STAGE_VERTEX_BIT, 0, 64+16}, {VK_SHADER_STAGE_FRAGMENT_BIT, 64+16, 16}}; + VkPipelineLayoutCreateInfo pipe_layout_info = { + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + NULL, + 0, + sizeof(set_layouts)/sizeof(set_layouts[0]), + &set_layouts[0], + 2, + push_range + }; + res = vkCreatePipelineLayout(dev, &pipe_layout_info, NULL, &pipe_layout); + printf("CreatePipelineLayout: (%ld)\n", res); + } + VkRenderPass pass; + { + VkAttachmentDescription color_attach = { + 0, + VK_FORMAT_B8G8R8A8_UNORM, + VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_CLEAR, + VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR + }; + VkAttachmentDescription depth_attach = { + 0, + VK_FORMAT_D32_SFLOAT, + VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_CLEAR, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + }; + VkAttachmentReference color_ref = { + 0, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL + }; + VkAttachmentReference depth_ref = { + 1, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + }; + VkSubpassDescription subpass_info = { + 0, + VK_PIPELINE_BIND_POINT_GRAPHICS, + 0, + NULL, + 1, + &color_ref, + NULL, + &depth_ref, + 0, + NULL + }; + VkSubpassDependency sub_dep = { + VK_SUBPASS_EXTERNAL, + 0, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + 0, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + 0 + }; + VkAttachmentDescription attaches[] = {color_attach, depth_attach}; + VkRenderPassCreateInfo pass_info = { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + NULL, + 0, + 2, + &attaches[0], + 1, + &subpass_info, + 1, + &sub_dep + }; + res = vkCreateRenderPass(dev, &pass_info, NULL, &pass); + printf("CreateRenderPass: (%ld)\n", res); + } + + VkViewport main_viewport = { + 0, + 0, + 1920, + 1080, + 0.0f, + 1.0f + }; + VkRect2D main_scissor = { + {0,0}, + {1920, 1080} + }; + VkPipeline pipe; + { + VkPipelineShaderStageCreateInfo vert_shader_stage_info = { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + NULL, + 0, + VK_SHADER_STAGE_VERTEX_BIT, + vert_mod, + "main", + NULL + }; + VkPipelineShaderStageCreateInfo frag_shader_stage_info = { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + NULL, + 0, + VK_SHADER_STAGE_FRAGMENT_BIT, + frag_mod, + "main", + NULL + }; + VkPipelineShaderStageCreateInfo stages[] = {vert_shader_stage_info, frag_shader_stage_info}; + + VkPipelineVertexInputStateCreateInfo vertex_input = { + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + NULL, + 0, + 0, + NULL, + 0, + NULL + }; + + VkPipelineInputAssemblyStateCreateInfo input_assembly = { + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + NULL, + 0, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + VK_FALSE + }; + + // IDK + //VkPipelineTessellationStateCreateInfo tesselation = { + // VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, + // NULL, + // 0, + // VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + // 0 + //}; + VkPipelineViewportStateCreateInfo viewport = { + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + NULL, + 0, + 1, + &main_viewport, + 1, + &main_scissor + }; + + VkPipelineRasterizationStateCreateInfo rasterization = { + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + NULL, + 0, + VK_FALSE, + VK_FALSE, + VK_POLYGON_MODE_FILL, + VK_CULL_MODE_FRONT_BIT, + VK_FRONT_FACE_COUNTER_CLOCKWISE, + VK_FALSE, + 0.0f, + 0.0f, + 0.0f, + 1.0f + }; + + VkPipelineMultisampleStateCreateInfo multisample = { + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + NULL, + 0, + VK_SAMPLE_COUNT_1_BIT, + VK_FALSE, + 0.0f, + VK_FALSE, + VK_FALSE + }; + + VkPipelineDepthStencilStateCreateInfo depth_stencil = { + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + NULL, + 0, + VK_TRUE, + VK_TRUE, + VK_COMPARE_OP_LESS, + VK_TRUE, + VK_FALSE, + {}, + {}, + 0.0f, + 1.0f + }; + + VkPipelineColorBlendAttachmentState blend_attachment = { + VK_FALSE, + VK_BLEND_FACTOR_SRC_COLOR, + VK_BLEND_FACTOR_SRC_COLOR, + VK_BLEND_OP_ADD, + VK_BLEND_FACTOR_SRC_COLOR, + VK_BLEND_FACTOR_SRC_COLOR, + VK_BLEND_OP_ADD, + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT + }; + + VkPipelineColorBlendStateCreateInfo color_blend = { + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + NULL, + 0, + VK_FALSE, + VK_LOGIC_OP_COPY, + 1, + &blend_attachment, + {1.0, 1.0, 1.0, 1.0} + }; + + VkGraphicsPipelineCreateInfo pipe_info = { + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + NULL, + 0,// VkPipelineCreateFlags + 2, + &stages[0], + &vertex_input, // Vertex Input + &input_assembly, // Input Assembly + NULL, // Tesselation + &viewport, // Viewport + &rasterization, // Rasterization + &multisample, // Multisample + &depth_stencil, // Depth Stencil + &color_blend, // Color Blend + NULL, // Dynamic + pipe_layout, + pass, // VkRenderPass + 0, // Subpass + 0, + 0 + }; + + res = vkCreateGraphicsPipelines(dev, NULL, 1, &pipe_info, NULL, &pipe); + printf("vkCreateGraphicsPipelines: (%ld)\n", res); + } + + VkSwapchainKHR swapchain; + { + VkSurfaceCapabilitiesKHR caps; + res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(pdev, surface, &caps); + printf("GetPhysicalDeviceSurfaceCapabilitiesKHR: (%ld)\n", res); + printf("minImageCount: %d\n", caps.minImageCount); + + uint32_t formats_count; + res = vkGetPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &formats_count, 0); + printf("GetPhysicalDeviceSurfaceFormatsKHR 1: (%ld)\n", res); + VkSurfaceFormatKHR* formats = malloc(formats_count * sizeof(VkSurfaceFormatKHR)); + res = vkGetPhysicalDeviceSurfaceFormatsKHR(pdev, surface, &formats_count, &formats[0]); + printf("GetPhysicalDeviceSurfaceFormatsKHR 2: (%ld)\n", res); + for(int i = 0; i < formats_count; i++) { + printf("Format %d: %d,%d;%d,%d\n", i, VK_FORMAT_B8G8R8A8_UNORM, formats[i].format, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, formats[i].colorSpace); + } + + VkSwapchainCreateInfoKHR swap_info = { + VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + NULL, + 0, + surface, + caps.minImageCount, + VK_FORMAT_B8G8R8A8_UNORM, + VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + {1920, 1080}, + 1, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + VK_PRESENT_MODE_MAILBOX_KHR, + VK_TRUE, + NULL + }; + res = vkCreateSwapchainKHR(dev, &swap_info, NULL, &swapchain); + printf("vkCreateSwapchainKHR: (%ld)\n", res); + } + + VkDescriptorPool desc_pool; + { + VkDescriptorPoolSize pool_sizes[] = { + { + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + 1 + } + }; + VkDescriptorPoolCreateInfo desc_pool_info = { + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + NULL, + 0, + 1, + 1, + &pool_sizes[0] + }; + res = vkCreateDescriptorPool(dev, &desc_pool_info, NULL, &desc_pool); + printf("CreateDescriptorPool: (%ld)\n", res); + } + + VkImage* swap_images = {}; + uint32_t swap_img_count; + { + res = vkGetSwapchainImagesKHR(dev, swapchain, &swap_img_count, NULL); + printf("GetSwapchainImagesKHR 1: (%ld)\n", res); + printf("Swapchain Size: %d\n", swap_img_count); + size_t size = swap_img_count * sizeof(VkImage); + printf("Allocating VkImage: %zu\n", size); + swap_images = malloc(size); + res = vkGetSwapchainImagesKHR(dev, swapchain, &swap_img_count, &swap_images[0]); + printf("GetSwapchainImagesKHR 2: (%ld)\n", res); + } + + VkImageView* image_view; + { + size_t size = swap_img_count * sizeof(VkImageView); + printf("Allocating VkImageView: %zu\n", size); + image_view = malloc(size); + } + for(int i = 0; i < swap_img_count; i++) { + VkImageViewCreateInfo image_info = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + swap_images[i], + VK_IMAGE_VIEW_TYPE_2D, + VK_FORMAT_B8G8R8A8_UNORM, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} + }; + res = vkCreateImageView(dev, &image_info, NULL, &image_view[i]); + printf("CreateImageView 2 %d: (%ld)\n", i, res); + } + + VkFramebuffer* framebuffers; + { + size_t size = swap_img_count * sizeof(VkFramebuffer); + printf("Allocating VkFramebuffer: %zu\n", size); + framebuffers = malloc(size); + } + for(int i = 0; i < swap_img_count; i++) { + VkImageView image_views[] = {image_view[i], depth_view}; + VkFramebufferCreateInfo framebuffer_info = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + NULL, + 0, + pass, + 2, + image_views, + 1920, + 1080, + 1 + }; + res = vkCreateFramebuffer(dev, &framebuffer_info, NULL, &framebuffers[i]); + printf("CreateFramebuffer %d: (%ld)\n", i, res); + } + + + VkDescriptorSet desc_sets[1]; + { + + VkDescriptorSetAllocateInfo desc_set_alloc_info = { + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + NULL, + desc_pool, + 1, + &set_layouts[0] + }; + res = vkAllocateDescriptorSets(dev, &desc_set_alloc_info, &desc_sets[0]); + printf("AllocateDescriptorSets: (%ld)\n", res); + } + + { + VkDescriptorBufferInfo buf_infos[] = { + vbuf, + 0, + VK_WHOLE_SIZE + }; + VkWriteDescriptorSet desc_writes[] = { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + NULL, + desc_sets[0], + 0, + 0, + 1, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + NULL, + &buf_infos[0], + NULL + }; + vkUpdateDescriptorSets(dev, 1, &desc_writes[0], 0, NULL); + } + + VkSemaphore sem_avail; + VkSemaphore sem_finish; + VkFence fence_flight; + + { + VkSemaphoreCreateInfo sem_info = { + VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + NULL, + 0 + }; + res = vkCreateSemaphore(dev, &sem_info, NULL, &sem_avail); + printf("CreateSemaphore 1: (%ld)\n", res); + } + + { + VkSemaphoreCreateInfo sem_info = { + VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + NULL, + 0 + }; + res = vkCreateSemaphore(dev, &sem_info, NULL, &sem_finish); + printf("CreateSemaphore 2: (%ld)\n", res); + } + + { + VkFenceCreateInfo fence_info = { + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + NULL, + VK_FENCE_CREATE_SIGNALED_BIT + }; + res = vkCreateFence(dev, &fence_info, NULL, &fence_flight); + printf("CreateFence: (%ld)\n", res); + } + + while(!glfwWindowShouldClose(win)) { + unsigned long long time_bef = get_time(); + //((float*)buf_mem)[1] -= 0.00001; + glfwPollEvents(); + res = vkWaitForFences(dev, 1, &fence_flight, VK_TRUE, UINT64_MAX); + res = vkResetFences(dev, 1, &fence_flight); + uint32_t img_inx; + res = vkAcquireNextImageKHR(dev, swapchain, UINT64_MAX, sem_avail, NULL, &img_inx); + res = vkResetCommandBuffer(cmd_buf, 0); + { + VkCommandBufferBeginInfo begin_info = { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + NULL, + 0, + NULL + }; + res = vkBeginCommandBuffer(cmd_buf, &begin_info); + } + + { + VkClearValue clear_vals[2]; + clear_vals[0].color = (VkClearColorValue){{0.0f, 0.0f, 0.0f, 1.0f}}; + clear_vals[1].depthStencil = (VkClearDepthStencilValue){1.0f, 0}; + VkRenderPassBeginInfo begin_pass_info = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + NULL, + pass, + framebuffers[img_inx], + {0, 0, 1920, 1080}, + 2, + &clear_vals[0] + }; + vkCmdBeginRenderPass(cmd_buf, &begin_pass_info, VK_SUBPASS_CONTENTS_INLINE); + } + + vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); + + vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe_layout, 0, 1, &desc_sets[0], 0, NULL); + + if(key_pressed[0]) { + pos_y += 0.001; + } if(key_pressed[1]) { + pos_y -= 0.001; + } + if(key_pressed[2]) { + rot_y += 0.001; + } if(key_pressed[3]) { + rot_y -= 0.001; + } + if(key_pressed[8]) { + rot_x += 0.001; + } if(key_pressed[9]) { + rot_x -= 0.001; + } + if(key_pressed[4]) { + pos_x -= -sin(rot_y)*0.001; + pos_z -= cos(rot_y)*0.001; + } if(key_pressed[5]) { + pos_x += -sin(rot_y)*0.001; + pos_z += cos(rot_y)*0.001; + } + if(key_pressed[6]) { + pos_x += cos(rot_y)*0.001; + pos_z += sin(rot_y)*0.001; + } if(key_pressed[7]) { + pos_x -= cos(rot_y)*0.001; + pos_z -= sin(rot_y)*0.001; + } + vkCmdPushConstants(cmd_buf, pipe_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 64, (float[]){ + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, rot_x, + }); + vkCmdPushConstants(cmd_buf, pipe_layout, VK_SHADER_STAGE_VERTEX_BIT, 64, 16, (float[]){ + pos_x, pos_y, pos_z, rot_y + }); + vkCmdPushConstants(cmd_buf, pipe_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 64+16, 16, (float[]){ + 0.0, 1.0, 1.0, 1.0, + }); + vkCmdDraw(cmd_buf, 36, 1, 0, 0); + + vkCmdEndRenderPass(cmd_buf); + + + { + res = vkEndCommandBuffer(cmd_buf); + } + + { + VkPipelineStageFlags stage_flags = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + VkSubmitInfo submit_info = { + VK_STRUCTURE_TYPE_SUBMIT_INFO, + NULL, + 1, + &sem_avail, + &stage_flags, + 1, + &cmd_buf, + 1, + &sem_finish + }; + res = vkQueueSubmit(queue, 1, &submit_info, fence_flight); + } + + { + VkPresentInfoKHR present_info = { + VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + NULL, + 1, + &sem_finish, + 1, + &swapchain, + &img_inx, + NULL + }; + res = vkQueuePresentKHR(queue, &present_info); + } + unsigned long long time_now = get_time(); + //printf("ms per frame: %llu\n", (time_now - time_bef)/1000); + } +} diff --git a/vert-inline.vert b/vert-inline.vert new file mode 100644 index 0000000..478aa2c --- /dev/null +++ b/vert-inline.vert @@ -0,0 +1,42 @@ +#version 450 + +// This file contains the raw math performed by the matrices in vert.vert +// Matrices are still used for rotation, though. + +layout(std430, set = 0, binding = 0) buffer positions_buffer { + mat2x4 posnrm[]; +} pos; + +layout(push_constant, std430) uniform pc { + layout(offset=0) mat4 data; + layout(offset=64) vec4 offst; +}; + +layout (location = 0) out vec4 normal; +layout (location = 1) out vec4 pos_pre; +layout (location = 2) out vec4 pos_post; + +const float PI = 3.14159; +const float TAU = PI*2.0; + +void main() { + normal = pos.posnrm[gl_VertexIndex][1]; + pos_pre = pos.posnrm[gl_VertexIndex][0]; + float zFar = 100.0; + float zNear = 0.1; + gl_Position = pos.posnrm[gl_VertexIndex][0]; + gl_Position.xyz += offst.xyz; + pos_post = gl_Position; + mat2 xz_rot; + xz_rot[0] = vec2(cos(offst.w), -sin(offst.w)); + xz_rot[1] = vec2(sin(offst.w), cos(offst.w)); + gl_Position.xz *= inverse(xz_rot); + mat2 yz_rot; + yz_rot[0] = vec2(cos(data[3].w), -sin(data[3].w)); + yz_rot[1] = vec2(sin(data[3].w), cos(data[3].w)); + gl_Position.yz *= inverse(yz_rot); + gl_Position.x *= (1080.0/1920.0); + gl_Position.w = (gl_Position.z*sin(140.0/360.0*TAU)); + gl_Position.z -= zNear; + gl_Position.z /= zFar; +} diff --git a/vert.vert b/vert.vert new file mode 100644 index 0000000..ece17a1 --- /dev/null +++ b/vert.vert @@ -0,0 +1,109 @@ +#version 450 +// vim: ft=c + +layout(std430, set = 0, binding = 0) buffer positions_buffer { + mat2x4 posnrm[]; +} pos; + +layout(push_constant, std430) uniform pc { + layout(offset=0) mat4 data; + layout(offset=64) vec4 offst; +}; + +layout (location = 0) out vec4 normal; +layout (location = 1) out vec4 pos_pre; + +const float PI = 3.14159; +// Forgive me for I have sinned +const float TAU = PI*2.0; + +void main() { + // assign outs + normal = pos.posnrm[gl_VertexIndex][1]; + pos_pre = pos.posnrm[gl_VertexIndex][0]; + + // define constants + const float zFar = 100.0; + const float zNear = 0.1; + + // assign the transformee + gl_Position = pos.posnrm[gl_VertexIndex][0]; + + mat4 view_orig = mat4( + 1.0, 0.0, 0.0, offst.x, + 0.0, 1.0, 0.0, offst.y, + 0.0, 0.0, 1.0, offst.z, + 0.0, 0.0, 0.0, 1.0 + ); + mat4 view_rot_xz = mat4( + cos(offst.w), 0.0, sin(offst.w), 0.0, + 0.0, 1.0, 0.0, 0.0, + -sin(offst.w), 0.0, cos(offst.w), 0.0, + 0.0, 0.0, 0.0, 1.0 + ); + mat4 view_rot_yz = mat4( + 1.0, 0.0, 0.0, 0.0, + 0.0, cos(data[3].w), sin(data[3].w), 0.0, + 0.0, -sin(data[3].w), cos(data[3].w), 0.0, + 0.0, 0.0, 0.0, 1.0 + ); + mat4 project_aspect = mat4( + (1080.0/1920.0), 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + ); + mat4 project_znear = mat4( + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, -zNear, + 0.0, 0.0, 0.0, 1.0 + ); + mat4 project_div = mat4( + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, tan((70.0/2.0)/360.0*TAU), 0.0 + ); + mat4 project_normal = mat4( + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0/zFar, 0.0, + 0.0, 0.0, 0.0, 1.0 + ); + + // apply view's origin transformation + //gl_Position.xyz += offst.xyz; + gl_Position *= view_orig; + + // apply view's xz rotation + //mat2 xz_rot; + //xz_rot[0] = vec2(cos(offst.w), -sin(offst.w)); + //xz_rot[1] = vec2(sin(offst.w), cos(offst.w)); + //gl_Position.xz *= inverse(xz_rot); + gl_Position *= view_rot_xz; + + // apply view's yz rotation + //mat2 yz_rot; + //yz_rot[0] = vec2(cos(data[3].w), -sin(data[3].w)); + //yz_rot[1] = vec2(sin(data[3].w), cos(data[3].w)); + //gl_Position.yz *= inverse(yz_rot); + gl_Position *= view_rot_yz; + + // aspect correction + //gl_Position.x *= (1080.0/1920.0); + gl_Position *= project_aspect; + + // z near correction + //gl_Position.z -= zNear; + gl_Position *= project_znear; + + // division by z + // has to be assigned by w so that the hardware performs the division AFTER clipping. + //gl_Position.w = (gl_Position.z*sin(140.0/360.0*TAU)); + gl_Position *= project_div; + + // z normalization + //gl_Position.z /= zFar; + gl_Position *= project_normal; +}