Exemplo n.º 1
0
VkBool32 VKTS_APIENTRY imageDataSaveGli(const std::string& name, const IImageDataSP& imageData, const uint32_t mipLevel, const uint32_t arrayLayer)
{
	gli::format format = imageDataTranslateFormat(imageData->getFormat());

	if (format == gli::FORMAT_UNDEFINED)
	{
		return VK_FALSE;
	}

	VkExtent3D currentExtent;
	size_t currentOffset;
	if (!imageData->getExtentAndOffset(currentExtent, currentOffset, mipLevel, arrayLayer))
	{
		return VK_FALSE;
	}

	gli::texture::extent_type extent{currentExtent.width, currentExtent.height, currentExtent.depth};

	gli::texture texture(gli::TARGET_2D, format, extent, 1, 1, 1);

	VkSubresourceLayout subresourceLayout{0, (VkDeviceSize)texture.size(0), texture.size(0) / extent.y, 0, 0};

	if (!imageData->copy(texture.data(0, 0, 0), mipLevel, arrayLayer, subresourceLayout))
	{
		return VK_FALSE;
	}

	return (VkBool32)gli::save(texture, name.c_str());
}
Exemplo n.º 2
0
glm::vec3 VKTS_APIENTRY renderLambert(const IImageDataSP& cubeMap, const VkFilter filter, const uint32_t mipLevel, const glm::vec2& randomPoint, const glm::mat3& basis)
{
	if (!cubeMap.get() || cubeMap->getArrayLayers() != 6)
	{
		return glm::vec3(0.0f, 0.0f, 0.0f);
	}

	glm::vec3 LtangentSpace = renderGetCosineWeightedVector(randomPoint);

	// Transform light ray to world space.
	glm::vec3 L = basis * LtangentSpace;

	return glm::vec3(cubeMap->getSampleCubeMap(L.x, L.y, L.z, filter, mipLevel));
}
Exemplo n.º 3
0
glm::vec3 VKTS_APIENTRY renderCookTorrance(const IImageDataSP& cubeMap, const VkFilter filter, const uint32_t mipLevel, const glm::vec2& randomPoint, const glm::mat3& basis, const glm::vec3& N, const glm::vec3& V, const float roughness)
{
	if (!cubeMap.get() || cubeMap->getArrayLayers() != 6)
	{
		return glm::vec3(0.0f, 0.0f, 0.0f);
	}

	glm::vec3 HtangentSpace = renderGetGGXWeightedVector(randomPoint, roughness);

	// Transform H to world space.
	glm::vec3 H = basis * HtangentSpace;

	// Note: reflect takes incident vector.
	glm::vec3 L = glm::reflect(-V, H);

	return glm::vec3(cubeMap->getSampleCubeMap(L.x, L.y, L.z, filter, mipLevel));
}
Exemplo n.º 4
0
glm::vec3 VKTS_APIENTRY renderOrenNayar(const IImageDataSP& cubeMap, const VkFilter filter, const uint32_t mipLevel, const glm::vec2& randomPoint, const glm::mat3& basis, const glm::vec3& N, const glm::vec3& V, const float roughness)
{
	if (!cubeMap.get() || cubeMap->getArrayLayers() != 6)
	{
		return glm::vec3(0.0f, 0.0f, 0.0f);
	}

	glm::vec3 LtangentSpace = renderGetCosineWeightedVector(randomPoint);

	// Transform light ray to world space.
	glm::vec3 L = basis * LtangentSpace;


    float NdotL = glm::dot(N, L);
    float NdotV = glm::dot(N, V);

    float angleVN = acosf(NdotV);
    float angleLN = acosf(NdotL);

    float alpha = glm::max(angleVN, angleLN);
    float beta = glm::min(angleVN, angleLN);
    float gamma = glm::dot(V - N * NdotV, L - N * NdotL);


    float roughnessSquared = roughness * roughness;


    float A = 1.0f - 0.5f * (roughnessSquared / (roughnessSquared + 0.57f));

    float B = 0.45f * (roughnessSquared / (roughnessSquared + 0.09f));

    float C = sinf(alpha) * tanf(beta);


    float Lr = glm::max(0.0f, NdotL) * (A + B * glm::max(0.0f, gamma) * C);


	return glm::vec3(cubeMap->getSampleCubeMap(L.x, L.y, L.z, filter, mipLevel)) * Lr;
}
Exemplo n.º 5
0
SmartPointerVector<IImageDataSP> VKTS_APIENTRY imageDataCubemap(const IImageDataSP& sourceImage, const std::string& name)
{
    if (name.size() == 0 || !sourceImage.get())
    {
        return SmartPointerVector<IImageDataSP>();
    }

    std::string sourceImageFilename = name;

    auto dotIndex = sourceImageFilename.rfind(".");

    if (dotIndex == sourceImageFilename.npos)
    {
        return SmartPointerVector<IImageDataSP>();
    }

    auto sourceImageName = sourceImageFilename.substr(0, dotIndex);
    auto sourceImageExtension = sourceImageFilename.substr(dotIndex);

    // TODO: Implement.

    return SmartPointerVector<IImageDataSP>();
}
Exemplo n.º 6
0
IMemoryImageSP VKTS_APIENTRY memoryImageCreate(IImageSP& stageImage, IBufferSP& stageBuffer, IDeviceMemorySP& stageDeviceMemory, const IInitialResourcesSP& initialResources, const ICommandBuffersSP& cmdBuffer, const std::string& name, const IImageDataSP& imageData, const VkImageCreateInfo& imageCreateInfo, const VkAccessFlags srcAccessMask, const VkAccessFlags dstAccessMask, const VkImageLayout newLayout, const VkImageSubresourceRange& subresourceRange, const VkMemoryPropertyFlags memoryPropertyFlags)
{
    if (!cmdBuffer || !imageData.get())
    {
        return IMemoryImageSP();
    }

    VkResult result;

    //

    IImageSP image;

    IDeviceMemorySP deviceMemory;

    //

    if (!memoryImagePrepare(image, deviceMemory, initialResources, cmdBuffer, imageCreateInfo, srcAccessMask, dstAccessMask, newLayout, subresourceRange, memoryPropertyFlags))
    {
        return IMemoryImageSP();
    }

    //

    if (memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
    {
        for (uint32_t i = 0; i < imageData->getMipLevels(); i++)
        {
            VkImageSubresource imageSubresource;

            imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
            imageSubresource.mipLevel = i;
            imageSubresource.arrayLayer = 0;

            VkSubresourceLayout subresourceLayout;

            image->getImageSubresourceLayout(subresourceLayout, imageSubresource);

            if (!memoryImageUpload(deviceMemory, imageData, i, subresourceLayout))
            {
                logPrint(VKTS_LOG_ERROR, "MemoryImage: Could not upload image data.");

                return IMemoryImageSP();
            }
        }
    }
    else
    {
        if (initialResources->getPhysicalDevice()->isImageTilingAvailable(VK_IMAGE_TILING_LINEAR, imageData->getFormat(), imageData->getImageType(), 0, imageData->getExtent3D(), imageData->getMipLevels(), 1, VK_SAMPLE_COUNT_1_BIT, imageData->getSize()))
        {
            VkImageCreateInfo stageImageCreateInfo;

            memcpy(&stageImageCreateInfo, &imageCreateInfo, sizeof(VkImageCreateInfo));

            stageImageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR;
            stageImageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
            stageImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;

            if (!memoryImagePrepare(stageImage, stageDeviceMemory, initialResources, cmdBuffer, stageImageCreateInfo, VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresourceRange, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
            {
                logPrint(VKTS_LOG_ERROR, "MemoryImage: Could not prepare staging image.");

                return IMemoryImageSP();
            }

            for (uint32_t i = 0; i < imageData->getMipLevels(); i++)
            {
                VkImageSubresource imageSubresource;
                imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
                imageSubresource.mipLevel = i;
                imageSubresource.arrayLayer = 0;

                VkSubresourceLayout subresourceLayout;

                stageImage->getImageSubresourceLayout(subresourceLayout, imageSubresource);

                if (!memoryImageUpload(stageDeviceMemory, imageData, i, subresourceLayout))
                {
                    logPrint(VKTS_LOG_ERROR, "MemoryImage: Could not upload image data.");

                    return IMemoryImageSP();
                }

                VkImageCopy imageCopy;

                imageCopy.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, i, 0, 1};
                imageCopy.srcOffset = {0, 0, 0};
                imageCopy.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, i, 0, 1};
                imageCopy.dstOffset = {0, 0, 0};
                imageCopy.extent = {glm::max(imageData->getWidth() >> i, 1u), glm::max(imageData->getHeight() >> i, 1u), glm::max(imageData->getDepth() >> i, 1u)};

                stageImage->copyImage(cmdBuffer->getCommandBuffer(), image, imageCopy);
            }
        }
Exemplo n.º 7
0
SmartPointerVector<IImageDataSP> VKTS_APIENTRY imageDataMipmap(const IImageDataSP& sourceImage, VkBool32 addSourceAsCopy, const std::string& name)
{
    if (name.size() == 0 || !sourceImage.get())
    {
        return SmartPointerVector<IImageDataSP>();
    }

    std::string sourceImageFilename = name;

    auto dotIndex = sourceImageFilename.rfind(".");

    if (dotIndex == sourceImageFilename.npos)
    {
        return SmartPointerVector<IImageDataSP>();
    }

    auto sourceImageName = sourceImageFilename.substr(0, dotIndex);
    auto sourceImageExtension = sourceImageFilename.substr(dotIndex);

    IImageDataSP currentSourceImage = sourceImage;
    int32_t width = currentSourceImage->getWidth();
    int32_t height = currentSourceImage->getHeight();
    int32_t depth = currentSourceImage->getDepth();

    IImageDataSP currentTargetImage;
    std::string targetImageFilename;

    int32_t level = 0;

    SmartPointerVector<IImageDataSP> result;

    if (addSourceAsCopy)
    {
        targetImageFilename = sourceImageName + "_L" + std::to_string(level++) + sourceImageExtension;

        currentTargetImage = imageDataCopy(sourceImage, targetImageFilename);

        if (!currentTargetImage.get())
        {
            return SmartPointerVector<IImageDataSP>();
        }

        result.append(currentTargetImage);
    }
    else
    {
        result.append(sourceImage);

        level++;
    }

    while (width > 1 || height > 1 || depth > 1)
    {
        width = glm::max(width / 2, 1);
        height = glm::max(height / 2, 1);
        depth = glm::max(depth / 2, 1);

        targetImageFilename = sourceImageName + "_L" + std::to_string(level++) + sourceImageExtension;

        currentTargetImage = imageDataCreate(targetImageFilename, width, height, depth, 0.0f, 0.0f, 0.0f, 0.0f, sourceImage->getImageType(), sourceImage->getFormat());

        if (!currentTargetImage.get())
        {
            return SmartPointerVector<IImageDataSP>();
        }

        for (int32_t z = 0; z < depth; z++)
        {
            for (int32_t y = 0; y < height; y++)
            {
                for (int32_t x = 0; x < width; x++)
                {
                    glm::vec4 rgba = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
                    float sampleCount = 0.0f;

                    for (int32_t iz = z * 2; iz < z * 2 + 1; iz++)
                    {
                        for (int32_t iy = y * 2; iy < y * 2 + 1; iy++)
                        {
                            for (int32_t ix = x * 2; ix < x * 2 + 1; ix++)
                            {
                                rgba += currentSourceImage->getTexel(ix, iy, iz);

                                sampleCount += 1.0f;
                            }
                        }
                    }

                    if (sampleCount > 0.0f)
                    {
                        rgba /= sampleCount;

                        currentTargetImage->setTexel(rgba, x, y, z);
                    }
                }
            }
        }

        result.append(currentTargetImage);

        //

        currentSourceImage = currentTargetImage;
        width = currentSourceImage->getWidth();
        height = currentSourceImage->getHeight();
        depth = currentSourceImage->getDepth();
    }

    return result;
}
Exemplo n.º 8
0
FontCacheEntry* FreeTypeFont::getGlyph(const char32_t character, const size_t size)
{
    if (!face)
    {
        return nullptr;
    }

    //

    auto results = cache.find(character);

    while (results != cache.cend())
    {
        if (results->second.size == size)
        {
            return &results->second;
        }

        results++;
    }

    //

    if (FT_Set_Char_Size(face, VKTS_TO_CHAR_SIZE(size), VKTS_TO_CHAR_SIZE(size), 0, 0))
    {
        return nullptr;
    }

    auto glyphIndex = FT_Get_Char_Index(face, character);

    if (FT_Load_Glyph(face, glyphIndex, FT_LOAD_DEFAULT))
    {
        return nullptr;
    }

    if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL))
    {
        return nullptr;
    }

    //

    IImageDataSP glyphImageData;

    if (face->glyph->bitmap.buffer)
    {
    	glyphImageData = imageDataCreate("FontCharacterImageData", face->glyph->bitmap.width, face->glyph->bitmap.rows, 1, VK_IMAGE_TYPE_2D, VK_FORMAT_R8_UNORM);


        if (!glyphImageData.get())
        {
            return nullptr;
        }


        VkSubresourceLayout subresourceLayout;

        subresourceLayout.offset = 0;
        subresourceLayout.size = face->glyph->bitmap.width * face->glyph->bitmap.rows;
        subresourceLayout.rowPitch = face->glyph->bitmap.width;
        subresourceLayout.arrayPitch = 0;
        subresourceLayout.depthPitch = 0;

        if (!glyphImageData->upload(face->glyph->bitmap.buffer, 0, subresourceLayout))
        {
        	return nullptr;
        }
    }
    else
    {
        // For space, no data is created.

    	glyphImageData = imageDataCreate("FontCharacterImageData", 1, 1, 1, 0.0f, 0.0f, 0.0f, 0.0f, VK_IMAGE_TYPE_2D, VK_FORMAT_R8_UNORM);

        if (!glyphImageData.get())
        {
            return nullptr;
        }
    }

    //

    FontCacheEntry fontCacheEntry;

    fontCacheEntry.character = character;
    fontCacheEntry.size = size;

    fontCacheEntry.width = face->glyph->bitmap.width;
    fontCacheEntry.height = face->glyph->bitmap.rows;

    fontCacheEntry.advanceX = VKTS_FROM_CHAR_SIZE(face->glyph->advance.x);
    fontCacheEntry.advanceY = VKTS_FROM_CHAR_SIZE(face->glyph->advance.y);
    fontCacheEntry.offsetX = VKTS_FROM_CHAR_SIZE(face->glyph->metrics.vertBearingX - face->glyph->metrics.width);
    fontCacheEntry.offsetY = VKTS_FROM_CHAR_SIZE(face->glyph->metrics.horiBearingY - face->glyph->metrics.height);

    fontCacheEntry.glyphImageData = glyphImageData;

    fontCacheEntry.texture = ITextureSP();

    cache.insert(std::make_pair(character, fontCacheEntry));

    //

    results = cache.find(character);

    while (results != cache.cend())
    {
        if (results->second.size == size)
        {
            return &results->second;
        }

        results++;
    }

    return nullptr;
}