Files
funnygame/engine/vk_video.cpp
2025-05-31 00:42:41 +03:00

546 lines
18 KiB
C++

#include "filesystem.h"
#include "rendering.h"
#include "tier0/lib.h"
#include "tier1/utlvector.h"
#include "vk_helper.h"
#include "tier0/platform.h"
#include "vulkan/vulkan_core.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
VkSampler g_invalidTextureSampler;
vk_buffer_t g_cameraProperties;
CameraProjection *g_cameraDataMap;
IMaterial *g_pDefaultMaterial;
IMaterial *g_pCurrentMaterial;
vk_image2d_t g_meshDepth;
vk_image2d_t g_meshDepthMSAA;
vk_image2d_t g_meshColor;
vk_image2d_t g_meshColorMSAA;
void IVulkan::Init()
{
char invalidTexture[1024] = {};
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
int index = i * 16 + j;
if ((i + j) % 2 == 0) {
invalidTexture[index*4] = 255;
}
}
}
ITextureManager::LoadTexture(invalidTexture, 16, 16, 4);
VkPhysicalDeviceProperties properties{};
vkGetPhysicalDeviceProperties(g_vkPhysicalDevice, &properties);
VkSamplerCreateInfo samplerInfo{};
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerInfo.magFilter = VK_FILTER_NEAREST;
samplerInfo.minFilter = VK_FILTER_NEAREST;
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.anisotropyEnable = VK_FALSE;
samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
samplerInfo.unnormalizedCoordinates = VK_FALSE;
samplerInfo.compareEnable = VK_FALSE;
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
samplerInfo.mipLodBias = 0.0f;
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = 0.0f;
vkCreateSampler(g_vkDevice, &samplerInfo, nullptr, &g_invalidTextureSampler);
g_cameraProperties.Create(sizeof(CameraProjection), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
g_cameraDataMap = (CameraProjection*)g_cameraProperties.Map(0, 64);
g_meshDepth.Create(1280, 720, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_SAMPLE_COUNT_1_BIT);
g_meshDepthMSAA.Create(1280, 720, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_4_BIT);
g_meshColor.Create(1280, 720, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_SAMPLE_COUNT_1_BIT);
g_meshColorMSAA.Create(1280, 720, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_4_BIT);
IMeshRenderer::Init();
};
void IVulkan::Frame()
{
glm_mat4_identity(g_cameraDataMap->viewprojection);
glm_perspective(glm_rad(90),(float)g_nWindowWidth/g_nWindowHeight, 0.01, 100, g_cameraDataMap->viewprojection);
glm_rotate(g_cameraDataMap->viewprojection, glm_rad(90), (vec4){1,0,0,0});
glm_scale(g_cameraDataMap->viewprojection, (vec4){1,-1,1,1});
glm_rotate(g_cameraDataMap->viewprojection, glm_rad(90), (vec4){0,0,1,0});
if (g_bConfigNotify)
{
g_meshDepth.Destroy();
g_meshDepthMSAA.Destroy();
g_meshColor.Destroy();
g_meshColorMSAA.Destroy();
g_meshDepth.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_SAMPLE_COUNT_1_BIT);
g_meshDepthMSAA.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_1_BIT);
g_meshColor.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_SAMPLE_COUNT_1_BIT);
g_meshColorMSAA.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_4_BIT);
}
IMeshRenderer::Frame(0);
};
void vk_shader_t::Create( const char *szPath, VkShaderStageFlagBits shaderStage )
{
FileHandle_t shader = IFileSystem::Open(szPath, IFILE_READ);
if (!shader)
Plat_FatalErrorFunc("Failed to open shader %s\n", szPath);
CUtlBuffer<uint8_t> buffer(IFileSystem::Size(shader));
IFileSystem::Read(shader, buffer.GetMemory(), buffer.GetSize());
Create(buffer, shaderStage);
IFileSystem::Close(shader);
}
void vk_shader_t::Create( CUtlBuffer<uint8_t> &spirv, VkShaderStageFlagBits shaderStage )
{
if (m_shaderModule != NULL)
Plat_FatalErrorFunc("Shader already exists");
VkShaderModuleCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = spirv.GetSize();
createInfo.pCode = (uint32_t*)spirv.GetMemory();
vkCreateShaderModule(g_vkDevice, &createInfo, NULL, &m_shaderModule);
m_stageCreateInfo = {};
m_stageCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
m_stageCreateInfo.module = m_shaderModule;
m_stageCreateInfo.stage = shaderStage;
m_stageCreateInfo.pName = "main";
}
void vk_shader_t::Destroy( void )
{
if (m_shaderModule == NULL)
Plat_FatalErrorFunc("Shader doesn't exist");
vkDestroyShaderModule(g_vkDevice, m_shaderModule, NULL);
}
void vk_tripipeline_t::Create(
CUtlVector<vk_shader_t> &shaders,
CUtlVector<VkDescriptorSetLayoutBinding> &bindings,
uint32_t pushConstantSize,
CUtlVector<VkFormat> formats
)
{
VkPushConstantRange pushConstantRange = {};
pushConstantRange.stageFlags = VK_SHADER_STAGE_ALL;
pushConstantRange.offset = 0;
pushConstantRange.size = pushConstantSize;
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {};
descriptorSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptorSetLayoutCreateInfo.bindingCount = bindings.GetSize();
descriptorSetLayoutCreateInfo.pBindings = bindings.GetData();
vkCreateDescriptorSetLayout(g_vkDevice, &descriptorSetLayoutCreateInfo, NULL, &m_descriptorSetLayout);
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {};
pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutCreateInfo.setLayoutCount = 1;
pipelineLayoutCreateInfo.pSetLayouts = &m_descriptorSetLayout;
if (pushConstantSize != 0)
{
pipelineLayoutCreateInfo.pushConstantRangeCount = 1;
pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange;
}
vkCreatePipelineLayout(g_vkDevice, &pipelineLayoutCreateInfo, NULL, &m_layout);
VkDynamicState dynamicStates[] = {
/* pVertexInputState */
VK_DYNAMIC_STATE_VERTEX_INPUT_EXT,
/* pInputAssemblyState */
VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE,
VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY,
/* pTessellationState */
VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT,
/* pViewportState */
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT,
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,
/* pRasterizationState */
VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT,
VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE,
VK_DYNAMIC_STATE_POLYGON_MODE_EXT,
VK_DYNAMIC_STATE_CULL_MODE,
VK_DYNAMIC_STATE_FRONT_FACE,
VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE,
VK_DYNAMIC_STATE_DEPTH_BIAS,
VK_DYNAMIC_STATE_LINE_WIDTH,
/* pMultisampleState */
VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
/* pDepthStencilState */
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE,
VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE,
VK_DYNAMIC_STATE_DEPTH_COMPARE_OP,
VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE,
VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE,
VK_DYNAMIC_STATE_STENCIL_OP,
VK_DYNAMIC_STATE_DEPTH_BOUNDS,
/* pColorBlendState */
VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
VK_DYNAMIC_STATE_LOGIC_OP_EXT,
VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
};
VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.dynamicStateCount = sizeof(dynamicStates)/sizeof(VkDynamicState),
.pDynamicStates = dynamicStates,
};
VkPipelineInputAssemblyStateCreateInfo piasci = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
.primitiveRestartEnable = VK_TRUE,
};
VkPipelineRenderingCreateInfo prci = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
.pNext = NULL,
.colorAttachmentCount = (uint32_t)formats.GetSize(),
.pColorAttachmentFormats = formats.GetData(),
.depthAttachmentFormat = VK_FORMAT_D32_SFLOAT,
};
VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {};
graphicsPipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
graphicsPipelineCreateInfo.pInputAssemblyState = &piasci;
graphicsPipelineCreateInfo.layout = m_layout;
graphicsPipelineCreateInfo.pDynamicState = &pipelineDynamicStateCreateInfo;
graphicsPipelineCreateInfo.stageCount = shaders.GetSize();
CUtlVector<VkPipelineShaderStageCreateInfo> stages(graphicsPipelineCreateInfo.stageCount);
uint32_t i = 0;
for (auto &shader: shaders)
{
stages[i] = shader.m_stageCreateInfo;
i++;
}
graphicsPipelineCreateInfo.pStages = stages.GetData();
graphicsPipelineCreateInfo.pNext = &prci;
vkCreateGraphicsPipelines(g_vkDevice, NULL, 1, &graphicsPipelineCreateInfo, NULL, &m_pipeline);
}
void vk_tripipeline_t::Destroy()
{
}
void vk_buffer_t::Create(size_t size, VkBufferUsageFlags usage)
{
VkBufferCreateInfo bufferCreateInfo = {};
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferCreateInfo.usage = usage;
bufferCreateInfo.size = size;
VmaAllocationCreateInfo allocInfo = {};
allocInfo.usage = VMA_MEMORY_USAGE_AUTO;
allocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
VMA_ALLOCATION_CREATE_MAPPED_BIT;
m_nSize = size;
vmaCreateBuffer(g_allocator, &bufferCreateInfo, &allocInfo, &m_buffer, &m_memory, NULL);
}
void vk_buffer_t::Destroy()
{
}
void *vk_buffer_t::Map(size_t offset, size_t size)
{
void *pData;
vmaMapMemory(g_allocator, m_memory, &pData);
return pData;
}
void vk_buffer_t::Unmap()
{
vmaUnmapMemory(g_allocator, m_memory);
}
void vk_buffer_t::CopyTo(struct vk_image2d_t *image)
{
}
void vk_buffer_t::CopyTo(struct vk_buffer_t *buffer)
{
}
void vk_image2d_t::Create(size_t x, size_t y, VkFormat format, VkImageUsageFlags usage, VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT)
{
VkImageCreateInfo imageInfo={};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.extent.width = x > 1 ? x : 1;
imageInfo.extent.height = y > 1 ? y : 1;
imageInfo.extent.depth = 1;
imageInfo.mipLevels = 1;
imageInfo.arrayLayers = 1;
imageInfo.usage = usage;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageInfo.format=format;
imageInfo.samples = samples;
VmaAllocationCreateInfo alloc = {};
alloc.usage=VMA_MEMORY_USAGE_AUTO;
vmaCreateImage(g_allocator, &imageInfo,&alloc, &m_image, &m_memory,0);
m_X=imageInfo.extent.width;
m_Y=imageInfo.extent.width;
m_format=format;
VkImageView imageView = 0;
VkImageViewCreateInfo imageViewCreateInfo={};
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageViewCreateInfo.format = format;
imageViewCreateInfo.image = m_image;
imageViewCreateInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
if (format == VK_FORMAT_D32_SFLOAT) {
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
}
imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
imageViewCreateInfo.subresourceRange.levelCount = 1;
imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
imageViewCreateInfo.subresourceRange.layerCount = 1;
vkCreateImageView(g_vkDevice, &imageViewCreateInfo, 0, &m_imageView);
}
void vk_image2d_t::Destroy()
{
vkDestroyImageView(g_vkDevice, m_imageView, NULL);
vmaDestroyImage(g_allocator, m_image, NULL);
}
void CopyTo(struct vk_image2d_t *image);
void CopyTo(struct vk_buffer_t *buffer);
void *CVertexBuffer::Map()
{
if (!m_pAllocated)
m_pAllocated = m_buffer.Map(0, m_buffer.m_nSize);
return m_pAllocated;
};
void CVertexBuffer::Unmap()
{
if (!m_pAllocated)
return;
m_buffer.Unmap();
m_pAllocated = 0;
};
void *CIndexBuffer::Map()
{
if (!m_pAllocated)
m_pAllocated = m_buffer.Map(0, m_buffer.m_nSize);
return m_pAllocated;
};
void CIndexBuffer::Unmap()
{
if (!m_pAllocated)
return;
m_buffer.Unmap();
m_pAllocated = 0;
};
CUtlVector<ITexture*> g_textures;
CUtlVector<ITexture*> g_newtextures;
uint32_t ITextureManager::GetTexture(ITexture *pTexture)
{
uint32_t i = 0;
for (ITexture *texture: g_textures)
{
if (texture == pTexture)
return i;
i++;
};
return 0;
}
ITexture *ITextureManager::LoadTexture( void *pData, uint32_t X, uint32_t Y, uint32_t numChannels )
{
CTexture *pTexture = new CTexture;
*pTexture = {};
VkDeviceSize imageSize = X*Y*4;
vk_buffer_t gpu_buffer = {};
gpu_buffer.Create(imageSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
void *gpu_buffer_map = gpu_buffer.Map(0, 0);
V_memcpy(gpu_buffer_map, pData, imageSize);
gpu_buffer.Unmap();
pTexture->image = {};
pTexture->image.Create(X, Y, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
VkCommandPool commandPool;
VkCommandBuffer commandBuffer;
VkCommandPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
poolInfo.queueFamilyIndex = g_drawfamily;
poolInfo.flags = 0;
vkCreateCommandPool(g_vkDevice, &poolInfo, NULL, &commandPool);
VkCommandBufferAllocateInfo cmdAllocInfo{};
cmdAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
cmdAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
cmdAllocInfo.commandPool = commandPool;
cmdAllocInfo.commandBufferCount = 1;
vkAllocateCommandBuffers(g_vkDevice, &cmdAllocInfo, &commandBuffer);
VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
vkBeginCommandBuffer(commandBuffer, &beginInfo);
VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = pTexture->image.m_image;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
vkCmdPipelineBarrier(
commandBuffer,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0,
0, NULL,
0, NULL,
1, &barrier
);
VkBufferImageCopy region{};
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = {0, 0, 0};
region.imageExtent = {(uint32_t)X, (uint32_t)Y, 1};
vkCmdCopyBufferToImage(
commandBuffer,
gpu_buffer.m_buffer,
pTexture->image.m_image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
&region
);
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
vkCmdPipelineBarrier(
commandBuffer,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
0,
0, NULL,
0, NULL,
1, &barrier
);
vkEndCommandBuffer(commandBuffer);
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;
vkQueueSubmit(g_drawQueue, 1, &submitInfo, VK_NULL_HANDLE);
vkQueueWaitIdle(g_drawQueue);
vkFreeCommandBuffers(g_vkDevice, commandPool, 1, &commandBuffer);
vkDestroyCommandPool(g_vkDevice, commandPool, NULL);
g_newtextures.AppendTail(pTexture);
g_textures.AppendTail(pTexture);
return pTexture;
};
ITexture *ITextureManager::LoadTexture( const char *szName )
{
for (ITexture *texture: g_textures)
{
if (!texture->szName)
continue;
if (!V_strcmp(texture->szName, szName))
return texture;
};
FileHandle_t file = IFileSystem::Open(szName, IFILE_READ);
if (!file)
Plat_FatalErrorFunc("Failed to load %s\n", szName);
CUtlBuffer<stbi_uc> buffer(IFileSystem::Size(file));
IFileSystem::Read(file, buffer.GetMemory(), buffer.GetSize());
int nImageX;
int nImageY;
int nImageChannels;
stbi_uc *pixels = stbi_load_from_memory((stbi_uc*)buffer.GetMemory(), buffer.GetSize(), &nImageX, &nImageY, &nImageChannels, STBI_rgb_alpha);
ITexture *pTexture = ITextureManager::LoadTexture(pixels, nImageX, nImageY, 4);
pTexture->szName = szName;
return pTexture;
};
IMaterial *IRenderer::LoadMaterial( const char *szMaterial )
{
FileHandle_t file = IFileSystem::Open(szMaterial, IFILE_READ);
IMaterial *pMaterial = new IMaterial;
if (!file)
{
return g_pDefaultMaterial;
}
IFileSystem::Close(file);
}
void IRenderer::SetMaterial( IMaterial *pMaterial )
{
g_pCurrentMaterial = pMaterial;
}
IVertexBuffer *IRenderer::CreateVertexBuffer( uint32_t uSize )
{
CVertexBuffer *pBuffer = new CVertexBuffer();
pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
return pBuffer;
}
IIndexBuffer *IRenderer::CreateIndexBuffer( uint32_t uSize )
{
CIndexBuffer *pBuffer = new CIndexBuffer();
pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
return pBuffer;
}