Compare commits

...

2 Commits

22 changed files with 2288 additions and 139 deletions

View File

@ -0,0 +1,2 @@
# Blender 4.2.3 LTS MTL File: 'None'
# www.blender.org

2070
assets/models/UVSphere.obj Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,2 @@
# Blender 4.2.3 LTS MTL File: 'None' # Blender 4.2.3 LTS MTL File: 'None'
# www.blender.org # www.blender.org
newmtl Material
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
map_Kd /home/lillian/Downloads/d41777258e68c9d7046fc03c4d1d1e89.png

View File

@ -0,0 +1,39 @@
# Blender 4.2.3 LTS
# www.blender.org
mtllib untitled.mtl
o Cube
v -6.996062 0.060240 6.002291
v -6.996062 0.123414 6.002291
v -6.996062 0.060240 -6.002291
v -6.996062 0.123414 -6.002291
v 6.996062 0.060240 6.002291
v 6.996062 0.123414 6.002291
v 6.996062 0.060240 -6.002291
v 6.996062 0.123414 -6.002291
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.561014 0.000000
vt 0.625000 0.000000
vt 0.625000 0.250000
vt 0.561014 0.250000
vt 0.625000 0.500000
vt 0.561014 0.500000
vt 0.625000 0.750000
vt 0.561014 0.750000
vt 0.625000 1.000000
vt 0.561014 1.000000
vt 0.125000 0.500000
vt 0.125000 0.750000
vt 0.875000 0.500000
vt 0.875000 0.750000
s 0
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/4/2 4/3/2 8/5/2 7/6/2
f 7/6/3 8/5/3 6/7/3 5/8/3
f 5/8/4 6/7/4 2/9/4 1/10/4
f 3/11/5 7/6/5 5/8/5 1/12/5
f 8/5/6 4/13/6 2/14/6 6/7/6

View File

@ -3,6 +3,6 @@ Pos=60,60
Size=400,400 Size=400,400
[Window][Agnosia Debug] [Window][Agnosia Debug]
Pos=40,377 Pos=57,392
Size=623,438 Size=623,438

View File

@ -23,8 +23,8 @@ void initImGuiWindow() {
} }
ImGui::DragFloat3("Camera Position", Graphics::getCamPos()); ImGui::DragFloat3("Camera Position", Graphics::getCamPos());
ImGui::DragFloat3("Light Position", Graphics::getLightPos());
ImGui::DragFloat3("Center Position", Graphics::getCenterPos()); ImGui::DragFloat3("Center Position", Graphics::getCenterPos());
ImGui::DragFloat3("Up Direction", Graphics::getUpDir());
ImGui::DragFloat("Depth of Field", &Graphics::getDepthField(), 0.1f, 1.0f, ImGui::DragFloat("Depth of Field", &Graphics::getDepthField(), 0.1f, 1.0f,
180.0f, NULL, ImGuiSliderFlags_AlwaysClamp); 180.0f, NULL, ImGuiSliderFlags_AlwaysClamp);
ImGui::DragFloat2("Near and Far fields", Graphics::getDistanceField()); ImGui::DragFloat2("Near and Far fields", Graphics::getDistanceField());

View File

