Browse Source

Use vertex buffers.

master
Amber 2 years ago
parent
commit
920328d35a
  1. 95
      src/main.c
  2. 19
      src/vertex_simple.vert

95
src/main.c

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <cglm/cglm.h>
#define WIDTH 2560
#define HEIGHT 1440
@ -69,6 +70,9 @@ typedef struct ApplicationState { @@ -69,6 +70,9 @@ typedef struct ApplicationState {
VkSemaphore image_available_semaph[MAX_FRAMES_IN_FLIGHT];
VkSemaphore render_finished_sempah[MAX_FRAMES_IN_FLIGHT];
VkFence in_flight_frames[MAX_FRAMES_IN_FLIGHT];
VkBuffer vertex_buffer;
VkDeviceMemory vertex_buffer_memory;
} ApplicationState;
typedef struct QueueFamilyIndices {
@ -78,6 +82,17 @@ typedef struct QueueFamilyIndices { @@ -78,6 +82,17 @@ typedef struct QueueFamilyIndices {
uint32_t present_queue;
} QueueFamilyIndices;
typedef struct Vertex {
vec2 position;
vec3 color;
} Vertex;
const Vertex vertices[] = {
{{0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}},
{{0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}},
{{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}
};
void create_window(ApplicationState* state) {
glfwInit();
@ -692,15 +707,27 @@ void create_graphics_pipeline(ApplicationState* state) { @@ -692,15 +707,27 @@ void create_graphics_pipeline(ApplicationState* state) {
dynamic_state.dynamicStateCount = ARRSIZE(dynamic_states);
dynamic_state.pDynamicStates = dynamic_states;
VkVertexInputBindingDescription binding = {
.binding = 0,
.stride = sizeof(Vertex),
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
};
//We have position and color, so we need two descriptions
VkVertexInputAttributeDescription attribute_description[2] = {
{.binding = 0, .location = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof(Vertex, position)},
{.binding = 0, .location = 1, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = offsetof(Vertex, color)},
};
//vertex input format
//bindings: spacing between data, what data is per-vertex and what data is per instance
//attribute types, which bindings to load them from and at which offset
VkPipelineVertexInputStateCreateInfo vertex_input_info = {0};
vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertex_input_info.vertexBindingDescriptionCount = 0;
vertex_input_info.pVertexBindingDescriptions = NULL;
vertex_input_info.vertexAttributeDescriptionCount = 0;
vertex_input_info.pVertexAttributeDescriptions = NULL;
vertex_input_info.vertexBindingDescriptionCount = 1;
vertex_input_info.pVertexBindingDescriptions = &binding;
vertex_input_info.vertexAttributeDescriptionCount = ARRSIZE(attribute_description);
vertex_input_info.pVertexAttributeDescriptions = attribute_description;
//input assembly
//type of geometry and primitive restart, which allows one to break lines and triangles
@ -862,13 +889,61 @@ void create_command_pool(ApplicationState* state) { @@ -862,13 +889,61 @@ void create_command_pool(ApplicationState* state) {
pool_info.queueFamilyIndex = families.graphics_queue;
if (vkCreateCommandPool(state->device, &pool_info, NULL, &state->commandPool) != VK_SUCCESS) {
printf("failed to create command pool");
printf("failed to create command pool\n");
exit(1);
}
printf("created command pools\n");
}
uint32_t find_memory_type (ApplicationState* state, uint32_t type_filter, VkMemoryPropertyFlags props) {
VkPhysicalDeviceMemoryProperties mem_props;
vkGetPhysicalDeviceMemoryProperties(state->physical_device, &mem_props);
for (uint32_t i = 0; i < mem_props.memoryTypeCount; i++) {
if ((type_filter & (1 << i)) && (mem_props.memoryTypes[i].propertyFlags & props) == props) {
return i;
}
}
printf("no suitable memory type\n");
exit(1);
}
void create_vertex_buffer(ApplicationState* state) {
VkBufferCreateInfo buffer_info = {0};
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_info.size = sizeof(Vertex) * ARRSIZE(vertices);
buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
if (vkCreateBuffer(state->device, &buffer_info, NULL, &state->vertex_buffer) != VK_SUCCESS) {
printf("Failed to create vertex buffer\n");
exit(1);
}
VkMemoryRequirements mem_req;
vkGetBufferMemoryRequirements(state->device, state->vertex_buffer, &mem_req);
VkMemoryAllocateInfo alloc_info = {0};
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
alloc_info.allocationSize = mem_req.size;
alloc_info.memoryTypeIndex = find_memory_type(state, mem_req.memoryTypeBits,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
if (vkAllocateMemory(state->device, &alloc_info, NULL, &state->vertex_buffer_memory) != VK_SUCCESS) {
printf("failed to allocate memory for buffer\n");
exit(1);
}
vkBindBufferMemory(state->device, state->vertex_buffer, state->vertex_buffer_memory, 0);
void* data;
vkMapMemory(state->device, state->vertex_buffer_memory, 0, buffer_info.size, 0, &data);
memcpy(data, vertices, buffer_info.size);
vkUnmapMemory(state->device, state->vertex_buffer_memory);
}
void create_command_buffer(ApplicationState* state) {
VkCommandBufferAllocateInfo command_buf_allocate_info = {0};
command_buf_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
@ -916,6 +991,10 @@ void record_command_buffer(ApplicationState* state, VkCommandBuffer command_buff @@ -916,6 +991,10 @@ void record_command_buffer(ApplicationState* state, VkCommandBuffer command_buff
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, state->graphics_pipeline);
VkBuffer vertex_buffers[] = {state->vertex_buffer};
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, offsets);
//setup dynamic state
VkViewport viewport = {0};
viewport.x = 0.0f;
@ -935,7 +1014,7 @@ void record_command_buffer(ApplicationState* state, VkCommandBuffer command_buff @@ -935,7 +1014,7 @@ void record_command_buffer(ApplicationState* state, VkCommandBuffer command_buff
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
//vertex count, instance count, first vertex and first instance
vkCmdDraw(command_buffer, 3, 1, 0, 0);
vkCmdDraw(command_buffer, ARRSIZE(vertices), 1, 0, 0);
vkCmdEndRenderPass(command_buffer);
@ -977,6 +1056,7 @@ void init_vulkan(ApplicationState* state) { @@ -977,6 +1056,7 @@ void init_vulkan(ApplicationState* state) {
create_graphics_pipeline(state);
create_framebuffers(state);
create_command_pool(state);
create_vertex_buffer(state);
create_command_buffer(state);
create_sync_objects(state);
}
@ -1057,6 +1137,9 @@ void terminate(ApplicationState* state) { @@ -1057,6 +1137,9 @@ void terminate(ApplicationState* state) {
for (int i = 0; i < state->swapchain_image_count; i++) {
vkDestroyImageView(state->device, state->swapchain_image_views[i], NULL);
}
vkDestroyBuffer(state->device, state->vertex_buffer, NULL);
vkFreeMemory(state->device, state->vertex_buffer_memory, NULL);
vkDestroySwapchainKHR(state->device, state->swapchain, NULL);
vkDestroyDevice(state->device, NULL);
vkDestroySurfaceKHR(state->instance, state->surface, NULL);

19
src/vertex_simple.vert

@ -1,20 +1,11 @@ @@ -1,20 +1,11 @@
#version 450
layout(location = 0) out vec3 fragColor;
vec2 positions[3] = vec2[](
vec2(0.0, -0.5),
vec2(0.5, 0.5),
vec2(-0.5, 0.5)
);
layout (location = 0) in vec2 inPosition;
layout (location = 1) in vec3 inColor;
vec3 colors[3] = vec3[](
vec3(1.0, 0.0, 0.0),
vec3(0.0, 1.0, 0.0),
vec3(0.0, 0.0, 1.0)
);
layout(location = 0) out vec3 fragColor;
void main() {
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
fragColor = colors[gl_VertexIndex];
gl_Position = vec4(inPosition, 0.0, 1.0);
fragColor = inColor;
}

Loading…
Cancel
Save