Changeset e1a7f5a in opengl-game for vulkan-game.cpp


Ignore:
Timestamp:
Aug 16, 2019, 3:47:01 PM (5 years ago)
Author:
Dmitry Portnoy <dmitry.portnoy@…>
Branches:
feature/imgui-sdl, master, points-test
Children:
5936c58
Parents:
5f3dba8
Message:

Copy an SDL Texture to a Vulkan texture to use as a UI overlay on the 3D scene

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vulkan-game.cpp

    r5f3dba8 re1a7f5a  
    3232using namespace std;
    3333
     34// TODO: Maybe add asserts for testing
     35
    3436const int SCREEN_WIDTH = 800;
    3537const int SCREEN_HEIGHT = 600;
     
    182184      VkSurfaceKHR surface;
    183185
    184       // TODO: It seems that I can call all the same draw functions on an SDL_Renderer that I can
    185       // on an SDL_Surface, so I should use gRenderer (probably after renaming it) instead of getting
    186       // sdlSurface from the created window
    187       SDL_Surface* sdlSurface = nullptr;
    188 
    189186      VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
    190187      VkDevice device;
     
    221218      VkImageView overlayImageView;
    222219
     220      VkImage sdlOverlayImage;
     221      VkDeviceMemory sdlOverlayImageMemory;
     222      VkImageView sdlOverlayImageView;
     223
    223224      VkSampler textureSampler;
    224225
     
    268269         }
    269270
    270          uiOverlay = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT);
     271         uiOverlay = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT);
    271272         if (uiOverlay == nullptr) {
    272273            cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << endl;
     
    333334         createFramebuffers();
    334335         createImageResources("textures/texture.jpg", textureImage, textureImageMemory, textureImageView);
    335          createImageResources("textures/space.jpg", overlayImage, overlayImageMemory, overlayImageView);
     336         createImageResourcesFromSDLTexture(uiOverlay, sdlOverlayImage, sdlOverlayImageMemory, sdlOverlayImageView);
    336337         createTextureSampler();
    337338         createVertexBuffer();
     
    444445
    445446      void createSurface() {
    446          sdlSurface = SDL_GetWindowSurface(window);
    447 
    448          if (sdlSurface == nullptr) {
    449             cout << "Could not get SDL Surface! =(" << endl;
    450          }
    451 
    452447         if (gui->CreateVulkanSurface(instance, &surface) == RTWO_ERROR) {
    453448            throw runtime_error("failed to create window surface!");
     
    10871082      }
    10881083
     1084      void createImageResourcesFromSDLTexture(SDL_Texture* texture, VkImage& image, VkDeviceMemory& imageMemory, VkImageView& view) {
     1085         int a, w, h;
     1086
     1087         // I only need this here for the width and height, which are constants, so just use those instead
     1088         SDL_QueryTexture(texture, nullptr, &a, &w, &h);
     1089         //cout << "TEXTURE INFO" << endl;
     1090         //cout << "w: " << w << endl;
     1091         //cout << "h: " << h << endl;
     1092
     1093         createImage(w, h, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL,
     1094            VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
     1095            VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, image, imageMemory);
     1096
     1097         view = createImageView(image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT);
     1098      }
     1099
     1100      void populateImageFromSDLTexture(SDL_Texture* texture, VkImage& image) {
     1101         int a, w, h, pitch;
     1102
     1103         SDL_QueryTexture(texture, nullptr, &a, &w, &h);
     1104
     1105         VkDeviceSize imageSize = w * h * 4;
     1106         unsigned char* pixels = new unsigned char[imageSize];
     1107
     1108         SDL_RenderReadPixels(gRenderer, nullptr, SDL_PIXELFORMAT_ABGR8888, pixels, w * 4);
     1109
     1110         VkBuffer stagingBuffer;
     1111         VkDeviceMemory stagingBufferMemory;
     1112
     1113         createBuffer(imageSize,
     1114            VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
     1115            VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
     1116            stagingBuffer, stagingBufferMemory);
     1117
     1118         void* data;
     1119
     1120         vkMapMemory(device, stagingBufferMemory, 0, VK_WHOLE_SIZE, 0, &data);
     1121         memcpy(data, pixels, static_cast<size_t>(imageSize));
     1122
     1123         VkMappedMemoryRange mappedMemoryRange = {};
     1124         mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
     1125         mappedMemoryRange.memory = stagingBufferMemory;
     1126         mappedMemoryRange.offset = 0;
     1127         mappedMemoryRange.size = VK_WHOLE_SIZE;
     1128
     1129         // TODO: Should probably check that the function succeeded
     1130         vkFlushMappedMemoryRanges(device, 1, &mappedMemoryRange);
     1131
     1132         vkUnmapMemory(device, stagingBufferMemory);
     1133
     1134         transitionImageLayout(image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
     1135         copyBufferToImage(stagingBuffer, image, static_cast<uint32_t>(w), static_cast<uint32_t>(h));
     1136         transitionImageLayout(image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
     1137
     1138         vkDestroyBuffer(device, stagingBuffer, nullptr);
     1139         vkFreeMemory(device, stagingBufferMemory, nullptr);
     1140      }
     1141
    10891142      void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage,
    10901143            VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory) {
     
    14521505            VkDescriptorImageInfo overlayImageInfo = {};
    14531506            overlayImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
    1454             overlayImageInfo.imageView = overlayImageView;
     1507            overlayImageInfo.imageView = sdlOverlayImageView;
    14551508            overlayImageInfo.sampler = textureSampler;
    14561509
     
    15951648            }
    15961649
    1597             //drawFrame();
    1598 
    15991650            drawUI();
     1651
     1652            drawFrame();
    16001653         }
    16011654
     
    16671720      }
    16681721
    1669       /* NOTES:
    1670        *
    1671        * SDL can already render rects and lines. Rendering circles would be nice, but I can implement it myself
    1672        * and wouldn't use it that often anyway
    1673        */
    16741722      void drawUI() {
    1675          SDL_SetRenderTarget(gRenderer, nullptr);
     1723         // TODO: Since I currently don't use any other render targets,
     1724         // I may as well set this once before the render loop
     1725         SDL_SetRenderTarget(gRenderer, uiOverlay);
    16761726
    16771727         SDL_SetRenderDrawColor(gRenderer, 0x00, 0x9F, 0x9F, 0xFF);
    1678                         SDL_RenderClear(gRenderer);
    1679 
    1680          SDL_SetRenderTarget(gRenderer, uiOverlay);
    1681 
    1682          SDL_SetRenderDrawColor(gRenderer, 0x00, 0x00, 0x00, 0x00);
    16831728         SDL_RenderClear(gRenderer);
    16841729
     
    17011746         SDL_RenderDrawLine(gRenderer, 50, 5, 150, 500);
    17021747
    1703          SDL_SetRenderTarget(gRenderer, nullptr);
    1704 
    1705          SDL_RenderCopy(gRenderer, uiOverlay, nullptr, nullptr);
    1706 
    1707          SDL_RenderPresent(gRenderer);
     1748         populateImageFromSDLTexture(uiOverlay, sdlOverlayImage);
    17081749      }
    17091750
     
    17661807         vkFreeMemory(device, overlayImageMemory, nullptr);
    17671808
     1809         vkDestroyImageView(device, sdlOverlayImageView, nullptr);
     1810         vkDestroyImage(device, sdlOverlayImage, nullptr);
     1811         vkFreeMemory(device, sdlOverlayImageMemory, nullptr);
     1812
    17681813         vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
    17691814
Note: See TracChangeset for help on using the changeset viewer.