gpt4 book ai didi

c++ - 如果我使用 malloc() 而不是堆栈数组,OpenGL 不会渲染对象?

转载 作者:行者123 更新时间:2023-11-30 04:42:04 25 4
gpt4 key购买 nike

在我的 C++ 2D OpenGL 游戏项目中,我现在尝试从文件中读取“敌人的数量”,然后渲染这些敌人。每个敌人由 2 个具有纹理的三角形组成(2D Sprite )。

我可以通过数组声明实现渲染,该结构包含单独的“敌人”数据(例如每个敌人的位置),但是如果我尝试使用 malloc 根据我从文件中读取的数字动态分配内存,什么都不渲染。

我做错了什么?我真的很想使用 malloc,因为敌人的数量会有所不同,我不想使用固定大小的数组。

关于下面的代码:基本上一个名为“gameEnemies”的类包含一个名为“Enemy”的结构;每次创建“gameEnemies”类的对象时,该对象都应分配足够的内存以根据外部文件中定义的内容创建尽可能多的敌人。

  1. 这是带有固定大小数组声明的结构 - 这个可以工作。

    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];
  2. 这是不起作用的结构 - 与上面相同,但改为声明指针。

    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;
  3. 下面是分配内存和初始化值的循环 - 似乎可以正常工作,因为我可以访问数据,而且我在编译时和运行时都没有出错:

    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

    }
  4. 下面是使用数组声明时初始化值的循环 - 唯一的变化是没有预先设置 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

    }
  5. 在通用渲染函数之下:与数组配合良好,如果我使用 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);
    }
  6. Enemy 结构位于名为“gameEnemies”的结构内 - 不确定这是否会改变任何东西,但以防万一。这是因为所有“敌人”都将共享公共(public)属性,如 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[] enemy 释放内存。


但是,您不应该使用手动动态内存管理。使用 std::vector 代替:

std::vector<Enemy> enemies;

enemies.resize(totalObj);

也很不清楚为什么您使用默认成员初始值设定项初始化类定义中的一些成员,而其他成员则在外部循环中。

要么为所有成员使用默认成员初始化程序,要么为您的 struct 编写适当的构造函数来完成所有初始化。

您当前的方法令人困惑且效率较低,因为内存必须迭代两次。

这也是危险的,因为如果在构造 Enemy 后忘记设置其中一个未初始化的成员,那么在使用它时将出现未定义的行为。

关于c++ - 如果我使用 malloc() 而不是堆栈数组,OpenGL 不会渲染对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58922149/

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