Changeset 4a777d2 in opengl-game for sdl-game.cpp


Ignore:
Timestamp:
Apr 11, 2021, 12:09:58 AM (3 years ago)
Author:
Dmitry Portnoy <dportnoy@…>
Branches:
feature/imgui-sdl
Children:
cb6fabb, e8445f0
Parents:
b8efa56
git-author:
Dmitry Portnoy <dportnoy@…> (04/11/21 00:09:49)
git-committer:
Dmitry Portnoy <dportnoy@…> (04/11/21 00:09:58)
Message:

Add the model pipeline and the spinning, textured squares to SDLGame

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sdl-game.cpp

    rb8efa56 r4a777d2  
    88
    99#include "logger.hpp"
     10#include "utils.hpp"
    1011
    1112#include "gui/imgui/button-imgui.hpp"
     
    8990   initImGuiOverlay();
    9091
     92   // TODO: Figure out how much of ubo creation and associated variables should be in the pipeline class
     93   // Maybe combine the ubo-related objects into a new class
     94
     95   initGraphicsPipelines();
     96
     97   initMatrices();
     98
     99   modelPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ModelVertex::pos));
     100   modelPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ModelVertex::color));
     101   modelPipeline.addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&ModelVertex::texCoord));
     102   modelPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ModelVertex::normal));
     103   modelPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex));
     104
     105   createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     106      uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline);
     107
     108   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
     109      VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_modelPipeline);
     110   modelPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
     111   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
     112      VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor);
     113
     114   SceneObject<ModelVertex, SSBO_ModelObject>* texturedSquare = nullptr;
     115
     116   texturedSquare = &addObject(modelObjects, modelPipeline,
     117      addObjectIndex<ModelVertex>(modelObjects.size(),
     118         addVertexNormals<ModelVertex>({
     119            {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f, 0.0f}, 0},
     120            {{ 0.5f, -0.5f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}, 0},
     121            {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0},
     122            {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0},
     123            {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0},
     124            {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f, 0.0f}, 0}
     125         })), {
     126            0, 1, 2, 3, 4, 5
     127      }, {
     128         mat4(1.0f)
     129      }, false);
     130
     131   texturedSquare->model_base =
     132      translate(mat4(1.0f), vec3(0.0f, 0.0f, -2.0f));
     133   texturedSquare->modified = true;
     134
     135   texturedSquare = &addObject(modelObjects, modelPipeline,
     136      addObjectIndex<ModelVertex>(modelObjects.size(),
     137         addVertexNormals<ModelVertex>({
     138            {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
     139            {{ 0.5f, -0.5f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
     140            {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
     141            {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
     142            {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
     143            {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}}
     144         })), {
     145            0, 1, 2, 3, 4, 5
     146      }, {
     147         mat4(1.0f)
     148      }, false);
     149
     150   texturedSquare->model_base =
     151      translate(mat4(1.0f), vec3(0.0f, 0.0f, -1.5f));
     152   texturedSquare->modified = true;
     153
     154   modelPipeline.createDescriptorSetLayout();
     155   modelPipeline.createPipeline("shaders/model-vert.spv", "shaders/model-frag.spv");
     156   modelPipeline.createDescriptorPool(swapChainImages);
     157   modelPipeline.createDescriptorSets(swapChainImages);
     158
    91159   currentRenderScreenFn = &VulkanGame::renderMainScreen;
    92160
     
    182250   createCommandBuffers();
    183251   createSyncObjects();
     252}
     253
     254void VulkanGame::initGraphicsPipelines() {
     255   modelPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject>(
     256      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
     257      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 16, 24, 10);
     258}
     259
     260// TODO: Maybe change the name to initScene() or something similar
     261void VulkanGame::initMatrices() {
     262   cam_pos = vec3(0.0f, 0.0f, 2.0f);
     263
     264   float cam_yaw = 0.0f;
     265   float cam_pitch = -50.0f;
     266
     267   mat4 yaw_mat = rotate(mat4(1.0f), radians(-cam_yaw), vec3(0.0f, 1.0f, 0.0f));
     268   mat4 pitch_mat = rotate(mat4(1.0f), radians(-cam_pitch), vec3(1.0f, 0.0f, 0.0f));
     269
     270   mat4 R_view = pitch_mat * yaw_mat;
     271   mat4 T_view = translate(mat4(1.0f), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
     272   viewMat = R_view * T_view;
     273
     274   projMat = perspective(radians(FOV_ANGLE), (float)swapChainExtent.width / (float)swapChainExtent.height, NEAR_CLIP, FAR_CLIP);
     275   projMat[1][1] *= -1; // flip the y-axis so that +y is up
     276
     277   object_VP_mats.view = viewMat;
     278   object_VP_mats.proj = projMat;
    184279}
    185280
     
    241336               cout << "Window resize event detected" << endl;
    242337               shouldRecreateSwapChain = true;
     338               break;
     339            case UI_EVENT_KEYDOWN:
     340               if (e.key.repeat) {
     341                  break;
     342               }
     343
     344               if (e.key.keycode == SDL_SCANCODE_ESCAPE) {
     345                  done = true;
     346               } else if (e.key.keycode == SDL_SCANCODE_SPACE) {
     347                  cout << "Adding a plane" << endl;
     348                  float zOffset = -2.0f + (0.5f * modelObjects.size());
     349
     350                  SceneObject<ModelVertex, SSBO_ModelObject>& texturedSquare =
     351                     addObject(modelObjects, modelPipeline,
     352                        addObjectIndex<ModelVertex>(modelObjects.size(),
     353                           addVertexNormals<ModelVertex>({
     354                              {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f, 0.0f}, 0},
     355                              {{ 0.5f, -0.5f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f, 0.0f}, 0},
     356                              {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0},
     357                              {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0},
     358                              {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0},
     359                              {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f, 0.0f}, 0}
     360                           })), {
     361                              0, 1, 2, 3, 4, 5
     362                        }, {
     363                           mat4(1.0f)
     364                        }, true);
     365
     366                  texturedSquare.model_base =
     367                     translate(mat4(1.0f), vec3(0.0f, 0.0f, zOffset));
     368                  texturedSquare.modified = true;
     369               // START UNREVIEWED SECTION
     370               // END UNREVIEWED SECTION
     371               } else {
     372                  cout << "Key event detected" << endl;
     373               }
    243374               break;
    244375            case UI_EVENT_KEYUP:
     
    277408      }
    278409
     410      updateScene();
     411
    279412      // TODO: Move this into a renderImGuiOverlay() function
    280413      ImGui_ImplVulkan_NewFrame();
     
    296429}
    297430
     431// TODO: The only updates that need to happen once per Vulkan image are the SSBO ones,
     432// which are already handled by updateObject(). Move this code to a different place,
     433// where it will run just once per frame
     434void VulkanGame::updateScene() {
     435   for (SceneObject<ModelVertex, SSBO_ModelObject>& model : this->modelObjects) {
     436      model.model_transform =
     437         translate(mat4(1.0f), vec3(0.0f, -2.0f, -0.0f)) *
     438         rotate(mat4(1.0f), curTime * radians(90.0f), vec3(0.0f, 0.0f, 1.0f));
     439      model.modified = true;
     440   }
     441
     442   for (size_t i = 0; i < modelObjects.size(); i++) {
     443      if (modelObjects[i].modified) {
     444         updateObject(modelObjects, modelPipeline, i);
     445      }
     446   }
     447
     448   VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_modelPipeline[imageIndex], 0, object_VP_mats);
     449}
     450
    298451void VulkanGame::cleanup() {
    299452   // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals)
     
    304457
    305458   cleanupSwapChain();
     459
     460   VulkanUtils::destroyVulkanImage(device, floorTextureImage);
     461   // START UNREVIEWED SECTION
     462
     463   vkDestroySampler(device, textureSampler, nullptr);
     464
     465   modelPipeline.cleanupBuffers();
     466
     467   // END UNREVIEWED SECTION
    306468
    307469   vkDestroyCommandPool(device, resourceCommandPool, nullptr);
     
    638800   VulkanUtils::createDepthImage(device, physicalDevice, resourceCommandPool, findDepthFormat(), swapChainExtent,
    639801      depthImage, graphicsQueue);
     802
     803   createTextureSampler();
     804
     805   // TODO: Move all images/textures somewhere into the assets folder
     806
     807   VulkanUtils::createVulkanImageFromFile(device, physicalDevice, resourceCommandPool, "textures/texture.jpg",
     808      floorTextureImage, graphicsQueue);
     809
     810   floorTextureImageDescriptor = {};
     811   floorTextureImageDescriptor.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
     812   floorTextureImageDescriptor.imageView = floorTextureImage.imageView;
     813   floorTextureImageDescriptor.sampler = textureSampler;
    640814}
    641815
     
    726900      }
    727901   }
     902}
     903
     904void VulkanGame::createTextureSampler() {
     905   VkSamplerCreateInfo samplerInfo = {};
     906   samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
     907   samplerInfo.magFilter = VK_FILTER_LINEAR;
     908   samplerInfo.minFilter = VK_FILTER_LINEAR;
     909
     910   samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
     911   samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
     912   samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
     913
     914   samplerInfo.anisotropyEnable = VK_TRUE;
     915   samplerInfo.maxAnisotropy = 16;
     916   samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
     917   samplerInfo.unnormalizedCoordinates = VK_FALSE;
     918   samplerInfo.compareEnable = VK_FALSE;
     919   samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
     920   samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
     921   samplerInfo.mipLodBias = 0.0f;
     922   samplerInfo.minLod = 0.0f;
     923   samplerInfo.maxLod = 0.0f;
     924
     925   VKUTIL_CHECK_RESULT(vkCreateSampler(device, &samplerInfo, nullptr, &textureSampler),
     926      "failed to create texture sampler!");
    728927}
    729928
     
    8811080}
    8821081
     1082void VulkanGame::createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags,
     1083                                 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
     1084                                 vector<VkDescriptorBufferInfo>& bufferInfoList) {
     1085   buffers.resize(swapChainImageCount);
     1086   buffersMemory.resize(swapChainImageCount);
     1087   bufferInfoList.resize(swapChainImageCount);
     1088
     1089   for (size_t i = 0; i < swapChainImageCount; i++) {
     1090      VulkanUtils::createBuffer(device, physicalDevice, bufferSize, flags,
     1091         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
     1092         buffers[i], buffersMemory[i]);
     1093
     1094      bufferInfoList[i].buffer = buffers[i];
     1095      bufferInfoList[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now
     1096      bufferInfoList[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE
     1097   }
     1098}
     1099
    8831100void VulkanGame::renderFrame(ImDrawData* draw_data) {
    8841101   VkResult result = vkAcquireNextImageKHR(device, swapChain, numeric_limits<uint64_t>::max(),
     
    9261143
    9271144   vkCmdBeginRenderPass(commandBuffers[imageIndex], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
     1145
     1146   // TODO: Find a more elegant, per-screen solution for this
     1147   if (currentRenderScreenFn == &VulkanGame::renderGameScreen) {
     1148      modelPipeline.createRenderCommands(commandBuffers[imageIndex], imageIndex);
     1149
     1150
     1151
     1152
     1153   }
    9281154
    9291155   ImGui_ImplVulkan_RenderDrawData(draw_data, commandBuffers[imageIndex]);
     
    9991225   createSyncObjects();
    10001226
    1001    // TODO: Update pipelines here
     1227   // TODO: Move UBO creation/management into GraphicsPipeline_Vulkan, like I did with SSBOs
     1228   // TODO: Check if the shader stages and maybe some other properties of the pipeline can be re-used
     1229   // instead of recreated every time
     1230
     1231   createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     1232      uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline);
     1233
     1234   modelPipeline.updateRenderPass(renderPass);
     1235   modelPipeline.createPipeline("shaders/model-vert.spv", "shaders/model-frag.spv");
     1236   modelPipeline.createDescriptorPool(swapChainImages);
     1237   modelPipeline.createDescriptorSets(swapChainImages);
    10021238
    10031239   imageIndex = 0;
     
    10141250      vkFreeCommandBuffers(device, commandPools[i], 1, &commandBuffers[i]);
    10151251      vkDestroyCommandPool(device, commandPools[i], nullptr);
     1252   }
     1253
     1254   modelPipeline.cleanup();
     1255
     1256   for (size_t i = 0; i < uniformBuffers_modelPipeline.size(); i++) {
     1257      vkDestroyBuffer(device, uniformBuffers_modelPipeline[i], nullptr);
     1258      vkFreeMemory(device, uniformBuffersMemory_modelPipeline[i], nullptr);
    10161259   }
    10171260
Note: See TracChangeset for help on using the changeset viewer.