gpt4 book ai didi

c++ - 多种数据类型的C++列表。遗产?

转载 作者:太空宇宙 更新时间:2023-11-04 14:33:52 26 4
gpt4 key购买 nike

我有很多不同的课程。但是,它们都可以保证具有某些方法,例如render()和Activate()。

我的目标是能够将它们全部存储在一个大列表中。目前,我有一个名为Container的大类,并且我做了类似的事情来存储我拥有的许多对象。

class Container{
public:

BUTTON * buttons;
int buttons_len;

DRAW_AREA * draw_areas;
int draw_areas_len;

Container(){
// constructor
}

void render(){
for( int i = 0; i < buttons_len; i++ )
buttons[i].render();

for( int i = 0; i < draw_areas_len; i++ )
draw_areas[i].render();
}

};


这样做的问题是,每当我要添加新的数据类型时,都必须修改多个区域,将来它将变得笨拙。有什么好办法做到这一点?

我已经研究过使用模板,从我看到的结果来看,我不能将具有不同“模板变量”的类存储在同一列表中。

编辑:忘记提及渲染功能可以是不同的渲染功能。

编辑2:

我得到了我想工作的东西。不确定“好代码”方面有多好

这是一个例子:

// abstract class
class Base{
public:
virtual void render() = 0;
};


class Button : public Base{
public:
int y;

Button(){
y = 10;
}

void render(){
std::cout << "BUTTONS " << y << "\n";
}

};


class Draw_Area : public Base{
public:
int x;

Draw_Area(){
x = 5;
}

void render(){
std::cout << "DRAW AREA " << x << "\n";
}

void extra(){
std::cout << "extra draw_area\n" << x << "\n";
}
};



int main( int argc, char * * argv ){

Base * test_1 = new Button();
test_1->render();

Base * test_2 = new Draw_Area();
test_2->render();


Base * * test = new Base*[4];

test[0] = new Button();
test[1] = new Button();
test[2] = new Draw_Area();
test[3] = new Button();


test[0]->render();
test[1]->render();
test[2]->render();
test[3]->render();


return 0;
}


感谢您的所有帮助!我要处理的主要2个问题是制作一个抽象类以避免对象切片,并将指向类的指针而不是对象本身存储在列表中。

最佳答案

我有一个工作的游戏-使用现代OpenGL的着色器引擎。该项目具有集成在一起的许多组件。使用的一件事是一系列Manager Class对象,它们本身都是Singleton对象:

我无法显示完整的类,但将显示包含所有派生的Singleton类型的Singleton基类的枚举:

class Singleton {
public:
// Number Of Items In Enum Type Must Match The Number
// Of Items And Order Of Items Stored In s_aSingletons
enum SingletonType {
TYPE_LOGGER = 0, // MUST BE FIRST!
TYPE_SETTINGS,
TYPE_ENGINE,
TYPE_ANIMATION_MANAGER,
TYPE_SHADER_MANAGER,
TYPE_ASSET_STORAGE,
TYPE_AUDIO_MANAGER,
TYPE_FONT_MANAGER,
TYPE_BATCH_MANAGER,
}; // Type;

// More code below
}; // Singleton


这些对象在应用程序或游戏的生命周期内只需要一个实例。



现在,作为您的示例,并质疑上面列表中与您要实现的目标有关的重要性:


着色器管理器
资产存储
批处理管理器


其他的我们可以忽略的,因为我们不担心 AudioFontsAnimationsGame SettingsThe Main Game EngineLogger,尽管它们通过上面列出的某些对象使用。

上面的3以这样的方式集成在一起: AssetStorage类将保存所有要呈现的对象的容器。 AssetStorage还包含其他重要内容,例如加载的纹理,字体,音频文件,gui控件精灵,模型等。 AssetStorage类的目的在于,它充当负责管理所有内容的数据库。这些对象的记忆。

发送所有要渲染的顶点数据是 BatchManager's的责任,并且这基于优先级队列进行工作,在该优先级队列中,优先级队列由哪个 Batch最完整或具有 highest priority的优先级确定在 Z-Depth上。当 BatchManager准备好发送顶点数据(例如属性和制服,矩阵等)时,它会查看 ShaderManager以查看对要准备好渲染的顶点应用什么着色器技术,然后设置属性和制服。

这是一个非常复杂的野兽。这也不是唯一的方法,因为还有其他方法,尤其是当您开始开始渲染3D地形并且您必须构造一个场景图,BSP,体素,行进立方体等时。

如果您想了解有关上述技术的更多信息,可以访问 Marek Knows并遵循他的OpenGL视频教程系列。但是,上述方法使用的是Modern OpenGL,您必须按照他先前使用Deprecated-Legacy OpenGL 1.0的系列进行操作,这是他设置网站的方式。



