我有一个Vulkan项目,该项目使用的模型管理器基于我的教授编写的模型管理器。在这个模型管理器中,我Model.h
#include
分别将Mesh.h
,#include
到vulkan/vulkan.h
和#include
到{{ 1}}。在外部,它们都引用了我的包装的静态全局实例,用于我的引擎的呈现部分。在我的Google搜索过程中,我得出的初步结论是我具有循环依赖关系。我希望有人能为我指出这一点。
Model.h
Texture.h
Texture.h
#pragma once
#include <vector>
#include <vulkan/vulkan.h>
#include "Texture.h"
#include "Mesh.h"
struct Model
{
uint8_t _inuse;
uint32_t _refcount;
TextLine filename;
Mesh *mesh; //C4430 & C2143
Texture *texture; //C4430 & C2143
VkDescriptorPool descriptorPool;
std::vector<VkDescriptorSet> descriptorSets;
uint32_t descriptorSetCount;
void DrawModel(Model *model, uint32_t bufferFrame, VkCommandBuffer
commandBuffer);
};
class Model_Manager
{
private:
std::vector<Model> model_list;
uint32_t modelMax;
public:
uint32_t swapchainLength;
VkDevice logDevice;
VkPhysicalDevice physDevice;
VkDescriptorSetLayout descriptorSetLayout;
void Model_ManagerInit(uint32_t maxModels, uint32_t chainLength,
VkDevice device, VkPhysicalDevice physicalDevice);
Model* NewModel();
Model* GetModelByFilename(char *filename);
Model LoadModel(char * filename);
void DeleteModel(Model *model);
VkDescriptorSetLayout* GetModelDescriptorSetLayout(){ return
&descriptorSetLayout; }
static void CreateDescriptorPool(Model *model, VkDevice device);
static void CreateDescriptorSets(Model *model);
static void CreateDescriptorSetLayout(Model *model, VkDevice device);
static void ModelSetup(Model *model, VkDevice lDevice);
};
extern Model_Manager modelManager;
Mesh.h
#pragma once
#include <vector>
#include "gf3d_text.h"
#include "Vulkan_Graphics.h"
struct Texture
{
uint8_t _inuse;
uint32_t _refcount;
TextLine filename;
VkImage textureImage;
VkDeviceMemory textureImageMemory;
VkImageView textureImageView;
VkSampler textureSampler;
};
class Texture_Manager
{
private:
uint32_t textureMax;
VkDevice logDevice;
public:
std::vector<Texture> textureList;
void Texture_ManagerInit(uint32_t maxTextures, VkDevice lDevice);
static Texture* LoadTexture(char *filename);
static Texture* GetTextureByFilename(char * filename);
static void CopyBufferToImage(VkBuffer buffer, VkImage image, uint32_t
width, uint32_t height);
static Texture* NewTexture();
static void CreateTextureSampler(Texture *tex, VkDevice device);
static void DeleteTexture(Texture *tex, VkDevice device);
};
extern Texture_Manager textureManager;
Vulkan_Graphics.h
#pragma once
#include "gf3d_text.h"
#include "Vulkan_Graphics.h"
struct Vertex
{
glm::vec3 vertex;
glm::vec3 normal;
glm::vec2 texel;
};
struct Face
{
uint32_t verts[3];
};
struct Mesh
{
TextLine filename;
uint32_t _refCount;
uint8_t _inuse;
uint32_t vertexCount;
VkBuffer buffer;
VkDeviceMemory bufferMemory;
uint32_t faceCount;
VkBuffer faceBuffer;
VkDeviceMemory faceBufferMemory;
void MeshRender(Mesh *mesh, VkCommandBuffer commandBuffer, VkDescriptorSet
*descSet);
};
class Mesh_Wrapper
{
private:
std::vector<Mesh> mesh_list;
uint32_t maxMeshes;
VkVertexInputAttributeDescription attributeDescriptions[3];
VkVertexInputBindingDescription bindingDescription;
std::vector<Command> stagingCommandBuffer;
VkDevice logDevice;
VkPhysicalDevice physDevice;
public:
Mesh_Wrapper();
~Mesh_Wrapper();
void Mesh_WrapperInit(uint32_t meshCount, VkDevice logDevice,
VkPhysicalDevice physDevice);
Mesh* NewMesh();
void DeleteMesh(Mesh* mesh);
Mesh* LoadMesh(char *filename);
Mesh* GetMeshByFilename(char *filename);
VkVertexInputAttributeDescription* GetAttributeDescriptions(uint32_t
*count);
VkVertexInputBindingDescription* GetBindDescription();
static Mesh* LoadMesh(char * filename, Mesh_Wrapper *mWrapper);
static void CreateVertexBufferFromVertices(Mesh *mesh, Vertex *vertices,
uint32_t vcount, Face *faces, uint32_t fcount);
static void SetupFaceBuffers(Mesh *mesh, Face *faces, uint32_t fcount);
};
extern Mesh_Wrapper meshManager;
答案 0 :(得分:2)
我无法诚实地告诉您是否具有循环依赖关系,但是您拥有.h文件(包括其他.h文件)的事实使它有一定的可能性。我可以告诉你如何避免。
当您为类声明 pointer 或 reference 时,您不需要完整的类定义。前瞻性声明可以。在您的Model.h
中,不必包含Texture.h
和Mesh.h
。将它们替换为前向声明:
struct Texture;
struct Mesh;
您需要确保在实际尝试使用这些指针的源文件中包含这些标题。
答案 1 :(得分:0)
您对文件有循环依赖关系,该依赖关系应由#pragma once
语句破坏。该语句保证include
文件在编译中仅包含一次。因此,如果Mesh.h
已包含在Model.h中,并且首先编译了Mesh.h,则尽管它已包含在Vulkan_Graphics.h中,也不会再次编译。
但是,问题在于此编译指示不是标准的编译指示,某些编译器可能不支持该编译指示。因此,保护文件免受多个包含内容和导致循环依赖的可能性的标准方法是使用保护宏来保护文件,即
#ifndef MY_HEADER_FILE
#define MY_HEADER_FILE
... header file contents ...
#endif
缺点是您必须确保宏名称在所有编译文件中都是唯一的,通常将文件名用作其模板。