Changeset 6486ba8 in opengl-game for vulkan-game.hpp


Ignore:
Timestamp:
Jun 11, 2021, 8:12:29 PM (3 years ago)
Author:
Dmitry Portnoy <dportnoy@…>
Branches:
feature/imgui-sdl
Children:
5ea0a37
Parents:
c1ec4f6
Message:

Rewrite some parts of SDLGame and VulkanGame to store per-object buffer object
data contiguously and copied to the GPU in one call

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vulkan-game.hpp

    rc1ec4f6 r6486ba8  
    109109// TODO: Create a typedef for index type so I can easily change uin16_t to something else later
    110110// TODO: Maybe create a typedef for each of the templated SceneObject types
    111 template<class VertexType, class SSBOType>
     111template<class VertexType>
    112112struct SceneObject {
    113113   vector<VertexType> vertices;
    114114   vector<uint16_t> indices;
    115    SSBOType ssbo;
    116115
    117116   mat4 model_base;
     
    125124   // Move the targetAsteroid stuff out of this class since it is very specific to lasers
    126125   // and makes moving SceneObject into its own header file more problematic
    127    SceneObject<ModelVertex, SSBO_Asteroid>* targetAsteroid; // currently only used for lasers
    128 };
    129 
    130 // TODO: Have to figure out how to include an optional ssbo parameter for each object
     126   SceneObject<ModelVertex>* targetAsteroid; // currently only used for lasers
     127};
     128
     129// TODO: Figure out how to include an optional ssbo parameter for each object
    131130// Could probably use the same approach to make indices optional
    132131// Figure out if there are sufficient use cases to make either of these optional or is it fine to make
     
    149148};
    150149
    151 template<class VertexType, class SSBOType>
     150// TODO: Move this into its own hpp and cpp files
     151// TODO: Actually, since this is only used to make lasers deal damage to asteroids, review the logic
     152// and see if there is a more straightforward way of implementing this.
     153// If there is a simple and straightforward way to implement this in updateScene(), I should just do that instead of
     154// using this class. A general feature like this is useful, but, depending on the actual game, it might not be used
     155// that often, and using this class might actually make things more complicated if it doesn't quite implement the
     156// desired features
     157template<class SSBOType>
    152158struct EffectOverTime : public BaseEffectOverTime {
    153    GraphicsPipeline_Vulkan<VertexType>& pipeline;
    154    vector<SceneObject<VertexType, SSBOType>>& objects;
    155    unsigned int objectIndex;
     159   VulkanBuffer<SSBOType> &buffer;
     160   uint32_t objectIndex;
    156161   size_t effectedFieldOffset;
    157162   float startValue;
     
    159164   float changePerSecond;
    160165
    161    EffectOverTime(GraphicsPipeline_Vulkan<VertexType>& pipeline, vector<SceneObject<VertexType, SSBOType>>& objects,
    162                   unsigned int objectIndex, size_t effectedFieldOffset, float startTime, float changePerSecond)
    163                : pipeline(pipeline)
    164                , objects(objects)
     166   EffectOverTime(VulkanBuffer<SSBOType> &buffer, uint32_t objectIndex, size_t effectedFieldOffset, float startTime,
     167                  float changePerSecond)
     168               : buffer(buffer)
    165169               , objectIndex(objectIndex)
    166170               , effectedFieldOffset(effectedFieldOffset)
    167171               , startTime(startTime)
    168172               , changePerSecond(changePerSecond) {
    169       size_t ssboOffset = offset_of(&SceneObject<VertexType, SSBOType>::ssbo);
    170 
    171       unsigned char* effectedFieldPtr = reinterpret_cast<unsigned char*>(&objects[objectIndex]) +
    172          ssboOffset + effectedFieldOffset;
    173 
    174       startValue = *reinterpret_cast<float*>(effectedFieldPtr);
     173      startValue = *reinterpret_cast<float*>(getEffectedFieldPtr());
     174   }
     175
     176   unsigned char* getEffectedFieldPtr() {
     177      return reinterpret_cast<unsigned char*>(&buffer.get(objectIndex)) + effectedFieldOffset;
    175178   }
    176179
    177180   void applyEffect(float curTime) {
    178       if (objects[objectIndex].ssbo.deleted) {
    179          this->deleted = true;
     181      if (buffer.get(objectIndex).deleted) {
     182         deleted = true;
    180183         return;
    181184      }
    182185
    183       size_t ssboOffset = offset_of(&SceneObject<VertexType, SSBOType>::ssbo);
    184 
    185       unsigned char* effectedFieldPtr = reinterpret_cast<unsigned char*>(&objects[objectIndex]) +
    186          ssboOffset + effectedFieldOffset;
    187 
    188       *reinterpret_cast<float*>(effectedFieldPtr) = startValue + (curTime - startTime) * changePerSecond;
     186      *reinterpret_cast<float*>(getEffectedFieldPtr()) = startValue + (curTime - startTime) * changePerSecond;
    189187   }
    190188};
     
    341339      // if there is a need to add other uniform variables to one or more of the shaders
    342340
    343       vector<SceneObject<ModelVertex, SSBO_ModelObject>> modelObjects;
     341      vector<SceneObject<ModelVertex>> modelObjects;
    344342
    345343      UBO_VP_mats object_VP_mats;
    346344
    347       vector<SceneObject<ModelVertex, SSBO_ModelObject>> shipObjects;
     345      vector<SceneObject<ModelVertex>> shipObjects;
    348346
    349347      UBO_VP_mats ship_VP_mats;
    350348
    351       vector<SceneObject<ModelVertex, SSBO_Asteroid>> asteroidObjects;
     349      vector<SceneObject<ModelVertex>> asteroidObjects;
    352350
    353351      UBO_VP_mats asteroid_VP_mats;
    354352
    355       vector<SceneObject<LaserVertex, SSBO_Laser>> laserObjects;
     353      vector<SceneObject<LaserVertex>> laserObjects;
    356354
    357355      UBO_VP_mats laser_VP_mats;
    358356
    359       vector<SceneObject<ExplosionVertex, SSBO_Explosion>> explosionObjects;
     357      vector<SceneObject<ExplosionVertex>> explosionObjects;
    360358
    361359      UBO_Explosion explosion_UBO;
     
    370368
    371369      unsigned int leftLaserIdx = -1;
    372       EffectOverTime<ModelVertex, SSBO_Asteroid>* leftLaserEffect = nullptr;
     370      EffectOverTime<SSBO_Asteroid>* leftLaserEffect = nullptr;
    373371
    374372      unsigned int rightLaserIdx = -1;
    375       EffectOverTime<ModelVertex, SSBO_Asteroid>* rightLaserEffect = nullptr;
     373      EffectOverTime<SSBO_Asteroid>* rightLaserEffect = nullptr;
    376374
    377375      /*** High-level vars ***/
     
    440438      // stop using objects.back() to access the object that was just created
    441439      template<class VertexType, class SSBOType>
    442       SceneObject<VertexType, SSBOType>& addObject(vector<SceneObject<VertexType, SSBOType>>& objects,
    443                                                    GraphicsPipeline_Vulkan<VertexType>& pipeline,
    444                                                    const vector<VertexType>& vertices, vector<uint16_t> indices,
    445                                                    VulkanBuffer<SSBOType>& objectBuffer, SSBOType ssbo);
     440      SceneObject<VertexType>& addObject(vector<SceneObject<VertexType>>& objects,
     441                                         GraphicsPipeline_Vulkan<VertexType>& pipeline,
     442                                         const vector<VertexType>& vertices, vector<uint16_t> indices,
     443                                         VulkanBuffer<SSBOType>& objectBuffer, SSBOType ssbo);
    446444
    447445      template<class VertexType>
     
    451449      vector<VertexType> addVertexNormals(vector<VertexType> vertices);
    452450
    453       template<class VertexType, class SSBOType>
    454       void centerObject(SceneObject<VertexType, SSBOType>& object);
    455 
    456       template<class VertexType, class SSBOType>
    457       void updateObjectVertices(GraphicsPipeline_Vulkan<VertexType>& pipeline,
    458             SceneObject<VertexType, SSBOType>& obj, size_t index);
     451      template<class VertexType>
     452      void centerObject(SceneObject<VertexType>& object);
     453
     454      template<class VertexType>
     455      void updateObjectVertices(GraphicsPipeline_Vulkan<VertexType>& pipeline, SceneObject<VertexType>& obj,
     456                                size_t index);
    459457
    460458      void addLaser(vec3 start, vec3 end, vec3 color, float width);
    461459      void translateLaser(size_t index, const vec3& translation);
    462460      void updateLaserTarget(size_t index);
    463       bool getLaserAndAsteroidIntersection(SceneObject<ModelVertex, SSBO_Asteroid>& asteroid,
    464             vec3& start, vec3& end, vec3& intersection);
     461      bool getLaserAndAsteroidIntersection(SceneObject<ModelVertex>& asteroid, vec3& start, vec3& end,
     462                                          vec3& intersection);
    465463
    466464      void addExplosion(mat4 model_mat, float duration, float cur_time);
     
    488486
    489487template<>
    490 inline void VulkanGame::centerObject(SceneObject<ExplosionVertex, SSBO_Explosion>& object) {
     488inline void VulkanGame::centerObject(SceneObject<ExplosionVertex>& object) {
    491489}
    492490
     
    505503// Figure out a better way to allow the model matrix to be set during object creation
    506504template<class VertexType, class SSBOType>
    507 SceneObject<VertexType, SSBOType>& VulkanGame::addObject(vector<SceneObject<VertexType, SSBOType>>& objects,
    508                                                          GraphicsPipeline_Vulkan<VertexType>& pipeline,
    509                                                          const vector<VertexType>& vertices, vector<uint16_t> indices,
    510                                                          VulkanBuffer<SSBOType>& objectBuffer, SSBOType ssbo) {
     505SceneObject<VertexType>& VulkanGame::addObject(vector<SceneObject<VertexType>>& objects,
     506                                               GraphicsPipeline_Vulkan<VertexType>& pipeline,
     507                                               const vector<VertexType>& vertices, vector<uint16_t> indices,
     508                                               VulkanBuffer<SSBOType>& objectBuffer, SSBOType ssbo) {
    511509   // TODO: Use the model field of ssbo to set the object's model_base
    512510   // currently, the passed-in model is useless since it gets overridden when ssbo.model is recalculated
     
    517515   }
    518516
    519    objects.push_back({ vertices, indices, ssbo, mat4(1.0f), mat4(1.0f) });
     517   objects.push_back({ vertices, indices, mat4(1.0f), mat4(1.0f) });
    520518   objectBuffer.add(ssbo);
    521519
    522    SceneObject<VertexType, SSBOType>& obj = objects.back();
     520   SceneObject<VertexType>& obj = objects.back();
    523521
    524522   // TODO: Specify whether to center the object outside of this function or, worst case, maybe
     
    571569}
    572570
    573 template<class VertexType, class SSBOType>
    574 void VulkanGame::centerObject(SceneObject<VertexType, SSBOType>& object) {
     571template<class VertexType>
     572void VulkanGame::centerObject(SceneObject<VertexType>& object) {
    575573   vector<VertexType>& vertices = object.vertices;
    576574
     
    617615}
    618616
    619 template<class VertexType, class SSBOType>
    620 void VulkanGame::updateObjectVertices(GraphicsPipeline_Vulkan<VertexType>& pipeline,
    621       SceneObject<VertexType, SSBOType>& obj, size_t index) {
     617template<class VertexType>
     618void VulkanGame::updateObjectVertices(GraphicsPipeline_Vulkan<VertexType>& pipeline, SceneObject<VertexType>& obj,
     619                                      size_t index) {
    622620   pipeline.updateObjectVertices(index, obj.vertices, resourceCommandPool, graphicsQueue);
    623621}
Note: See TracChangeset for help on using the changeset viewer.