to test on windows
This commit is contained in:
parent
b83207e652
commit
a015aa00ef
BIN
assets/boy.jpg
BIN
assets/boy.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 685 KiB |
BIN
assets/boy.png
Normal file
BIN
assets/boy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 MiB |
6
main.cpp
6
main.cpp
@ -51,7 +51,7 @@ int main() {
|
|||||||
|
|
||||||
Renderer renderer(window);
|
Renderer renderer(window);
|
||||||
|
|
||||||
texture_manager.load("assets/boy.jpg", renderer);
|
texture_manager.load("assets/boy.png", renderer);
|
||||||
|
|
||||||
uint64_t current_time = glfwGetTimerValue();
|
uint64_t current_time = glfwGetTimerValue();
|
||||||
|
|
||||||
@ -72,8 +72,8 @@ int main() {
|
|||||||
t += dt;
|
t += dt;
|
||||||
updates++;
|
updates++;
|
||||||
}
|
}
|
||||||
std::println("Updates: {}", updates);
|
// std::println("Updates: {}", updates);
|
||||||
std::println("frame time: {}", ((double) (frame_time) / (double) glfwGetTimerFrequency()));
|
// std::println("frame time: {}", ((double) (frame_time) / (double) glfwGetTimerFrequency()));
|
||||||
|
|
||||||
renderer.begin_frame();
|
renderer.begin_frame();
|
||||||
|
|
||||||
|
|||||||
@ -102,39 +102,33 @@ void Renderer::submit_sprite(glm::vec2 pos, const sprite_t &sprite) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::create_pipeline_layout() {
|
void Renderer::create_pipeline_layout() {
|
||||||
VkDescriptorSetLayoutBinding bindings[2];
|
std::array<VkDescriptorSetLayoutBinding, 1> bindings = {
|
||||||
|
{
|
||||||
bindings[0] = VkDescriptorSetLayoutBinding{
|
{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = nextTextureSlot,
|
||||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bindings[1] = {
|
VkDescriptorBindingFlags flags[1] = {
|
||||||
.binding = 1,
|
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
||||||
.descriptorCount = 1,
|
|
||||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT
|
|
||||||
};
|
|
||||||
|
|
||||||
VkDescriptorBindingFlags flags[2] = {
|
|
||||||
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
|
|
||||||
0 // Standard behavior for the buffer
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VkDescriptorSetLayoutBindingFlagsCreateInfo layoutFlags{
|
VkDescriptorSetLayoutBindingFlagsCreateInfo layoutFlags{
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
|
||||||
.bindingCount = 2,
|
.bindingCount = 1,
|
||||||
.pBindingFlags = flags
|
.pBindingFlags = flags
|
||||||
};
|
};
|
||||||
|
|
||||||
VkDescriptorSetLayoutCreateInfo dslci{
|
VkDescriptorSetLayoutCreateInfo dslci{
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||||
.pNext = &layoutFlags,
|
.pNext = &layoutFlags,
|
||||||
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
|
// .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
|
||||||
.bindingCount = 2,
|
.bindingCount = bindings.size(),
|
||||||
.pBindings = bindings
|
.pBindings = bindings.data()
|
||||||
};
|
};
|
||||||
|
|
||||||
vkCreateDescriptorSetLayout(device, &dslci, nullptr, &descriptor_set_layout);
|
vkCreateDescriptorSetLayout(device, &dslci, nullptr, &descriptor_set_layout);
|
||||||
@ -316,15 +310,14 @@ VkPipeline Renderer::get_pipeline(PipelineType type) const {
|
|||||||
|
|
||||||
void Renderer::create_descriptor_pool() {
|
void Renderer::create_descriptor_pool() {
|
||||||
VkDescriptorPoolSize pool_sizes[] = {
|
VkDescriptorPoolSize pool_sizes[] = {
|
||||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 10 },
|
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, nextTextureSlot },
|
||||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VkDescriptorPoolCreateInfo pool_info{
|
VkDescriptorPoolCreateInfo pool_info{
|
||||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||||
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
|
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
|
||||||
.maxSets = 1,
|
.maxSets = 1,
|
||||||
.poolSizeCount = 2,
|
.poolSizeCount = 1,
|
||||||
.pPoolSizes = pool_sizes
|
.pPoolSizes = pool_sizes
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -340,7 +333,7 @@ void Renderer::create_descriptor_pool() {
|
|||||||
vkAllocateDescriptorSets(device, &alloc_info, &set);
|
vkAllocateDescriptorSets(device, &alloc_info, &set);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::update_bindless_slot(uint32_t slot, VkImageView view, VkSampler sampler) {
|
void Renderer::update_bindless_slot(uint32_t slot, VkImageView view, VkSampler sampler) const {
|
||||||
VkDescriptorImageInfo image_info{
|
VkDescriptorImageInfo image_info{
|
||||||
.sampler = sampler,
|
.sampler = sampler,
|
||||||
.imageView = view,
|
.imageView = view,
|
||||||
@ -350,7 +343,7 @@ void Renderer::update_bindless_slot(uint32_t slot, VkImageView view, VkSampler s
|
|||||||
VkWriteDescriptorSet write{
|
VkWriteDescriptorSet write{
|
||||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
.dstSet = set,
|
.dstSet = set,
|
||||||
.dstArrayElement = slot, // Index in the 1000-size array
|
.dstArrayElement = slot,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||||
.pImageInfo = &image_info
|
.pImageInfo = &image_info
|
||||||
@ -359,9 +352,16 @@ void Renderer::update_bindless_slot(uint32_t slot, VkImageView view, VkSampler s
|
|||||||
vkUpdateDescriptorSets(device, 1, &write, 0, nullptr);
|
vkUpdateDescriptorSets(device, 1, &write, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture Renderer::upload_texture(int w, int h, void* pixels) {
|
void Renderer::upload_texture(
|
||||||
|
const int w,
|
||||||
|
const int h,
|
||||||
|
const void* pixels,
|
||||||
|
VkImage *image,
|
||||||
|
VmaAllocation *allocation,
|
||||||
|
VkImageView *view,
|
||||||
|
uint32_t *descriptor_index)
|
||||||
|
{
|
||||||
VkDeviceSize imageSize = w * h * 4;
|
VkDeviceSize imageSize = w * h * 4;
|
||||||
Texture res{};
|
|
||||||
|
|
||||||
// --- 1. Create Staging Buffer (CPU Visible) ---
|
// --- 1. Create Staging Buffer (CPU Visible) ---
|
||||||
VkBuffer stagingBuffer;
|
VkBuffer stagingBuffer;
|
||||||
@ -371,9 +371,10 @@ Texture Renderer::upload_texture(int w, int h, void* pixels) {
|
|||||||
stagingBufferInfo.size = imageSize;
|
stagingBufferInfo.size = imageSize;
|
||||||
stagingBufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
stagingBufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
|
||||||
VmaAllocationCreateInfo stagingAllocCreateInfo = {};
|
VmaAllocationCreateInfo stagingAllocCreateInfo = {
|
||||||
stagingAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
stagingAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||||
|
};
|
||||||
|
|
||||||
VmaAllocationInfo stagingResultInfo;
|
VmaAllocationInfo stagingResultInfo;
|
||||||
vmaCreateBuffer(allocator, &stagingBufferInfo, &stagingAllocCreateInfo, &stagingBuffer, &stagingAlloc, &stagingResultInfo);
|
vmaCreateBuffer(allocator, &stagingBufferInfo, &stagingAllocCreateInfo, &stagingBuffer, &stagingAlloc, &stagingResultInfo);
|
||||||
@ -384,26 +385,30 @@ Texture Renderer::upload_texture(int w, int h, void* pixels) {
|
|||||||
// --- 2. Create GPU Image (Device Local / Tiled) ---
|
// --- 2. Create GPU Image (Device Local / Tiled) ---
|
||||||
VkExtent3D imageExtent = { (uint32_t) w, (uint32_t) h, 1 };
|
VkExtent3D imageExtent = { (uint32_t) w, (uint32_t) h, 1 };
|
||||||
|
|
||||||
VkImageCreateInfo imageInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
|
VkImageCreateInfo imageInfo = {
|
||||||
imageInfo.imageType = VK_IMAGE_TYPE_2D;
|
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
|
||||||
imageInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
|
.imageType = VK_IMAGE_TYPE_2D,
|
||||||
imageInfo.extent = imageExtent;
|
.format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
imageInfo.mipLevels = 1;
|
.extent = imageExtent,
|
||||||
imageInfo.arrayLayers = 1;
|
.mipLevels = 1,
|
||||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
.arrayLayers = 1,
|
||||||
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||||
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
|
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
||||||
|
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
|
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
|
||||||
|
};
|
||||||
|
|
||||||
VmaAllocationCreateInfo imageAllocCreateInfo = {};
|
VmaAllocationCreateInfo imageAllocCreateInfo = {
|
||||||
imageAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||||
imageAllocCreateInfo.priority = 1.0f; // High priority for textures
|
.priority = 1.0f,
|
||||||
|
};
|
||||||
|
|
||||||
vmaCreateImage(allocator, &imageInfo, &imageAllocCreateInfo, &res.image, &res.allocation, nullptr);
|
vmaCreateImage(allocator, &imageInfo, &imageAllocCreateInfo, image, allocation, nullptr);
|
||||||
|
|
||||||
// --- 3. The Transfer ---
|
// --- 3. The Transfer ---
|
||||||
immediate_submit([&](VkCommandBuffer cmd) {
|
immediate_submit([&](VkCommandBuffer cmd) {
|
||||||
// Transition image from UNDEFINED to TRANSFER_DST
|
// Transition image from UNDEFINED to TRANSFER_DST
|
||||||
transition_image_layout(cmd, res.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
transition_image_layout(cmd, *image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
VkBufferImageCopy copyRegion = {};
|
VkBufferImageCopy copyRegion = {};
|
||||||
copyRegion.bufferOffset = 0;
|
copyRegion.bufferOffset = 0;
|
||||||
@ -415,23 +420,21 @@ Texture Renderer::upload_texture(int w, int h, void* pixels) {
|
|||||||
copyRegion.imageSubresource.layerCount = 1;
|
copyRegion.imageSubresource.layerCount = 1;
|
||||||
copyRegion.imageExtent = imageExtent;
|
copyRegion.imageExtent = imageExtent;
|
||||||
|
|
||||||
vkCmdCopyBufferToImage(cmd, stagingBuffer, res.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Region);
|
vkCmdCopyBufferToImage(cmd, stagingBuffer, *image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Region);
|
||||||
|
|
||||||
// Transition image from TRANSFER_DST to SHADER_READ_ONLY
|
// Transition image from TRANSFER_DST to SHADER_READ_ONLY
|
||||||
transition_image_layout(cmd, res.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
transition_image_layout(cmd, *image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clean up temporary staging resources
|
// Clean up temporary staging resources
|
||||||
vmaDestroyBuffer(allocator, stagingBuffer, stagingAlloc);
|
vmaDestroyBuffer(allocator, stagingBuffer, stagingAlloc);
|
||||||
|
|
||||||
// --- 4. Finalize Handles ---
|
// --- 4. Finalize Handles ---
|
||||||
res.view = create_image_view(res.image, imageInfo.format);
|
*view = create_image_view(*image, imageInfo.format);
|
||||||
|
|
||||||
// Register in your Bindless Array (Set 0, Binding 0, Index N)
|
// Register in your Bindless Array (Set 0, Binding 0, Index N)
|
||||||
res.descriptor_index = nextTextureSlot++;
|
*descriptor_index = nextTextureSlot++;
|
||||||
update_bindless_slot(res.descriptor_index, res.view, defaultSampler);
|
update_bindless_slot(*descriptor_index, *view, defaultSampler);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::immediate_submit(std::function<void(VkCommandBuffer)>&& func) const {
|
void Renderer::immediate_submit(std::function<void(VkCommandBuffer)>&& func) const {
|
||||||
@ -513,25 +516,27 @@ VkImageView Renderer::create_image_view(VkImage image, VkFormat format) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::create_default_sampler() {
|
void Renderer::create_default_sampler() {
|
||||||
VkSamplerCreateInfo samplerInfo{ .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
|
VkSamplerCreateInfo samplerInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
|
||||||
|
// For crisp pixel art, use NEAREST. For smooth textures, use LINEAR.
|
||||||
|
.magFilter = VK_FILTER_NEAREST,
|
||||||
|
.minFilter = VK_FILTER_NEAREST,
|
||||||
|
|
||||||
// For crisp pixel art, use NEAREST. For smooth textures, use LINEAR.
|
.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
|
||||||
samplerInfo.magFilter = VK_FILTER_NEAREST;
|
|
||||||
samplerInfo.minFilter = VK_FILTER_NEAREST;
|
|
||||||
|
|
||||||
// How to handle "out of bounds" UVs
|
// How to handle "out of bounds" UVs
|
||||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
|
||||||
// Optimization: turn off things we don't need for simple 2D
|
// Optimization: turn off things we don't need for simple 2D
|
||||||
samplerInfo.anisotropyEnable = VK_FALSE;
|
.anisotropyEnable = VK_FALSE,
|
||||||
samplerInfo.maxAnisotropy = 1.0f;
|
.maxAnisotropy = 1.0f,
|
||||||
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
.compareEnable = VK_FALSE,
|
||||||
samplerInfo.unnormalizedCoordinates = VK_FALSE;
|
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||||
samplerInfo.compareEnable = VK_FALSE;
|
.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK,
|
||||||
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
.unnormalizedCoordinates = VK_FALSE,
|
||||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
};
|
||||||
|
|
||||||
vkCreateSampler(device, &samplerInfo, nullptr, &defaultSampler);
|
vkCreateSampler(device, &samplerInfo, nullptr, &defaultSampler);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -203,13 +203,20 @@ struct Renderer {
|
|||||||
const Frame &frame,
|
const Frame &frame,
|
||||||
std::span<const vertex_p2_s2_st2_col4_a1_u32> vertices) const;
|
std::span<const vertex_p2_s2_st2_col4_a1_u32> vertices) const;
|
||||||
|
|
||||||
VkPipeline get_pipeline(PipelineType type) const;
|
[[nodiscard]] VkPipeline get_pipeline(PipelineType type) const;
|
||||||
// void bind_material(VkCommandBuffer cmd, uint16_t materialID);
|
// void bind_material(VkCommandBuffer cmd, uint16_t materialID);
|
||||||
void create_descriptor_pool();
|
void create_descriptor_pool();
|
||||||
void update_bindless_slot(uint32_t slot, VkImageView view, VkSampler sampler);
|
void update_bindless_slot(uint32_t slot, VkImageView view, VkSampler sampler) const;
|
||||||
|
|
||||||
// Returns the resource info so the Manager can store it
|
// Returns the resource info so the Manager can store it
|
||||||
Texture upload_texture(int w, int h, void* pixels);
|
void upload_texture(
|
||||||
|
int w,
|
||||||
|
int h,
|
||||||
|
const void* pixels,
|
||||||
|
VkImage *image,
|
||||||
|
VmaAllocation *allocation,
|
||||||
|
VkImageView *view,
|
||||||
|
uint32_t *descriptor_index);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
VkPipeline create_graphics_pipeline(
|
VkPipeline create_graphics_pipeline(
|
||||||
|
|||||||
@ -10,7 +10,7 @@ TextureManager::TextureManager() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t TextureManager::load(const std::string& path, Renderer &renderer) {
|
Texture TextureManager::load(const std::string& path, Renderer &renderer) {
|
||||||
// Dedup: Don't load the same file twice!
|
// Dedup: Don't load the same file twice!
|
||||||
// if (path_to_id.contains(path)) return path_to_id[path];
|
// if (path_to_id.contains(path)) return path_to_id[path];
|
||||||
|
|
||||||
@ -18,13 +18,21 @@ uint32_t TextureManager::load(const std::string& path, Renderer &renderer) {
|
|||||||
unsigned char* data = stbi_load(path.c_str(), &w, &h, &ch, STBI_rgb_alpha);
|
unsigned char* data = stbi_load(path.c_str(), &w, &h, &ch, STBI_rgb_alpha);
|
||||||
|
|
||||||
// Tell the renderer to make the GPU version
|
// Tell the renderer to make the GPU version
|
||||||
Texture res = renderer.upload_texture(w, h, data);
|
Texture res;
|
||||||
|
res.width = w;
|
||||||
|
res.height = h;
|
||||||
|
res.channels = STBI_rgb_alpha;
|
||||||
|
res.srgb = true;
|
||||||
|
renderer.upload_texture(w, h, data, &res.image, &res.allocation, &res.view, &res.descriptor_index);
|
||||||
|
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
|
|
||||||
uint32_t id = static_cast<uint32_t>(textures.size());
|
res.id = path;
|
||||||
|
res.path = path;
|
||||||
|
res.uploaded = true;
|
||||||
|
|
||||||
textures[path] = res;
|
textures[path] = res;
|
||||||
// path_to_id[path] = id;
|
// path_to_id[path] = id;
|
||||||
|
|
||||||
return id; // This is the textureID for your sprites
|
return res; // This is the textureID for your sprites
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,6 @@ typedef std::string texture_id;
|
|||||||
struct Texture {
|
struct Texture {
|
||||||
texture_id id;
|
texture_id id;
|
||||||
std::string path;
|
std::string path;
|
||||||
uint32_t index;
|
|
||||||
|
|
||||||
// NOTE: (vfs) stb_image wants s32 values for the width and height.
|
// NOTE: (vfs) stb_image wants s32 values for the width and height.
|
||||||
int32_t width;
|
int32_t width;
|
||||||
@ -37,7 +36,7 @@ struct TextureManager {
|
|||||||
std::unordered_map<texture_id, Texture> textures;
|
std::unordered_map<texture_id, Texture> textures;
|
||||||
|
|
||||||
TextureManager();
|
TextureManager();
|
||||||
uint32_t load(const std::string& path, Renderer &renderer);
|
Texture load(const std::string& path, Renderer &renderer);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline TextureManager texture_manager;
|
inline TextureManager texture_manager;
|
||||||
|
|||||||
@ -2,4 +2,4 @@
|
|||||||
// Created by Vicente Ferrari Smith on 14.02.26.
|
// Created by Vicente Ferrari Smith on 14.02.26.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "texture_sheet.h"
|
#include "texture_sheet.h"
|
||||||
|
|||||||
@ -17,6 +17,8 @@ struct VSOutput {
|
|||||||
uint32_t tex_id;
|
uint32_t tex_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Sampler2D textures[];
|
||||||
|
|
||||||
static const float2 square[6] = {
|
static const float2 square[6] = {
|
||||||
float2(-0.5, -0.5), // Top-left
|
float2(-0.5, -0.5), // Top-left
|
||||||
float2(-0.5, 0.5), // Bottom-left
|
float2(-0.5, 0.5), // Bottom-left
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user