我能做的是向您展示 Asset Storage's头文件的一小段摘录,以便您可以看到有关此类“存储”和“管理”游戏对象或“资产”的内存的容器和方法。

资产存储库

#ifndef ASSET_STORAGE_H
#define ASSET_STORAGE_H

#include "Singleton.h"
#include "CommonStructs.h"

namespace vmk {

class BaseMko;
class GuiElement;
enum GuiType;

struct Texture {
bool hasAlphaChannel;
bool generateMipMap;
bool wrapRepeat;
unsigned uWidth;
unsigned uHeight;
TextureInfo::FilterQuality filterQuality;
std::vector<unsigned char> vPixelData;

Texture( TextureInfo::FilterQuality filterQualityIn, bool generateMipMapIn, bool wrapRepeatIn ) :
hasAlphaChannel( false ),
generateMipMap( generateMipMapIn ),
wrapRepeat( wrapRepeatIn ),
uWidth( 0 ),
uHeight( 0 ),
filterQuality( filterQualityIn )
{}
}; // Texture

class AssetStorage sealed : public Singleton {
private:
typedef std::unordered_map<std::string, std::shared_ptr<BaseMko>> MapMkoAssets;
typedef std::unordered_map<std::string, TextureInfo> MapTextureInfos;
typedef std::unordered_map<std::string, std::shared_ptr<GuiElement>> MapGuiAssets;

MapMkoAssets m_mkoAssets;
MapTextureInfos m_textureInfos;
MapGuiAssets m_guiScreenAssets;
MapGuiAssets m_guiRenderableAssets;

std::vector<std::string> m_vGuiForRemoval;

public:
AssetStorage();
virtual ~AssetStorage();

static AssetStorage* const get();

// Mko Objects
BaseMko* getMko( const std::string& strId ) const;
void add( BaseMko* pMko );
bool removeMko( const std::string& strId, bool removeTexture = false );
void showLoadedMkoObjects() const;

// Texture Objects
TextureInfo getTextureInfo( const std::string& strFilename ) const;
TextureInfo add( const Texture& texture, const std::string& strFilename );
bool removeTextureInfo( const std::string& strFilename );
bool removeTextureInfo( unsigned uTextureId );
void showLoadedTextureInfo() const;

// Gui Objects
GuiElement* getGuiElement( const std::string& strId, GuiType type ) const;
void add( GuiElement* pGui, GuiType type );
bool removeGuiElement( const std::string& strId, bool removeTextures = false );
template<typename T>
bool removeGuiElement( T* pGui, bool removeTextures = false );
void markGuiForRemoval( const std::string& strId );
void cleanOrphanedGuiObjects();
void showLoadedGuiObjects() const;

private:
AssetStorage( const AssetStorage& c ); // Not Implemented
AssetStorage& operator=( const AssetStorage& c ); // Not Implemented

// Gui Objects
GuiElement* getGuiElement( const std::string& strId, const MapGuiAssets& guiMap ) const;
void add( GuiElement* pGui, MapGuiAssets& guiMap );
bool removeGuiElement( const std::string& strId, MapGuiAssets& guiMap, bool removeTextures );
}; // AssetStorage

} // namespace vmk

#endif // ASSET_STORAGE_H




我还可以向您展示 BatchManagerShaderManager类的声明,但不能向您展示它们的实现。

BatchManager.h

#ifndef BATCH_MANAGER_H
#define BATCH_MANAGER_H

#include "Singleton.h"
#include "CommonStructs.h"

namespace vmk {

class Batch;

class BatchManager sealed : public Singleton {
private:
std::vector<std::shared_ptr<Batch>> m_vBatches;

unsigned m_uNumBatches;
unsigned m_uMaxNumVerticesPerBatch;

public:
BatchManager( unsigned uNumBatches, unsigned uNumVerticesPerBatch );
virtual ~BatchManager();

static BatchManager* const get();

void render( const std::vector<GuiVertex>& vVertices, const BatchConfig& config, const std::string& strId );
void emptyAll();

private:
BatchManager( const BatchManager& c ); // Not Implemented
BatchManager& operator=( const BatchManager& c ); // Not Implemented

void emptyBatch( bool emptyAll, Batch* pBatchToEmpty );
//void renderBatch( const std::vector<GuiVertex>& vVertices, const BatchConfig& confg );

}; // BatchManager

} // namespace vmk

#endif // BATCH_MANAGER_H




ShaderManager.h

#ifndef SHADER_MANAGER_H
#define SHADER_MANAGER_H

#include "Singleton.h"
#include "ShaderProgramSettings.h"

namespace vmk {

class ShaderManager sealed : public Singleton {
private:
// Number Of Items In enum type Must Match The Number Of Items
// Stored In s_aShaders And In InfoProgram::aShaderIndex
enum ShaderType {
TYPE_VERTEX = 0,
TYPE_FRAGMENT,
}; // ShaderType

struct AttributeVariable{
unsigned uLocation;
AttributeType eType;
int iSize;

AttributeVariable( AttributeType eTypeIn, unsigned uLocationIn );
}; // AttributeVariable

struct UniformVariable{
unsigned uLocation;
UniformType eType;

UniformVariable( UniformType eTypeIn, unsigned uLocationIn );
}; // UniformVariable

typedef std::unordered_map<Attribute, AttributeVariable> MapAttributes;
typedef std::unordered_map<Uniform, UniformVariable> MapUniforms;

struct InfoProgram{
unsigned uId;
std::array<unsigned, 2> aShaderIndex;

MapAttributes mAttributes;
MapUniforms mUniforms;

InfoProgram();
}; // InfoProgram

struct InfoShader{
unsigned uId;
std::string strFilename;

InfoShader( int iOpenglSharedId, std::string strShaderFilename );
}; // InfoShader

typedef std::shared_ptr<InfoProgram> SharedInfoProgram;
typedef std::shared_ptr<InfoShader> SharedInfoShader;
typedef std::vector<SharedInfoProgram> VectorInfoPrograms;
typedef std::vector<SharedInfoShader> VectorInfoShaders;

VectorInfoPrograms m_vPrograms;
std::array<VectorInfoShaders, 2> m_avShaders;

Program m_eEnabledShaderProgram;

unsigned m_uActiveTextureNumber;

public:
ShaderManager();
virtual ~ShaderManager();

static ShaderManager* const get();

void create( ShaderProgramSettings& shaderProgramSettings );
void enable( Program eShaderProgram );
void enableAttribute( Attribute eShaderAttribute, unsigned strideBytes = 0, unsigned offsetBytes = 0, bool normalize = false ) const;
void disableAttribute( Attribute eShaderAttribute ) const;
void setAttribute( Attribute eShaderAttribute, const glm::vec4& v4Value ) const;
void setUniform( Uniform eShaderUniform, const glm::mat4& m4Matrix ) const;
void setUniform( Uniform eShaderUniform, const float fValue ) const;
void setUniform( Uniform eShaderUniform, unsigned uValue ) const;
void setUniform( Uniform eShaderUniform, bool bValue ) const;
void setTexture( unsigned uTextureNumber, Uniform eSamplerUniform, int iTextureId );

private:
ShaderManager( const ShaderManager& c ); // Not Implemented
ShaderManager& operator=( const ShaderManager& c ); // Not Implemented

unsigned initializeShader( ShaderType eType, const std::string& strShaderFilename );

void processAttributes( unsigned uInfoProgramId, Program eShaderProgram, std::vector<ShaderProgramSettings::AttributeInfo>& vAttributes, MapAttributes& mAttributes ) const;
void processUniforms( unsigned uInforProgramId, Program eShaderProgram, std::vector<ShaderProgramSettings::UniformInfo>& vUniforms, MapUniforms& mUniforms ) const;

template<typename T>
void setVertexAttribute( Attribute eShaderAttribute, const T* const pParam, bool bEnable, unsigned strideBytes, unsigned offsetBytes, bool normalize ) const;

void setVertexAttribute( AttributeVariable attrib, const void* const pVoid, bool bEnable, unsigned strideBytes, unsigned offsetBytes, bool normalize ) const;
void setVertexAttribute( AttributeVariable attrib, const float* p4Values, bool _x1_, unsigned _x2_, unsigned _x3_, bool _x4_ ) const;

}; // ShaderManager

#include "ShaderManager.inl"

} // namespace vmk

#endif // SHADER_MANAGER_H




如您所见,这是一个相当复杂的对象系统,您所要提出的问题是一个非常广泛的问题,可以根据您的需要以许多不同的方式来完成。我只是为了说明这一点而展示了一个有关如何实现这一目标的单一概念。

如上面的代码片段所示,您可以看到 AssetStorage类中不同类型的容器,然后,当您查看 BatchManager类时,可以看到用于渲染顶点的函数原型。由 render()emptyBatch()emptyAll()完成。

试图让每个“对象”都有其自己的“渲染”功能是非常不明智的。每个对象仅需担心其 Attributes & PropertiesGameEngine的责任是使用这些类集来了解何时最有效,最及时地通过 Batch Process渲染所述顶点,然后应用适当的着色或着色技术。

关于c++ - 多种数据类型的C++列表。遗产?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45003008/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com