如果我使用malloc()而不是堆栈数组,OpenGL不会渲染对象
OpenGL does not render objects if I use malloc() instead of stack arrays?
在C++中的2D OpenGL游戏项目中,我现在正试图从文件中读取"敌人数量",然后渲染这些敌人。每个敌人由2个具有纹理的三角形组成(2D精灵(。
我可以为保存单个"敌人"数据(例如每个敌人的位置(的结构体使用数组声明来实现渲染,但如果我尝试使用malloc根据从文件中读取的数字动态分配内存,则不会渲染任何内容。
我做错了什么?我真的很想使用malloc,因为敌人的数量会有所不同,我不想使用固定大小的数组。
关于下面的代码:基本上,一个名为"gameEnemies"的类包含一个称为"Enemy"的结构;每次创建"gameEnemies"类的对象时,该对象都应该分配足够的内存,以便根据外部文件中的定义创建尽可能多的敌人。
-
这是一个具有固定大小数组声明的结构-这个正在工作。
struct Enemy { Point3D center; //object attributes Vector3D direction; //gets updated with current direction after rotations to show where object is facing at Vector3D collDir; //which direction collided float deltaX; float deltaY; float prevDeltaX; float prevDeltaY; float deltaA; float prevDeltaA; float speed; bool collided; int qtyCollided; //with how many other objects it collided bool alive; //matrices below passed as uniforms to shader //rotation Transform4D rotateTransf{ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f }; //moves to world position after being drawn with center at origin (0,0) Transform4D modelTransf{ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f }; //translation of texture (animation), passed as uniform to shader Transform4D transformTex{ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f }; }enemies[MAX_TMX_ENEMIES];
-
这是一个不起作用的结构,与上面的相同,只是声明了指针。
struct Enemy { Point3D center; //object attributes Vector3D direction; //gets updated with current direction after rotations to show where object is facing at Vector3D collDir; //which direction collided float deltaX; float deltaY; float prevDeltaX; float prevDeltaY; float deltaA; float prevDeltaA; float speed; bool collided; int qtyCollided; //with how many other objects it collided bool alive; //matrices below passed as uniforms to shader //rotation Transform4D rotateTransf{ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f }; //moves to world position after being drawn with center at origin (0,0) Transform4D modelTransf{ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f }; //translation of texture (animation), passed as uniform to shader Transform4D transformTex{ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f }; }*enemies;
-
下面是分配内存加初始化值的循环-似乎可以工作,因为我可以访问数据,并且在编译时和运行时都没有错误:
enemies = (Enemy*)malloc(sizeof(Enemy) * totalObj); for (int j = 0; j < totalObj; j++) //loop objects in the group { enemies[j].center = mapObj.getObjects(i)[j].center; enemies[j].direction = Vector3D{1.0f, 0.0f, 0.0f}; enemies[j].deltaX = 0.0f; enemies[j].deltaY = 0.0f; enemies[j].prevDeltaX = 0.0f; enemies[j].prevDeltaY = 0.0f; enemies[j].deltaA = 0.0f; enemies[j].prevDeltaA = 0.0f; enemies[j].speed = 6.0f; enemies[j].collided = false; enemies[j].collDir = Vector3D{ 0.0f, 0.0f, 0.f }; enemies[j].qtyCollided = 0; enemies[j].alive = true; enemies[j].modelTransf.SetTranslation(Point3D{ enemies[j].center.x, enemies[j].center.y, 0.0f }); //initial translation to world position enemies[j].rotateTransf.SetRotationZ(enemies[j].deltaA); //initial rotation = 0 enemies[j].transformTex.SetTranslation(Point3D{ 0.0f, 0.0f, 0.0f }); //no transform on texture upon object creation }
-
下面是使用数组声明时初始化值的循环-唯一的变化是没有预设malloc:
/*EXCLUDED: enemies = (Enemy*)malloc(sizeof(Enemy) * totalObj);*/ for (int j = 0; j < totalObj; j++) //loop objects in the group { enemies[j].center = mapObj.getObjects(i)[j].center; enemies[j].direction = Vector3D{1.0f, 0.0f, 0.0f}; enemies[j].deltaX = 0.0f; enemies[j].deltaY = 0.0f; enemies[j].prevDeltaX = 0.0f; enemies[j].prevDeltaY = 0.0f; enemies[j].deltaA = 0.0f; enemies[j].prevDeltaA = 0.0f; enemies[j].speed = 6.0f; enemies[j].collided = false; enemies[j].collDir = Vector3D{ 0.0f, 0.0f, 0.f }; enemies[j].qtyCollided = 0; enemies[j].alive = true; enemies[j].modelTransf.SetTranslation(Point3D{ enemies[j].center.x, enemies[j].center.y, 0.0f }); //initial translation to world position enemies[j].rotateTransf.SetRotationZ(enemies[j].deltaA); //initial rotation = 0 enemies[j].transformTex.SetTranslation(Point3D{ 0.0f, 0.0f, 0.0f }); //no transform on texture upon object creation }
-
下面的通用渲染函数:与数组配合良好,如果我使用malloc:,则不会渲染单个对象
void render() { // shader to use objShader.use(); objShader.setVec4("orthoTex", orthoTex); //common to all instances //for texture glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBindTexture(GL_TEXTURE_2D, texture); glBindVertexArray(VAO); for(int i = 0; i< totalEnemies; i++) { //pass relevant uniforms to shader before drawing each instance objShader.setVec4("transfTex", enemies[i].transformTex); objShader.setVec4("modelTransf", enemies[i].modelTransf); objShader.setVec4("rotateTransf", enemies[i].rotateTransf); //draw glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } glBindVertexArray(0); }
-
Enemy结构位于一个名为"gameEnemies"的结构中——不确定这是否会改变什么,只是以防万一。这是因为所有"敌人"都将共享通用属性,如OpenGL缓冲区、顶点、着色器等。
struct gameEnemies { protected: //arrays with vertex data and indices float vertices[16]; //holds vertex + texture coordinates for VBO (order: obj.x, obj.y, tex.x, tex.y, obj.x...) unsigned int indices[6]; //holds triangle indices for the EBO //the OpenGL buffers unsigned int VBO, VAO, EBO; //object shader Shader objShader; //texture ID unsigned int texture; float width; float height; int totalEnemies; int enemyMapPos; //position in the MAP OBJECT (which group) where enemies of specicif "label" for this handler are //transform texture coordinates to world (png file) coordinates (0,0 //bottom left to 1,1//top right) Transform4D orthoTex; struct Enemy { Point3D center; //object attributes Vector3D direction; //gets updated with current direction after rotations to show where object is facing at Vector3D collDir; //which direction collided float deltaX; float deltaY; float prevDeltaX;
等等。。。
在C++中使用malloc
是错误的,除非在非常特殊的情况下。
malloc
分配内存,但不在内存中构造任何对象。试图使用内存,就像在内存中创建了Enemy
的实例一样,会导致未定义的行为。
您需要使用new[]
。它分配内存并构造对象:
enemies = new Enemy[totalObj];
您可以销毁这些对象,然后使用delete[] enemies
释放内存。
但是,您不应该使用手动动态内存管理。改为使用std::vector
:
std::vector<Enemy> enemies;
enemies.resize(totalObj);
也不清楚为什么用默认的成员初始化器初始化类定义中的一些成员,而用外部循环初始化其他成员。
为所有成员使用默认的成员初始值设定项,或者为执行所有初始化的struct
编写适当的构造函数。
由于内存必须迭代两次,因此您当前的方法令人困惑且效率较低。
这也是危险的,因为如果在构造Enemy
s后忘记设置一个未初始化的成员,那么在使用它时就会出现未定义的行为。
- 在 glsl opengl 中将嵌套结构数组作为统一传递
- 如果我使用malloc()而不是堆栈数组,OpenGL不会渲染对象
- OpenGL 顶点数组对象与 tinyobjloader
- 假设传递给 OpenGL 的结构数组的内存布局存在潜在错误
- OpenGL:使用指向静态数据的指针数组传递缓冲区数据
- 如何从OpenGL 4.5中的单个Cube地图纹理中创建Cube地图数组纹理
- 如何使用OpenImageio将RGB值存储在数组中?(使用C ,OpenGL)
- 将 OpenGL 颜色附件存储在 constexpr GLenum 数组中
- opengl:两个不同的矢量可以绑定到同一个顶点数组对象吗
- 正确初始化 OpenGL 的结构数组
- 将opengl纹理保存到Byte数组中
- OpenGL 批处理:为什么我的绘制调用超出了数组缓冲区边界
- 将坐标数组传递给主数组(openGL,C++)
- 在 OpenGL 中重新组织图像/图片数组以适应 2 种纹理大小的幂
- openGL drawElements - 一个额外的三角形,使用索引数组
- Opengl 数组纹理,适用于原始数据,但不适用于图像数据
- 在 OpenGL 中呈现三角形结构引用数组
- OpenGL:两个顶点数组 + 两个索引数组
- C++/OpenGL-数组的指针
- OpenGL数组切换不工作