简体   繁体   中英

What causes textures to be rendered on each triangle of a polygon?

I am trying to render a textured square, but it looks like the texture doesn't get interpolated like it should. It looks like it gets mirrored on each triangle of my square. Behavior is presented on the image below.

Note that I'm using this tutorial.

如您所见,每个三角形都有其自己的纹理。

I don't have an idea where to start fixing my code. Also, when I try to translate my Image layout, I get this error: "Cannot submit cmd buffer using image 0x25 with layout VK_IMAGE_LAYOUT_UNDEFINED when first use is VK_IMAGE_LAYOUT_TRANSFER_DST_BIT."

Also, I get this warning when submitting a drawing command buffer for the first time: "Cannot submit cmd buffer using image 0x25 with layout VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL when first use is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL."

Can this warning cause my issue? Also, here are my vertices and its texture coordinates.

vertices->setVertices({
{{-1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}},
{{1.0f, -1.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
{{1.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
{{-1.0f, 1.0f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}
    });

vertices->setIndices({ 0, 1, 2, 2, 3, 0 });

Update:

Here is my image transition code:

void Util::transitionImageLayout(VkImage *image, VkFormat format, 
                                 VkImageLayout oldLayout, VkImageLayout newLayout,
                                 VkCommandBuffer recordingBuffer) {
    VkImageMemoryBarrier barrier = {};
    VkImageSubresourceRange subresourceRange = {};
    VkPipelineStageFlags sourceStage = {};
    VkPipelineStageFlags dstStage = {};

    if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
        barrier.srcAccessMask = 0;
        barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;

        sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
        dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
    }
    else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
        barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
        barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;

        sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
        dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
    }
    else {
        throw std::invalid_argument("Layout transition not supported.");
    }

    subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    subresourceRange.baseArrayLayer = 0;
    subresourceRange.baseMipLevel = 0;
    subresourceRange.layerCount = 1;
    subresourceRange.levelCount = 1;

    barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    barrier.image = *image;
    barrier.oldLayout = oldLayout;
    barrier.newLayout = newLayout;
    barrier.subresourceRange = subresourceRange;
    barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;  
    barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;

    vkCmdPipelineBarrier(recordingBuffer, sourceStage, dstStage, 0, 0, nullptr, 0, nullptr, 0, &barrier);
}

Here is my copy buffer to image code:

void Util::copyBufferToimage(VkCommandBuffer cmdBuffer, VkBuffer buffer, 
                             VkImage *image, uint32_t width, uint32_t height) {
     VkBufferImageCopy region{};
     VkImageSubresourceLayers subresouce{};

     subresouce.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
     subresouce.baseArrayLayer = 0;
     subresouce.mipLevel = 0;
     subresouce.layerCount = 1;

     region.bufferImageHeight = 0;
     region.bufferOffset = 0;                                   
     region.bufferRowLength = 0;
     region.imageOffset = { 0, 0, 0 };                          
     region.imageExtent = { width, height, 1 };                 
     region.imageSubresource = subresouce;                      
     vkCmdCopyBufferToImage(cmdBuffer, buffer, *image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
 }

Notes: I have tried running the project from tutorial's git repo, and it works fine. They get no warnings.

The problem was in my vertices struct code which I didn't provide. Format of texture coordinates was wrong. It should be R32 G32 , and I have set it to R32 G32 B32 A32 .

static std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions() {
    std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions = {};

    attributeDescriptions[0].binding = 0;                           
    attributeDescriptions[0].location = 0;                          
    attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
    attributeDescriptions[0].offset = offsetof(Vertex, position);

    attributeDescriptions[1].binding = 0;
    attributeDescriptions[1].location = 1;
    attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
    attributeDescriptions[1].offset = offsetof(Vertex, color);

    attributeDescriptions[2].binding = 0;
    attributeDescriptions[2].location = 2;
    attributeDescriptions[2].format = VK_FORMAT_R32G32B32A32_SFLOAT;      //This is an error. I guess this has to do something with texCoord being a glm::vec2
    attributeDescriptions[2].offset = offsetof(Vertex, texCoord);

    return attributeDescriptions;
}

So, attributes descriptions format regarding the texture coordinates should be

attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;

Now my polygon looks like this:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM