在c++中创建自定义类的原生数组
Creating Native Array of Custom Class in C++
我正在尝试创建一个本机对象数组,我必须一遍又一遍地重申OpenGL。
所以性能是关键。
问题是,似乎我的对象数组最终是指向任何地方的指针,或者数组从未创建。
无论如何,这里是相关类的问题:
class ItemToDraw {
public:
ItemToDraw();
~ItemToDraw();
GLuint Vertex_VBO;
GLuint Normal_VBO;
GLuint UV_VBO;
GLuint Index_VBO;
GLuint Material_VBO;
GLuint Pointer_VAO;
GLuint ElementCount;
GLuint Offset;
GLfloat ObjectColor[4];
GLfloat AmbientColor[4];
GLfloat EmissiveColor[4];
GLfloat DiffuseColor[4];
GLfloat SpecularColor[4];
GLfloat Shininess;
glm::mat4 ModelMatrix;
void DrawMe(GlManagerClass* CurrentOpenGLController);
};
我的构造函数/拆解:
ItemToDraw::ItemToDraw(){
Vertex_VBO = 0;
Normal_VBO = 0;
UV_VBO = 0;
Index_VBO = 0;
Material_VBO = 0;
Pointer_VAO = 0;
ElementCount = 0;
Offset = 0;
for (int i = 0; i < 4; i++) {
ObjectColor[i] = 0.0f;
AmbientColor[i] = 0.0f;
EmissiveColor[i] = 0.0f;
DiffuseColor[i] = 0.0f;
SpecularColor[i] = 0.0f;
}
Shininess = 0.0f;
float initializer[16];
for (int i = 0; i < 16; i++) {
initializer[i] = 0.0f;
}
ModelMatrix = glm::make_mat4x4(initializer);
}
ItemToDraw::~ItemToDraw() {
}
void ItemToDraw::DrawMe(GlManagerClass* CurrentOpenGLController) {
glm::mat4 ModelViewMatrix = CurrentOpenGLController->GetViewMatrix() * ModelMatrix;
glm::mat3 NormalMatrix = glm::transpose(glm::inverse(glm::mat3(ModelViewMatrix)));
glm::mat4 ModelViewProjectionMatrix = CurrentOpenGLController->GetProjectionViewMatrix() * ModelMatrix;
glBindVertexArray(Pointer_VAO);
glUniformMatrix3fv(CurrentOpenGLController->GetObjectOffsetPositionID(), 1, GL_FALSE,
glm::value_ptr(NormalMatrix));
glUniformMatrix4fv(CurrentOpenGLController->GetUniformGlobalPositionID(), 1, GL_FALSE, glm::value_ptr(ModelViewProjectionMatrix));
glUniform4fv(CurrentOpenGLController->GetEmmissiveMeshColorID(), 1, EmissiveColor);
glUniform4fv(CurrentOpenGLController->GetAmbientMeshColorID(), 1, AmbientColor);
glUniform4fv(CurrentOpenGLController->GetDiffuseMeshColorID(), 1, DiffuseColor);
glUniform4fv(CurrentOpenGLController->GetSpecularMeshColorID(), 1, SpecularColor);
glUniform4fv(CurrentOpenGLController->GetMaterialColorID(), 1, ObjectColor);
glUniform1f(CurrentOpenGLController->GetMeshShininessID(), Shininess);
glDrawElements(GL_TRIANGLES, ElementCount, GL_UNSIGNED_INT, reinterpret_cast<const GLvoid *>(Offset));
}
在"manager"类中,我是如何实例化数组以及定义用于控制集合的函数的:
/*
Variables
*/
ItemToDraw* CollectionOfItemsToDraw;
GLuint NumberOfItemsToDraw;
GLuint CurrentIndexOfItemToDraw;
bool IsNumberOfItemsToDrawAmountComplete;
/*
EDIT: My constructor for the GlManagerClass have these lines:
*/
NumberOfItemsToDraw = 0;
CurrentIndexOfItemToDraw = 0;
IsNumberOfItemsToDrawAmountComplete = false;
/*
Function Prototypes
*/
void IterateItemToDraw();
bool CreateItemToDraw();
ItemToDraw* GetItemToDraw(GLuint IndexOfItemToRetrieve);
GLuint GetCurrentItemNumber();
void MoveToNextItem();
/*
Functions
*/
void GlManagerClass::IterateItemToDraw() {
CurrentIndexOfItemToDraw += 1;
}
bool GlManagerClass::CreateCollectionOfItemsToDraw() {
if (IsCollectionOfItemToDrawComplete == true) {
CollectionOfItemsToDraw = new ItemToDraw[NumberOfItemsToDraw];
for (int i = 0; i < NumberOfItemsToDraw; i++) {
ItemToDraw NewItem;
CollectionOfItemsToDraw[i] = NewItem;
}
return true;
}
else {
return false;
}
}
ItemToDraw* GlManagerClass::GetItemToDraw(GLuint IndexOfElementToRetrieve) {
if (IndexOfElementToRetrieve> (NumberOfItemsToDraw - 1) || IndexOfElementToRetrieve < 0) {
return NULL;
}
else {
return &CollectionOfItemsToDraw[IndexOfElementToRetrieve];
}
}
bool GlManagerClass::SaveItemToDraw(ItemToDraw* ItemToSave, GLuint IndexOfElementToSave) {
if (IndexOfElementToSave > (NumberOfItemsToDraw - 1) || IndexOfElementToSave < 0) {
return false;
}
else {
CollectionOfItemsToDraw[IndexOfElementToSave] = (*ItemToSave);
return true;
}
}
void GlManagerClass::MoveToNextItem() {
CurrentIndexOfItemToDraw += 1;
if (CurrentIndexOfItemToDraw == NumberOfItemsToDraw) {
CurrentIndexOfItemToDraw = 0;
}
}
GLuint GlManagerClass::GetCurrentItemNumber() {
return CurrentIndexOfItemToDraw;
}
当我尝试使用数组时,问题出现了。
/*
Inside a draw call function in the GlManagerClass.
*/
for (GLuint i = 0; i < NumberOfItemsToDraw; i++) {
CollectionOfItemsToDraw[i].DrawMe(this);
}
我从列表中取出一个元素,然后其余的都是垃圾数据。
是不是缺少了什么我没有做的事情?
感谢您的宝贵时间。
编辑
也许我应该解释一下这应该是如何工作的。
我的OpenGL程序有一个标准的工作流和你在上面看到的工作流。
标准的工作流工作得很好;我想要创建的是一个非常快的高速"缓存"OpenGL(索引顶点属性ID和材料ID)的绘制调用的重要元素,这样我就可以创建一个非常快的"OnDisplay"或OnDraw循环。
尤其是对于那些变化不大的东西。
因此,程序第一次在一个工作流中运行,然后填充我试图在上面构建的数组。
在第二次和随后的运行中,我希望我的程序换档并使用上面看到的高速循环,这样我就可以循环遍历上面看到的数组并根据id进行绘制。
理论上应该更快。
这就是为什么我希望使用本机数组,所有的"vector"和其他来自库的数组都会增加额外的开销,特别是在迭代循环上,这样额外的毫秒加起来。
我找不到任何会导致您提到的问题的bug。但是你的代码中有一些愚蠢的错误。其中两个是@Mat指出的。这是另一个
bool GlManagerClass::CreateCollectionOfItemsToDraw() {
if (IsCollectionOfItemToDrawComplete == true) {
CollectionOfItemsToDraw = new ItemToDraw[NumberOfItemsToDraw]; // The objects are already created
for (int i = 0; i < NumberOfItemsToDraw; i++) {
ItemToDraw NewItem; // Here you are creating one object
CollectionOfItemsToDraw[i] = NewItem; // and here assigning again
}
return true;
}
else {
return false;
}
}
正如注释所指出的,对象数组是在分配内存时填充的。因此,在循环中再次创建和赋值是多余的。
因此,我怀疑在您的完整代码中可能存在其他类似的错误,这导致了您得到的错误。我发现GlManagerClass::SaveItemToDraw
可疑,你真的传递有效的对象指针或破坏它? 相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '