Changeset 4a9416a in opengl-game


Ignore:
Timestamp:
Apr 26, 2020, 9:50:00 PM (4 years ago)
Author:
Dmitry Portnoy <dmitry.portnoy@…>
Branches:
feature/imgui-sdl, master
Children:
b8d4456
Parents:
52a02e6
git-author:
Dmitry Portnoy <dmitry.portnoy@…> (04/26/20 19:00:18)
git-committer:
Dmitry Portnoy <dmitry.portnoy@…> (04/26/20 21:50:00)
Message:

Create a pipeline and shaders to render explosions

Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • new-game.cpp

    r52a02e6 r4a9416a  
    4747};
    4848
     49/*** START OF REFACTORED CODE ***/
    4950enum ObjectType {
    5051   TYPE_SHIP,
     
    6768   UNIFORM_3F,
    6869};
     70/*** END OF REFACTORED CODE ***/
    6971
    7072enum UIValueType {
     
    7375};
    7476
     77/*** START OF REFACTORED CODE ***/
    7578struct SceneObject {
    7679   unsigned int id;
     
    153156   unsigned int vboCapacity;
    154157};
     158/*** END OF REFACTORED CODE ***/
    155159
    156160struct UIValue {
     
    193197                  map<ObjectType, ShaderModelGroup>& modelGroups,
    194198                  GLuint ubo);
    195 /*** END OF REFACTORED CODE ***/
    196199void removeObjectFromScene(SceneObject& obj, GLuint ubo);
    197200
     
    200203void addModelToGroup(ShaderModelGroup& modelGroup, SceneObject& model);
    201204
    202 /*** START OF REFACTORED CODE ***/
    203205void defineModelGroupAttrib(ShaderModelGroup& modelGroup, string name, AttribType attribType, GLint size, GLenum type, size_t fieldOffset);
    204206void defineModelGroupUniform(ShaderModelGroup& modelGroup, string name, AttribType attribType, GLint size, UniformType type, GLfloat* data);
     
    206208void bindUniformData(AttribInfo& attrib);
    207209void bindUniformData(AttribInfo& attrib, GLfloat* data);
    208 /*** END OF REFACTORED CODE ***/
    209210
    210211size_t GLsizeof(GLenum);
     
    214215void calculateObjectBoundingBox(SceneObject* obj);
    215216
    216 /*** START OF REFACTORED CODE ***/
    217217void populateBuffers(vector<SceneObject*>& objects,
    218218                  map<GLuint, BufferInfo>& shaderBufferInfo,
     
    231231Asteroid* createAsteroid(vec3 pos);
    232232Laser* createLaser(vec3 start, vec3 end, vec3 color, GLfloat width);
    233 /*** END OF REFACTORED CODE ***/
    234233ParticleEffect* createExplosion(mat4 model_mat);
    235234
    236 /*** START OF REFACTORED CODE ***/
    237235void translateLaser(Laser* laser, const vec3& translation, GLuint ubo);
    238236void updateLaserTarget(Laser* laser, vector<SceneObject*>& objects, ShaderModelGroup& laserSmg, GLuint asteroid_sp);
     
    254252
    255253const int KEY_STATE_UNCHANGED = -1;
     254/*** START OF REFACTORED CODE ***/
    256255const bool FULLSCREEN = false;
    257256const int EXPLOSION_PARTICLE_COUNT = 300;
    258257unsigned int MAX_UNIFORMS = 0; // Requires OpenGL constants only available at runtime, so it can't be const
     258/*** END OF REFACTORED CODE ***/
    259259
    260260int key_state[NUM_KEYS];
     
    381381      cout << "OpenGL debug message callback is not supported" << endl;
    382382   }
    383 /*** END OF REFACTORED CODE ***/
    384383
    385384   srand(time(0));
     
    409408   cout << "MAX_UNIFORMS: " << MAX_UNIFORMS << endl;
    410409
    411 /*** START OF REFACTORED CODE ***/
    412410   // Setup Dear ImGui binding
    413411   IMGUI_CHECKVERSION();
     
    489487    */
    490488
     489/*** START OF REFACTORED CODE ***/
    491490   GLfloat laserColor[3] = {0.2f, 1.0f, 0.2f};
    492491   GLfloat curTime, prevTime, elapsedTime;
     
    498497   map<ObjectType, ShaderModelGroup> modelGroups;
    499498
    500 /*** START OF REFACTORED CODE ***/
    501499   modelGroups[TYPE_SHIP] = createModelGroup(
    502500      loadShaderProgram("gl-shaders/ship.vert", "gl-shaders/ship.frag"));
     
    558556
    559557   initModelGroupAttribs(modelGroups[TYPE_LASER]);
    560 /*** END OF REFACTORED CODE ***/
    561558
    562559   modelGroups[TYPE_EXPLOSION] = createModelGroup(
     
    580577   initModelGroupAttribs(modelGroups[TYPE_EXPLOSION]);
    581578
    582 /*** START OF REFACTORED CODE ***/
    583579   cam_pos = vec3(0.0f, 0.0f, 2.0f);
    584580   float cam_yaw = 0.0f * 2.0f * 3.14159f / 360.0f;
     
    666662
    667663   GLuint laser_sp_models_ub_index = glGetUniformBlockIndex(modelGroups[TYPE_LASER].shaderProgram, "models");
    668 /*** END OF REFACTORED CODE ***/
    669664
    670665   GLuint explosion_sp_models_ub_index = glGetUniformBlockIndex(modelGroups[TYPE_EXPLOSION].shaderProgram, "models");
    671666
    672667
    673 /*** START OF REFACTORED CODE ***/
    674668   glUseProgram(modelGroups[TYPE_SHIP].shaderProgram);
    675669   bindUniformData(modelGroups[TYPE_SHIP].attribs["view"]);
     
    698692   glUniformBlockBinding(modelGroups[TYPE_LASER].shaderProgram, laser_sp_models_ub_index, ub_binding_point);
    699693   glBindBufferRange(GL_UNIFORM_BUFFER, ub_binding_point, ubo, 0, GL_MAX_UNIFORM_BLOCK_SIZE);
    700 /*** END OF REFACTORED CODE ***/
    701694
    702695
     
    707700   glUniformBlockBinding(modelGroups[TYPE_EXPLOSION].shaderProgram, explosion_sp_models_ub_index, ub_binding_point);
    708701   glBindBufferRange(GL_UNIFORM_BUFFER, ub_binding_point, ubo, 0, GL_MAX_UNIFORM_BLOCK_SIZE);
     702/*** END OF REFACTORED CODE ***/
    709703
    710704
     
    881875                     score++;
    882876
     877/*** START OF REFACTORED CODE ***/
    883878                     addObjectToScene(createExplosion(model_mat), shaderBufferInfo, modelGroups, ubo);
    884879                  }
     
    889884                  }
    890885               }
    891 /*** START OF REFACTORED CODE ***/
    892886            }
    893887         }
     
    977971         cam_moved = false;
    978972      }
    979 /*** END OF REFACTORED CODE ***/
    980973
    981974      glUseProgram(modelGroups[TYPE_EXPLOSION].shaderProgram);
    982975      bindUniformData(modelGroups[TYPE_EXPLOSION].attribs["cur_time"]);
    983976
    984 /*** START OF REFACTORED CODE ***/
    985977      // Render scene
    986978
     
    12001192
    12011193
     1194/*** START OF REFACTORED CODE ***/
    12021195GLuint loadShader(GLenum type, string file) {
    12031196  cout << "Loading shader from file " << file << endl;
     
    12791272  return image_data;
    12801273}
     1274/*** END OF REFACTORED CODE ***/
    12811275
    12821276bool faceClicked(array<vec3, 3> points, SceneObject* obj, vec4 world_ray, vec4 cam, vec4& click_point) {
     
    13241318}
    13251319
     1320/*** START OF REFACTORED CODE ***/
    13261321// TODO: Pass a reference, not a pointer
    13271322void initObject(SceneObject* obj) {
     
    14461441}
    14471442
    1448 /*** START OF REFACTORED CODE ***/
    14491443SceneObject* createShip() {
    14501444   SceneObject* ship = new SceneObject();
     
    19171911   return obj;
    19181912}
    1919 /*** END OF REFACTORED CODE ***/
    19201913
    19211914ShaderModelGroup createModelGroup(GLuint shaderProgram) {
     
    19421935}
    19431936
    1944 /*** START OF REFACTORED CODE ***/
    19451937void defineModelGroupAttrib(ShaderModelGroup& modelGroup, string name, AttribType attribType,
    19461938                  GLint size, GLenum type, size_t fieldOffset) {
     
    20312023   }
    20322024}
    2033 /*** END OF REFACTORED CODE ***/
    20342025
    20352026/* The purpose of this function is to replace the use of sizeof() when calling
     
    24032394   glDisable(GL_BLEND);
    24042395}
     2396/*** END OF REFACTORED CODE ***/
    24052397
    24062398void renderSceneGui(map<string, vector<UIValue>> valueLists) {
     
    26712663   return obj;
    26722664}
    2673 /*** END OF REFACTORED CODE ***/
    26742665
    26752666// TODO: Maybe pass in startTime instead of calling glfwGetTime() here
     
    27032694   return obj;
    27042695}
     2696/*** END OF REFACTORED CODE ***/
  • vulkan-game.cpp

    r52a02e6 r4a9416a  
    33#include <array>
    44#include <iostream>
     5#include <numeric>
    56#include <set>
    67
     
    2829   this->asteroid_VP_mats = {};
    2930   this->laser_VP_mats = {};
     31   this->explosion_UBO = {};
    3032}
    3133
     
    564566   laserPipeline.createDescriptorSets(swapChainImages);
    565567
     568   explosionPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ExplosionVertex::particleStartVelocity));
     569   explosionPipeline.addAttribute(VK_FORMAT_R32_SFLOAT, offset_of(&ExplosionVertex::particleStartTime));
     570   explosionPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ExplosionVertex::objIndex));
     571
     572   createBufferSet(sizeof(UBO_Explosion), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     573      uniformBuffers_explosionPipeline, uniformBuffersMemory_explosionPipeline, uniformBufferInfoList_explosionPipeline);
     574
     575   explosionPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
     576      VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_explosionPipeline);
     577   explosionPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
     578
     579   explosionPipeline.createDescriptorSetLayout();
     580   explosionPipeline.createPipeline("shaders/explosion-vert.spv", "shaders/explosion-frag.spv");
     581   explosionPipeline.createDescriptorPool(swapChainImages);
     582   explosionPipeline.createDescriptorSets(swapChainImages);
     583
    566584   cout << "Created all the graphics pipelines" << endl;
    567585
     
    591609      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
    592610      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 8, 18, 2);
     611
     612   explosionPipeline = GraphicsPipeline_Vulkan<ExplosionVertex, SSBO_Explosion>(
     613      VK_PRIMITIVE_TOPOLOGY_POINT_LIST, physicalDevice, device, renderPass,
     614      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height },
     615      swapChainImages, EXPLOSION_PARTICLE_COUNT, EXPLOSION_PARTICLE_COUNT, 2);
    593616}
    594617
     
    621644   laser_VP_mats.view = viewMat;
    622645   laser_VP_mats.proj = projMat;
     646
     647   explosion_UBO.view = viewMat;
     648   explosion_UBO.proj = projMat;
    623649}
    624650
     
    691717                     vec3(-0.21f, -1.19f, 1.76f) + offset,
    692718                     vec3(-0.21f, -1.19f, -3.0f) + offset,
    693                      vec3(1.0f, 0.0f, 0.0f), 0.03f);
     719                     LASER_COLOR, 0.03f);
    694720
    695721                  leftLaserIdx = laserObjects.size() - 1;
     
    700726                     vec3(0.21f, -1.19f, 1.76f) + offset,
    701727                     vec3(0.21f, -1.19f, -3.0f) + offset,
    702                      vec3(0.0f, 1.0f, 0.0f), 0.03f);
     728                     LASER_COLOR, 0.03f);
    703729
    704730                  rightLaserIdx = laserObjects.size() - 1;
     
    818844         vec3 objCenter = vec3(viewMat * vec4(asteroid.center, 1.0f));
    819845
    820          if ((objCenter.z - asteroid.radius) > -NEAR_CLIP || asteroid.ssbo.hp <= 0.0f) {
     846         if (asteroid.ssbo.hp <= 0.0f) {
    821847            asteroid.ssbo.deleted = true;
    822848
    823             // TODO: Create explosion here
     849            // TODO: Optimize this so I don't recalculate the camera rotation every time
     850            // TODO: Also, avoid re-declaring cam_pitch
     851            float cam_pitch = -50.0f;
     852            mat4 pitch_mat = rotate(mat4(1.0f), radians(cam_pitch), vec3(1.0f, 0.0f, 0.0f));
     853            mat4 model_mat = translate(mat4(1.0f), asteroid.center) * pitch_mat;
     854
     855            addExplosion(model_mat, 0.5f, curTime);
     856
     857            // TODO: Increment player's score here
     858         } else if ((objCenter.z - asteroid.radius) > -NEAR_CLIP) {
     859            asteroid.ssbo.deleted = true;
    824860         } else {
    825861            asteroid.model_transform =
     
    914950   }
    915951
     952   for (SceneObject<ExplosionVertex, SSBO_Explosion>& explosion : this->explosionObjects) {
     953      if (!explosion.ssbo.deleted) {
     954         if (curTime > (explosion.ssbo.explosionStartTime + explosion.ssbo.explosionDuration)) {
     955            explosion.ssbo.deleted = true;
     956            explosion.modified = true;
     957         }
     958      }
     959   }
     960
    916961   for (size_t i = 0; i < shipObjects.size(); i++) {
    917962      if (shipObjects[i].modified) {
     
    938983   }
    939984
     985   for (size_t i = 0; i < explosionObjects.size(); i++) {
     986      if (explosionObjects[i].modified) {
     987         updateObject(explosionObjects, explosionPipeline, i);
     988      }
     989   }
     990
     991   explosion_UBO.cur_time = curTime;
     992
    940993   VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_modelPipeline[currentImage], 0, object_VP_mats);
    941994
     
    945998
    946999   VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_laserPipeline[currentImage], 0, laser_VP_mats);
     1000
     1001   VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_explosionPipeline[currentImage], 0, explosion_UBO);
    9471002}
    9481003
     
    10511106   asteroidPipeline.cleanupBuffers();
    10521107   laserPipeline.cleanupBuffers();
     1108   explosionPipeline.cleanupBuffers();
    10531109
    10541110   for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
     
    15431599      asteroidPipeline.createRenderCommands(commandBuffers[i], i);
    15441600      laserPipeline.createRenderCommands(commandBuffers[i], i);
     1601      explosionPipeline.createRenderCommands(commandBuffers[i], i);
    15451602
    15461603      // Always render this pipeline last
     
    17971854}
    17981855
     1856void VulkanGame::addExplosion(mat4 model_mat, float duration, float cur_time) {
     1857   vector<ExplosionVertex> vertices;
     1858   vertices.reserve(EXPLOSION_PARTICLE_COUNT);
     1859
     1860   float particle_start_time = 0.0f;
     1861
     1862   for (int i = 0; i < EXPLOSION_PARTICLE_COUNT; i++) {
     1863      float randx = ((float)rand() / (float)RAND_MAX) - 0.5f;
     1864      float randy = ((float)rand() / (float)RAND_MAX) - 0.5f;
     1865
     1866      vertices.push_back({ vec3(randx, randy, 0.0f), particle_start_time});
     1867
     1868      particle_start_time += .01f;
     1869      // TODO: Get this working
     1870      // particle_start_time += 1.0f * EXPLOSION_PARTICLE_COUNT / duration
     1871   }
     1872
     1873   // Fill the indices with the the first EXPLOSION_PARTICLE_COUNT ints
     1874   vector<uint16_t> indices(EXPLOSION_PARTICLE_COUNT);
     1875   iota(indices.begin(), indices.end(), 0);
     1876
     1877   SceneObject<ExplosionVertex, SSBO_Explosion>& explosion = addObject(
     1878      explosionObjects, explosionPipeline,
     1879      addObjectIndex(explosionObjects.size(), vertices),
     1880      indices, {
     1881         mat4(1.0f),
     1882         cur_time,
     1883         duration,
     1884         false
     1885      }, true);
     1886
     1887   explosion.model_base = model_mat;
     1888   explosion.model_transform = mat4(1.0f);
     1889
     1890   explosion.modified = true;
     1891}
     1892
    17991893// TODO: Fix the crash that happens when alt-tabbing
    18001894void VulkanGame::recreateSwapChain() {
     
    18581952   laserPipeline.createDescriptorPool(swapChainImages);
    18591953   laserPipeline.createDescriptorSets(swapChainImages);
     1954
     1955   createBufferSet(sizeof(UBO_Explosion), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     1956      uniformBuffers_explosionPipeline, uniformBuffersMemory_explosionPipeline, uniformBufferInfoList_explosionPipeline);
     1957
     1958   explosionPipeline.updateRenderPass(renderPass);
     1959   explosionPipeline.createPipeline("shaders/explosion-vert.spv", "shaders/explosion-frag.spv");
     1960   explosionPipeline.createDescriptorPool(swapChainImages);
     1961   explosionPipeline.createDescriptorSets(swapChainImages);
    18601962
    18611963   createCommandBuffers();
     
    18761978   asteroidPipeline.cleanup();
    18771979   laserPipeline.cleanup();
     1980   explosionPipeline.cleanup();
    18781981
    18791982   for (size_t i = 0; i < uniformBuffers_modelPipeline.size(); i++) {
     
    18972000   }
    18982001
     2002   for (size_t i = 0; i < uniformBuffers_explosionPipeline.size(); i++) {
     2003      vkDestroyBuffer(device, uniformBuffers_explosionPipeline[i], nullptr);
     2004      vkFreeMemory(device, uniformBuffersMemory_explosionPipeline[i], nullptr);
     2005   }
     2006
    18992007   vkDestroyRenderPass(device, renderPass, nullptr);
    19002008
  • vulkan-game.hpp

    r52a02e6 r4a9416a  
    5757};
    5858
     59struct ExplosionVertex {
     60   vec3 particleStartVelocity;
     61   float particleStartTime;
     62   unsigned int objIndex;
     63};
     64
    5965struct SSBO_ModelObject {
    6066   alignas(16) mat4 model;
     
    7379};
    7480
     81struct SSBO_Explosion {
     82   alignas(16) mat4 model;
     83   alignas(4) float explosionStartTime;
     84   alignas(4) float explosionDuration;
     85   alignas(4) unsigned int deleted;
     86};
     87
    7588struct UBO_VP_mats {
    7689   alignas(16) mat4 view;
    7790   alignas(16) mat4 proj;
     91};
     92
     93struct UBO_Explosion {
     94   alignas(16) mat4 view;
     95   alignas(16) mat4 proj;
     96   alignas(4) float cur_time;
    7897};
    7998
     
    183202      const float FOV_ANGLE = 67.0f; // means the camera lens goes from -33 deg to 33 def
    184203
     204      const int EXPLOSION_PARTICLE_COUNT = 300;
     205      const vec3 LASER_COLOR = vec3(0.2f, 1.0f, 0.2f);
     206
    185207      vec3 cam_pos;
    186208
     
    287309
    288310      UBO_VP_mats laser_VP_mats;
     311
     312      GraphicsPipeline_Vulkan<ExplosionVertex, SSBO_Explosion> explosionPipeline;
     313      vector<SceneObject<ExplosionVertex, SSBO_Explosion>> explosionObjects;
     314
     315      vector<VkBuffer> uniformBuffers_explosionPipeline;
     316      vector<VkDeviceMemory> uniformBuffersMemory_explosionPipeline;
     317      vector<VkDescriptorBufferInfo> uniformBufferInfoList_explosionPipeline;
     318
     319      UBO_Explosion explosion_UBO;
    289320
    290321      vector<BaseEffectOverTime*> effects;
     
    368399            vec3& start, vec3& end, vec3& intersection);
    369400
     401      void addExplosion(mat4 model_mat, float duration, float cur_time);
     402
    370403      void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags,
    371404            vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
     
    382415            void* pUserData);
    383416};
     417
     418// Start of specialized no-op functions
     419
     420template<>
     421inline void VulkanGame::centerObject(SceneObject<ExplosionVertex, SSBO_Explosion>& object) {
     422}
     423
     424// End of specialized no-op functions
    384425
    385426// TODO: Right now, it's basically necessary to pass the identity matrix in for ssbo.model
     
    409450   SceneObject<VertexType, SSBOType>& obj = objects.back();
    410451
    411    if (!is_same_v<VertexType, LaserVertex>) {
     452   if (!is_same_v<VertexType, LaserVertex> && !is_same_v<VertexType, ExplosionVertex>) {
    412453      centerObject(obj);
    413454   }
  • vulkan-utils.cpp

    r52a02e6 r4a9416a  
    257257void VulkanUtils::createVulkanImageFromFile(VkDevice device, VkPhysicalDevice physicalDevice,
    258258      VkCommandPool commandPool, string filename, VulkanImage& image, VkQueue graphicsQueue) {
     259   // TODO: Since the image loaded here will be used as a texture, display a warning if it has
     260   // non power-of-two dimensions
    259261   int texWidth, texHeight, texChannels;
    260262
Note: See TracChangeset for help on using the changeset viewer.