@ -87,24 +87,24 @@ void createInstance() {
throw std::runtime_error("failed to create instance!"); throw std::runtime_error("failed to create instance!");
} }
} }
void initAgnosia() {
void initVulkan() { Material *sphereMaterial =
Material *vikingRoomMaterial = new Material("sphereMaterial", "assets/textures/checkermap.png");
new Material("vikingRoomMaterial", "assets/textures/viking_room.png");
Material *stanfordDragonMaterial = Material *stanfordDragonMaterial =
new Material("stanfordDragonMaterial", "assets/textures/checkermap.png"); new Material("stanfordDragonMaterial", "assets/textures/checkermap.png");
Material *teapotMaterial = Material *teapotMaterial =
new Material("teapotMaterial", "assets/textures/checkermap.png"); new Material("teapotMaterial", "assets/textures/checkermap.png");
Model *vikingRoom = Model *uvSphere =
new Model("vikingRoom", *vikingRoomMaterial, new Model("uvSphere", *sphereMaterial, "assets/models/UVSphere.obj",
"assets/models/viking_room.obj", glm::vec3(0.0f, 0.0f, 0.0f)); glm::vec3(0.0f, 0.0f, 0.0f));
Model *stanfordDragon = new Model("stanfordDragon", *stanfordDragonMaterial, Model *stanfordDragon = new Model("stanfordDragon", *stanfordDragonMaterial,
"assets/models/StanfordDragon800k.obj", "assets/models/StanfordDragon800k.obj",
glm::vec3(0.0f, 2.0f, 0.0f)); glm::vec3(0.0f, 2.0f, 0.0f));
Model *teapot = Model *teapot =
new Model("teapot", *teapotMaterial, "assets/models/teapot.obj", new Model("teapot", *teapotMaterial, "assets/models/teapot.obj",
glm::vec3(1.0f, -3.0f, -1.0f)); glm::vec3(1.0f, -3.0f, -1.0f));
}
void initVulkan() {
// Initialize volk and continue if successful. // Initialize volk and continue if successful.
volkInitialize(); volkInitialize();
// Initialize vulkan and set up pipeline. // Initialize vulkan and set up pipeline.
@ -122,9 +122,7 @@ void initVulkan() {
Graphics::createCommandPool(); Graphics::createCommandPool();
// Image creation MUST be after command pool, because command // Image creation MUST be after command pool, because command
// buffers. // buffers.
vikingRoom->populateData(); Model::populateModels();
stanfordDragon->populateData();
teapot->populateData();
Texture::createMaterialTextures(Model::getInstances()); Texture::createMaterialTextures(Model::getInstances());
Texture::createColorResources(); Texture::createColorResources();
Texture::createDepthResources(); Texture::createDepthResources();
@ -150,6 +148,11 @@ void mainLoop() {
void cleanup() { void cleanup() {
Render::cleanupSwapChain(); Render::cleanupSwapChain();
Graphics::destroyGraphicsPipeline(); Graphics::destroyGraphicsPipeline();
Buffers::destroyDescriptorPool();
Model::destroyTextures();
vkDestroyDescriptorSetLayout(DeviceControl::getDevice(),
Buffers::getDescriptorSetLayout(), nullptr);
Buffers::destroyBuffers(); Buffers::destroyBuffers();
Render::destroyFenceSemaphores(); Render::destroyFenceSemaphores();
@ -179,6 +182,7 @@ GLFWwindow *EntryApp::getWindow() { return window; }
void EntryApp::run() { void EntryApp::run() {
initWindow(); initWindow();
initAgnosia();
initVulkan(); initVulkan();
mainLoop(); mainLoop();
cleanup(); cleanup();

View File

@ -122,6 +122,9 @@ void Buffers::createDescriptorPool() {
throw std::runtime_error("failed to create descriptor pool!"); throw std::runtime_error("failed to create descriptor pool!");
} }
} }
void Buffers::destroyDescriptorPool() {
vkDestroyDescriptorPool(DeviceControl::getDevice(), descriptorPool, nullptr);
}
void Buffers::createDescriptorSet(std::vector<Model *> models) { void Buffers::createDescriptorSet(std::vector<Model *> models) {
VkDescriptorSetAllocateInfo allocInfo{}; VkDescriptorSetAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;

View File

@ -19,6 +19,7 @@ public:
static void createDescriptorSetLayout(); static void createDescriptorSetLayout();
static void createDescriptorSet(std::vector<Model *> models); static void createDescriptorSet(std::vector<Model *> models);
static void createDescriptorPool(); static void createDescriptorPool();
static void destroyDescriptorPool();
static void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, static void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
VkMemoryPropertyFlags props, VkBuffer &buffer, VkMemoryPropertyFlags props, VkBuffer &buffer,
VkDeviceMemory &bufferMemory); VkDeviceMemory &bufferMemory);

View File

@ -13,6 +13,7 @@
#include <iostream> #include <iostream>
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
float lightPos[4] = {5.0f, 5.0f, 5.0f, 0.44f};
float camPos[4] = {3.0f, 3.0f, 3.0f, 0.44f}; float camPos[4] = {3.0f, 3.0f, 3.0f, 0.44f};
float centerPos[4] = {0.0f, 0.0f, 0.0f, 0.44f}; float centerPos[4] = {0.0f, 0.0f, 0.0f, 0.44f};
float upDir[4] = {0.0f, 0.0f, 1.0f, 0.44f}; float upDir[4] = {0.0f, 0.0f, 1.0f, 0.44f};
@ -363,6 +364,7 @@ void Graphics::recordCommandBuffer(VkCommandBuffer commandBuffer,
Agnosia_T::GPUPushConstants pushConsts; Agnosia_T::GPUPushConstants pushConsts;
pushConsts.vertexBuffer = model->getBuffers().vertexBufferAddress; pushConsts.vertexBuffer = model->getBuffers().vertexBufferAddress;
pushConsts.objPosition = model->getPos(); pushConsts.objPosition = model->getPos();
pushConsts.lightPos = glm::vec3(lightPos[0], lightPos[1], lightPos[2]);
pushConsts.textureID = texID; pushConsts.textureID = texID;
pushConsts.model = pushConsts.model =
@ -433,6 +435,7 @@ void Graphics::recordCommandBuffer(VkCommandBuffer commandBuffer,
} }
float *Graphics::getCamPos() { return camPos; } float *Graphics::getCamPos() { return camPos; }
float *Graphics::getLightPos() { return lightPos; }
float *Graphics::getCenterPos() { return centerPos; } float *Graphics::getCenterPos() { return centerPos; }
float *Graphics::getUpDir() { return upDir; } float *Graphics::getUpDir() { return upDir; }
float &Graphics::getDepthField() { return depthField; } float &Graphics::getDepthField() { return depthField; }

View File

@ -15,6 +15,7 @@ public:
uint32_t imageIndex); uint32_t imageIndex);
static float *getCamPos(); static float *getCamPos();
static float *getLightPos();
static float *getCenterPos(); static float *getCenterPos();
static float *getUpDir(); static float *getUpDir();
static float &getDepthField(); static float &getDepthField();

View File

@ -20,15 +20,21 @@
std::vector<Model *> Model::instances; std::vector<Model *> Model::instances;
VmaAllocator _allocator; VmaAllocator _allocator;
// chatgpt did this and the haters can WEEP fuck hash functions.
namespace std { namespace std {
template <> struct hash<Agnosia_T::Vertex> { template <> struct hash<Agnosia_T::Vertex> {
size_t operator()(Agnosia_T::Vertex const &vertex) const { size_t operator()(Agnosia_T::Vertex const &vertex) const {
return ((hash<glm::vec3>()(vertex.pos) ^ size_t hashPos = hash<glm::vec3>()(vertex.pos);
(hash<glm::vec3>()(vertex.color) << 1)) >> size_t hashColor = hash<glm::vec3>()(vertex.color);
1) ^ size_t hashUV = hash<glm::vec2>()(vertex.uv);
(hash<glm::vec2>()(vertex.texCoord) << 1); size_t hashNormal = hash<glm::vec3>()(vertex.normal);
// Combine all hashes
return ((hashPos ^ (hashColor << 1)) >> 1) ^ (hashUV << 1) ^
(hashNormal << 2);
} }
}; };
} // namespace std } // namespace std
void Model::createMemoryAllocator(VkInstance vkInstance) { void Model::createMemoryAllocator(VkInstance vkInstance) {
VmaVulkanFunctions vulkanFuncs{ VmaVulkanFunctions vulkanFuncs{
@ -105,112 +111,128 @@ Model::Model(const std::string &modelID, const Material &material,
instances.push_back(this); instances.push_back(this);
} }
void Model::populateData() { void Model::populateModels() {
for (Model *model : getInstances()) {
std::vector<Agnosia_T::Vertex> vertices; std::vector<Agnosia_T::Vertex> vertices;
// Index buffer definition, showing which points to reuse. // Index buffer definition, showing which points to reuse.
std::vector<uint32_t> indices; std::vector<uint32_t> indices;
tinyobj::ObjReaderConfig readerConfig; tinyobj::ObjReaderConfig readerConfig;
tinyobj::ObjReader reader; tinyobj::ObjReader reader;
if (!reader.ParseFromFile(modelPath, readerConfig)) { if (!reader.ParseFromFile(model->modelPath, readerConfig)) {
if (!reader.Error().empty()) { if (!reader.Error().empty()) {
throw std::runtime_error(reader.Error()); throw std::runtime_error(reader.Error());
} }
if (!reader.Warning().empty()) { if (!reader.Warning().empty()) {
throw std::runtime_error(reader.Warning()); throw std::runtime_error(reader.Warning());
}
}
auto &attrib = reader.GetAttrib();
auto &shapes = reader.GetShapes();
auto &materials = reader.GetMaterials();
std::unordered_map<Agnosia_T::Vertex, uint32_t> uniqueVertices{};
for (const auto &shape : shapes) {
for (const auto &index : shape.mesh.indices) {
Agnosia_T::Vertex vertex{};
vertex.pos = {attrib.vertices[3 * index.vertex_index + 0],
attrib.vertices[3 * index.vertex_index + 1],
attrib.vertices[3 * index.vertex_index + 2]};
// TODO: Small fix here, handle if there are no UV's unwrapped for the
// model.
// As of now, if it is not unwrapped, it segfaults on texCoord
// assignment. Obviously we should always have UV's, but it
// shouldn't crash, just unwrap in a default method.
vertex.texCoord = {attrib.texcoords[2 * index.texcoord_index + 0],
1.0f - attrib.texcoords[2 * index.texcoord_index + 1]};
vertex.color = {1.0f, 1.0f, 1.0f};
if (uniqueVertices.count(vertex) == 0) {
uniqueVertices[vertex] = static_cast<uint32_t>(vertices.size());
vertices.push_back(vertex);
} }
indices.push_back(uniqueVertices[vertex]);
} }
auto &attrib = reader.GetAttrib();
auto &shapes = reader.GetShapes();
auto &materials = reader.GetMaterials();
std::unordered_map<Agnosia_T::Vertex, uint32_t> uniqueVertices{};
for (const auto &shape : shapes) {
for (const auto &index : shape.mesh.indices) {
Agnosia_T::Vertex vertex{};
vertex.pos = {attrib.vertices[3 * index.vertex_index + 0],
attrib.vertices[3 * index.vertex_index + 1],
attrib.vertices[3 * index.vertex_index + 2]};
vertex.normal = {attrib.normals[3 * index.normal_index + 0],
attrib.normals[3 * index.normal_index + 1],
attrib.normals[3 * index.normal_index + 2]};
// TODO: Small fix here, handle if there are no UV's unwrapped for the
// model.
// As of now, if it is not unwrapped, it segfaults on texCoord
// assignment. Obviously we should always have UV's, but it
// shouldn't crash, just unwrap in a default method.
vertex.uv = {attrib.texcoords[2 * index.texcoord_index + 0],
1.0f - attrib.texcoords[2 * index.texcoord_index + 1]};
vertex.color = {1.0f, 1.0f, 1.0f};
if (uniqueVertices.count(vertex) == 0) {
uniqueVertices[vertex] = static_cast<uint32_t>(vertices.size());
vertices.push_back(vertex);
}
indices.push_back(uniqueVertices[vertex]);
}
}
const size_t vertexBufferSize = vertices.size() * sizeof(Agnosia_T::Vertex);
const size_t indexBufferSize = indices.size() * sizeof(uint32_t);
Agnosia_T::GPUMeshBuffers newSurface;
// Create a Vertex Buffer here, infinitely easier than the old Vulkan
// method!
newSurface.vertexBuffer = createBuffer(
vertexBufferSize,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
VMA_MEMORY_USAGE_GPU_ONLY);
// Find the address of the vertex buffer!
VkBufferDeviceAddressInfo deviceAddressInfo{
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = newSurface.vertexBuffer.buffer,
};
newSurface.vertexBufferAddress = vkGetBufferDeviceAddress(
DeviceControl::getDevice(), &deviceAddressInfo);
// Create the index buffer to iterate over and check for duplicate vertices
newSurface.indexBuffer = createBuffer(indexBufferSize,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VMA_MEMORY_USAGE_GPU_ONLY);
Agnosia_T::AllocatedBuffer stagingBuffer = createBuffer(
vertexBufferSize + indexBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VMA_MEMORY_USAGE_CPU_ONLY);
void *data = stagingBuffer.allocation->GetMappedData();
// Copy the vertex buffer
memcpy(data, vertices.data(), vertexBufferSize);
// Copy the index buffer
memcpy((char *)data + vertexBufferSize, indices.data(), indexBufferSize);
immediate_submit([&](VkCommandBuffer cmd) {
VkBufferCopy vertexCopy{0};
vertexCopy.dstOffset = 0;
vertexCopy.srcOffset = 0;
vertexCopy.size = vertexBufferSize;
vkCmdCopyBuffer(cmd, stagingBuffer.buffer, newSurface.vertexBuffer.buffer,
1, &vertexCopy);
VkBufferCopy indexCopy{0};
indexCopy.dstOffset = 0;
indexCopy.srcOffset = vertexBufferSize;
indexCopy.size = indexBufferSize;
vkCmdCopyBuffer(cmd, stagingBuffer.buffer, newSurface.indexBuffer.buffer,
1, &indexCopy);
});
vmaDestroyBuffer(_allocator, stagingBuffer.buffer,
stagingBuffer.allocation);
model->buffers = newSurface;
model->indiceCount = indices.size();
}
}
void Model::destroyTextures() {
for (Model *model : Model::getInstances()) {
vkDestroySampler(DeviceControl::getDevice(),
model->getMaterial().getTextureSampler(), nullptr);
vkDestroyImageView(DeviceControl::getDevice(),
model->getMaterial().getTextureView(), nullptr);
vkDestroyImage(DeviceControl::getDevice(),
model->getMaterial().getTextureImage(), nullptr);
} }
const size_t vertexBufferSize = vertices.size() * sizeof(Agnosia_T::Vertex);
const size_t indexBufferSize = indices.size() * sizeof(uint32_t);
Agnosia_T::GPUMeshBuffers newSurface;
// Create a Vertex Buffer here, infinitely easier than the old Vulkan method!
newSurface.vertexBuffer = createBuffer(
vertexBufferSize,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
VMA_MEMORY_USAGE_GPU_ONLY);
// Find the address of the vertex buffer!
VkBufferDeviceAddressInfo deviceAddressInfo{
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
.buffer = newSurface.vertexBuffer.buffer,
};
newSurface.vertexBufferAddress =
vkGetBufferDeviceAddress(DeviceControl::getDevice(), &deviceAddressInfo);
// Create the index buffer to iterate over and check for duplicate vertices
newSurface.indexBuffer = createBuffer(indexBufferSize,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VMA_MEMORY_USAGE_GPU_ONLY);
Agnosia_T::AllocatedBuffer stagingBuffer =
createBuffer(vertexBufferSize + indexBufferSize,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
void *data = stagingBuffer.allocation->GetMappedData();
// Copy the vertex buffer
memcpy(data, vertices.data(), vertexBufferSize);
// Copy the index buffer
memcpy((char *)data + vertexBufferSize, indices.data(), indexBufferSize);
immediate_submit([&](VkCommandBuffer cmd) {
VkBufferCopy vertexCopy{0};
vertexCopy.dstOffset = 0;
vertexCopy.srcOffset = 0;
vertexCopy.size = vertexBufferSize;
vkCmdCopyBuffer(cmd, stagingBuffer.buffer, newSurface.vertexBuffer.buffer,
1, &vertexCopy);
VkBufferCopy indexCopy{0};
indexCopy.dstOffset = 0;
indexCopy.srcOffset = vertexBufferSize;
indexCopy.size = indexBufferSize;
vkCmdCopyBuffer(cmd, stagingBuffer.buffer, newSurface.indexBuffer.buffer, 1,
&indexCopy);
});
vmaDestroyBuffer(_allocator, stagingBuffer.buffer, stagingBuffer.allocation);
this->buffers = newSurface;
this->objPosition = objPosition;
this->indiceCount = indices.size();
} }
std::string Model::getID() { return this->ID; } std::string Model::getID() { return this->ID; }

View File

@ -28,7 +28,8 @@ public:
static void createMemoryAllocator(VkInstance instance); static void createMemoryAllocator(VkInstance instance);
static const std::vector<Model *> &getInstances(); static const std::vector<Model *> &getInstances();
void populateData(); static void populateModels();
static void destroyTextures();
Agnosia_T::GPUMeshBuffers getBuffers(); Agnosia_T::GPUMeshBuffers getBuffers();
std::string getID(); std::string getID();

View File

@ -4,6 +4,7 @@
struct Vertex { struct Vertex {
vec3 pos; vec3 pos;
vec3 normal;
vec3 color; vec3 color;
vec2 texCoord; vec2 texCoord;
}; };
@ -14,6 +15,7 @@ layout(buffer_reference, scalar) readonly buffer VertexBuffer{
layout( push_constant, scalar ) uniform constants { layout( push_constant, scalar ) uniform constants {
VertexBuffer vertBuffer; VertexBuffer vertBuffer;
vec3 objPos; vec3 objPos;
vec3 lightPos;
int textureID; int textureID;
mat4 model; mat4 model;
mat4 view; mat4 view;

View File

@ -5,11 +5,18 @@
layout(binding = 1) uniform sampler2D texSampler[]; layout(binding = 1) uniform sampler2D texSampler[];
layout(location = 0) in vec3 fragColor; layout(location = 0) in vec3 v_norm;
layout(location = 1) in vec2 fragTexCoord; layout(location = 1) in vec3 v_pos;
layout(location = 2) in vec2 texCoord;
layout(location = 0) out vec4 outColor; layout(location = 0) out vec4 outColor;
void main() { void main() {
outColor = texture(texSampler[PushConstants.textureID], fragTexCoord); vec3 diffuseColor = texture(texSampler[PushConstants.textureID], texCoord).rgb;
vec3 ambientColor = vec3(0.05f,0.05f, 0.05f) * diffuseColor;
float lightPower = 5;
vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);
float cosTheta = dot(PushConstants.lightPos, v_norm);
float sqrDist = distance(v_pos, PushConstants.lightPos)*distance(v_pos, PushConstants.lightPos);
outColor = vec4(ambientColor + clamp(diffuseColor * lightColor * lightPower * cosTheta / sqrDist, vec3(0,0,0), vec3(1,1,1)), 1.0f);
} }

View File

@ -2,14 +2,16 @@
#extension GL_GOOGLE_include_directive : enable #extension GL_GOOGLE_include_directive : enable
#include "common.glsl" #include "common.glsl"
layout(location = 0) out vec3 fragColor; layout(location = 0) out vec3 v_norm;
layout(location = 1) out vec2 fragTexCoord; layout(location = 1) out vec3 v_pos;
layout(location = 2) out vec2 texCoord;
void main() { void main() {
Vertex vertex = PushConstants.vertBuffer.vertices[gl_VertexIndex]; Vertex vertex = PushConstants.vertBuffer.vertices[gl_VertexIndex];
gl_Position = PushConstants.proj * PushConstants.view * PushConstants.model * gl_Position = PushConstants.proj * PushConstants.view * PushConstants.model *
vec4(vertex.pos + PushConstants.objPos, 1.0f); vec4(vertex.pos + PushConstants.objPos, 1.0f);
fragColor = vertex.color.rgb; v_norm = vertex.normal;
fragTexCoord = vertex.texCoord; v_pos = vertex.pos;
texCoord = vertex.texCoord;
} }

View File

@ -10,12 +10,13 @@ public:
// This defines what a vertex is! // This defines what a vertex is!
// We control the position, color and texture coordinate here! // We control the position, color and texture coordinate here!
glm::vec3 pos; glm::vec3 pos;
glm::vec3 normal;
glm::vec3 color; glm::vec3 color;
glm::vec2 texCoord; glm::vec2 uv;
bool operator==(const Vertex &other) const { bool operator==(const Vertex &other) const {
return pos == other.pos && color == other.color && return pos == other.pos && normal == other.normal &&
texCoord == other.texCoord; color == other.color && uv == other.uv;
} }
}; };
struct AllocatedBuffer { struct AllocatedBuffer {
@ -31,6 +32,7 @@ public:
struct GPUPushConstants { struct GPUPushConstants {
VkDeviceAddress vertexBuffer; VkDeviceAddress vertexBuffer;
glm::vec3 objPosition; glm::vec3 objPosition;
glm::vec3 lightPos;
int textureID; int textureID;
glm::mat4 model; glm::mat4 model;
glm::mat4 view; glm::mat4 view;