-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMesh.cpp
133 lines (105 loc) · 4.19 KB
/
Mesh.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "Mesh.h"
Mesh::Mesh()
{
}
Mesh::Mesh(VkPhysicalDevice newPhysicalDevice, VkDevice newDevice,
VkQueue transferQueue, VkCommandPool transferCommandPool,
std::vector<Vertex>* vertices, std::vector<uint32_t> * indices,
int newTexId)
{
vertexCount = vertices->size();
indexCount = indices->size();
physicalDevice = newPhysicalDevice;
device = newDevice;
createVertexBuffer(transferQueue, transferCommandPool, vertices);
createIndexBuffer(transferQueue, transferCommandPool, indices);
model.model = glm::mat4(1.0f);
texId = newTexId;
}
void Mesh::setModel(glm::mat4 newModel)
{
model.model = newModel;
}
Model Mesh::getModel()
{
return model;
}
int Mesh::getTexId()
{
return texId;
}
int Mesh::getVertexCount()
{
return vertexCount;
}
VkBuffer Mesh::getVertexBuffer()
{
return vertexBuffer;
}
int Mesh::getIndexCount()
{
return indexCount;
}
VkBuffer Mesh::getIndexBuffer()
{
return indexBuffer;
}
void Mesh::destroyBuffers()
{
vkDestroyBuffer(device, vertexBuffer, nullptr);
vkFreeMemory(device, vertexBufferMemory, nullptr);
vkDestroyBuffer(device, indexBuffer, nullptr);
vkFreeMemory(device, indexBufferMemory, nullptr);
}
Mesh::~Mesh()
{
}
void Mesh::createVertexBuffer(VkQueue transferQueue, VkCommandPool transferCommandPool, std::vector<Vertex>* vertices)
{
// Get size of buffer needed for vertices
VkDeviceSize bufferSize = sizeof(Vertex) * vertices->size();
// Temporary buffer to "stage" vertex data before transferring to GPU
VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;
// Create Staging Buffer and Allocate Memory to it
createBuffer(physicalDevice, device, bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
&stagingBuffer, &stagingBufferMemory);
// MAP MEMORY TO VERTEX BUFFER
void * data; // 1. Create pointer to a point in normal memory
vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data); // 2. "Map" the vertex buffer memory to that point
memcpy(data, vertices->data(), (size_t)bufferSize); // 3. Copy memory from vertices vector to the point
vkUnmapMemory(device, stagingBufferMemory); // 4. Unmap the vertex buffer memory
// Create buffer with TRANSFER_DST_BIT to mark as recipient of transfer data (also VERTEX_BUFFER)
// Buffer memory is to be DEVICE_LOCAL_BIT meaning memory is on the GPU and only accessible by it and not CPU (host)
createBuffer(physicalDevice, device, bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &vertexBuffer, &vertexBufferMemory);
// Copy staging buffer to vertex buffer on GPU
copyBuffer(device, transferQueue, transferCommandPool, stagingBuffer, vertexBuffer, bufferSize);
// Clean up staging buffer parts
vkDestroyBuffer(device, stagingBuffer, nullptr);
vkFreeMemory(device, stagingBufferMemory, nullptr);
}
void Mesh::createIndexBuffer(VkQueue transferQueue, VkCommandPool transferCommandPool, std::vector<uint32_t>* indices)
{
// Get size of buffer needed for indices
VkDeviceSize bufferSize = sizeof(uint32_t) * indices->size();
// Temporary buffer to "stage" index data before transferring to GPU
VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;
createBuffer(physicalDevice, device, bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &stagingBuffer, &stagingBufferMemory);
// MAP MEMORY TO INDEX BUFFER
void * data;
vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
memcpy(data, indices->data(), (size_t)bufferSize);
vkUnmapMemory(device, stagingBufferMemory);
// Create buffer for INDEX data on GPU access only area
createBuffer(physicalDevice, device, bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &indexBuffer, &indexBufferMemory);
// Copy from staging buffer to GPU access buffer
copyBuffer(device, transferQueue, transferCommandPool, stagingBuffer, indexBuffer, bufferSize);
// Destroy + Release Staging Buffer resources
vkDestroyBuffer(device, stagingBuffer, nullptr);
vkFreeMemory(device, stagingBufferMemory, nullptr);
}