mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
Implement drawing very basic textures
With this commit you can draw very simple textures.
The following code will showcase it:
```lua
function love.run()
local data = love.image.newImageData(40, 40)
for i = 0,39 do
for j=0,39 do
if i <= 20 then
if j <= 20 then
data:setPixel(i, j, 1, 0, 0, 1)
else
data:setPixel(i, j, 0, 1, 0, 1)
end
else
if j <= 20 then
data:setPixel(i, j, 0, 0, 1, 1)
else
data:setPixel(i, j, 1, 1, 1, 1)
end
end
end
end
local texture
texture = love.graphics.newTexture(data)
return function()
love.event.pump()
for name, a,b,c,d,e,f in love.event.poll() do
if name == "quit" then
if not love.quit or not love.quit() then
return a or 0
end
end
love.handlers[name](a,b,c,d,e,f)
end
love.graphics.origin()
love.graphics.clear()
love.graphics.draw(texture, 50, 500)
love.graphics.present()
end
end
```
This commit is contained in:
@@ -205,7 +205,6 @@ namespace love {
|
||||
createUniformBuffers();
|
||||
createDefaultTexture();
|
||||
createDescriptorPool();
|
||||
createDescriptorSets();
|
||||
createSyncObjects();
|
||||
startRecordingGraphicsCommands();
|
||||
|
||||
@@ -282,11 +281,24 @@ namespace love {
|
||||
|
||||
std::vector<VkBuffer> buffers;
|
||||
std::vector<VkDeviceSize> offsets;
|
||||
|
||||
// vertices
|
||||
buffers.push_back((VkBuffer)cmd.buffers->info[0].buffer->getHandle());
|
||||
offsets.push_back((VkDeviceSize)0);
|
||||
|
||||
vkCmdBindDescriptorSets(commandBuffers.at(imageIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSets.at(currentFrame), 0, nullptr);
|
||||
vkCmdBindVertexBuffers(commandBuffers.at(imageIndex), 0, 1, buffers.data(), offsets.data());
|
||||
// tex coords
|
||||
buffers.push_back((VkBuffer)cmd.buffers->info[1].buffer->getHandle());
|
||||
offsets.push_back((VkDeviceSize)0);
|
||||
|
||||
if (cmd.texture == nullptr) {
|
||||
setTexture(standardTexture);
|
||||
}
|
||||
else {
|
||||
setTexture(cmd.texture);
|
||||
}
|
||||
|
||||
vkCmdBindDescriptorSets(commandBuffers.at(imageIndex), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, getDescriptorSet(currentFrame), 0, nullptr);
|
||||
vkCmdBindVertexBuffers(commandBuffers.at(imageIndex), 0, buffers.size(), buffers.data(), offsets.data());
|
||||
vkCmdBindIndexBuffer(commandBuffers.at(imageIndex), (VkBuffer)cmd.indexBuffer->getHandle(), 0, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdDrawIndexed(commandBuffers.at(imageIndex), static_cast<uint32_t>(cmd.indexCount), 1, 0, 0, 0);
|
||||
}
|
||||
@@ -298,6 +310,15 @@ namespace love {
|
||||
|
||||
// END IMPLEMENTATION OVERRIDDEN FUNCTIONS
|
||||
|
||||
VkDescriptorSet* Graphics::getDescriptorSet(int currentFrame) {
|
||||
auto it = textureToDescriptorSetsMap.find(currentTexture);
|
||||
if (it == textureToDescriptorSetsMap.end()) {
|
||||
textureToDescriptorSetsMap[currentTexture] = createDescriptorSets(currentTexture);
|
||||
}
|
||||
|
||||
return &textureToDescriptorSetsMap.at(currentTexture)[currentFrame];
|
||||
}
|
||||
|
||||
VkCommandBuffer Graphics::beginSingleTimeCommands() {
|
||||
VkCommandBufferAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
@@ -876,7 +897,7 @@ namespace love {
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::createDescriptorSets() {
|
||||
std::vector<VkDescriptorSet> Graphics::createDescriptorSets(graphics::Texture* texture) {
|
||||
std::vector<VkDescriptorSetLayout> layouts(MAX_FRAMES_IN_FLIGHT, descriptorSetLayout);
|
||||
VkDescriptorSetAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
@@ -884,26 +905,28 @@ namespace love {
|
||||
allocInfo.descriptorSetCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
|
||||
allocInfo.pSetLayouts = layouts.data();
|
||||
|
||||
descriptorSets.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
if (vkAllocateDescriptorSets(device, &allocInfo, descriptorSets.data()) != VK_SUCCESS) {
|
||||
std::vector<VkDescriptorSet> newDescriptorSets;
|
||||
|
||||
newDescriptorSets.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
if (vkAllocateDescriptorSets(device, &allocInfo, newDescriptorSets.data()) != VK_SUCCESS) {
|
||||
throw love::Exception("failed to allocate descriptor sets");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
||||
VkDescriptorBufferInfo bufferInfo{};
|
||||
bufferInfo.buffer = (VkBuffer) uniformBuffers.at(i)->getHandle();
|
||||
bufferInfo.buffer = (VkBuffer)uniformBuffers.at(i)->getHandle();
|
||||
bufferInfo.offset = 0;
|
||||
bufferInfo.range = sizeof(Shader::UniformBufferObject);
|
||||
|
||||
VkDescriptorImageInfo imageInfo{};
|
||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
Texture* vkTexture = (Texture*)standardTexture;
|
||||
Texture* vkTexture = (Texture*)texture;
|
||||
imageInfo.imageView = vkTexture->getImageView();
|
||||
imageInfo.sampler = vkTexture->getSampler();
|
||||
|
||||
std::array<VkWriteDescriptorSet, 2> descriptorWrite{};
|
||||
descriptorWrite[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWrite[0].dstSet = descriptorSets[i];
|
||||
descriptorWrite[0].dstSet = newDescriptorSets[i];
|
||||
descriptorWrite[0].dstBinding = 0;
|
||||
descriptorWrite[0].dstArrayElement = 0;
|
||||
descriptorWrite[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
@@ -911,7 +934,7 @@ namespace love {
|
||||
descriptorWrite[0].pBufferInfo = &bufferInfo;
|
||||
|
||||
descriptorWrite[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptorWrite[1].dstSet = descriptorSets[i];
|
||||
descriptorWrite[1].dstSet = newDescriptorSets[i];
|
||||
descriptorWrite[1].dstBinding = 1;
|
||||
descriptorWrite[1].dstArrayElement = 0;
|
||||
descriptorWrite[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
@@ -920,6 +943,8 @@ namespace love {
|
||||
|
||||
vkUpdateDescriptorSets(device, static_cast<uint32_t>(descriptorWrite.size()), descriptorWrite.data(), 0, nullptr);
|
||||
}
|
||||
|
||||
return newDescriptorSets;
|
||||
}
|
||||
|
||||
void Graphics::createGraphicsPipeline() {
|
||||
@@ -934,17 +959,30 @@ namespace love {
|
||||
vertexBindingDescription.stride = 2 * sizeof(float); // just position for now
|
||||
vertexBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
// todo later
|
||||
VkVertexInputAttributeDescription positionInputAttributeDescription;
|
||||
positionInputAttributeDescription.binding = 0;
|
||||
positionInputAttributeDescription.location = 0;
|
||||
positionInputAttributeDescription.format = VK_FORMAT_R32G32_SFLOAT;
|
||||
positionInputAttributeDescription.offset = 0;
|
||||
|
||||
vertexInputInfo.vertexBindingDescriptionCount = 1;
|
||||
vertexInputInfo.pVertexBindingDescriptions = &vertexBindingDescription;
|
||||
vertexInputInfo.vertexAttributeDescriptionCount = 1;
|
||||
vertexInputInfo.pVertexAttributeDescriptions = &positionInputAttributeDescription;
|
||||
VkVertexInputBindingDescription texCoordsBindingDescription;
|
||||
texCoordsBindingDescription.binding = 1;
|
||||
texCoordsBindingDescription.stride = 3 * sizeof(float); // 2 floats for texture coordinates, 1 float for color
|
||||
texCoordsBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
VkVertexInputAttributeDescription texCoordsInputAttributeDescription;
|
||||
texCoordsInputAttributeDescription.binding = 1;
|
||||
texCoordsInputAttributeDescription.location = 1;
|
||||
texCoordsInputAttributeDescription.format = VK_FORMAT_R32G32_SFLOAT;
|
||||
texCoordsInputAttributeDescription.offset = 0;
|
||||
|
||||
std::vector<VkVertexInputBindingDescription> bindingDescriptions = { vertexBindingDescription, texCoordsBindingDescription };
|
||||
std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions = { positionInputAttributeDescription, texCoordsInputAttributeDescription };
|
||||
|
||||
vertexInputInfo.vertexBindingDescriptionCount = bindingDescriptions.size();
|
||||
vertexInputInfo.pVertexBindingDescriptions = bindingDescriptions.data();
|
||||
vertexInputInfo.vertexAttributeDescriptionCount = vertexInputAttributeDescriptions.size();
|
||||
vertexInputInfo.pVertexAttributeDescriptions = vertexInputAttributeDescriptions.data();
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
|
||||
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
@@ -1119,6 +1157,7 @@ namespace love {
|
||||
void Graphics::cleanup() {
|
||||
vkDeviceWaitIdle(device);
|
||||
|
||||
|
||||
cleanupSwapChain();
|
||||
|
||||
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
||||
@@ -1149,6 +1188,7 @@ namespace love {
|
||||
}
|
||||
vkDestroySwapchainKHR(device, swapChain, nullptr);
|
||||
uniformBuffers.clear();
|
||||
textureToDescriptorSetsMap.clear();
|
||||
}
|
||||
|
||||
void Graphics::recreateSwapChain() {
|
||||
@@ -1163,7 +1203,6 @@ namespace love {
|
||||
createFramebuffers();
|
||||
createUniformBuffers();
|
||||
createDescriptorPool();
|
||||
createDescriptorSets();
|
||||
createCommandBuffers();
|
||||
startRecordingGraphicsCommands();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user