c++ - 如何从派生类实例化基类中的数组?

标签 c++ arrays inheritance opengl

我有一个包含未分配指针 _vertices 的基类,我想从派生类构造函数填充它:

class GameRenderable {  
    bool _indexed;
    int _vertSize;
    int _idxSize;

    unsigned int VAO, VBO, EBO;
    unsigned int _texture0;

protected:
    float *_vertices;
    unsigned int *_indices;

public:
    GameRenderable(GameRenderableMode grm);
    ~GameRenderable();

    void Render();

protected:
    void SetupBuffer(int, int);
};

void GameRenderable::SetupBuffer(int vs, int is) {
    _indexed = false;

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, vs, _vertices, GL_STATIC_DRAW);

    // position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // texture coord attribute
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);

    _idxSize = is;
    _vertSize = vs;
}

void GameRenderable::Render() {
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, _texture0);

    glBindVertexArray(VAO);

    glm::mat4 model = glm::mat4(1.0f);
    GetShader()->setMat4("model", model);

    glDrawArrays(GL_TRIANGLES, 0, _vertSize);
}

派生类:

class Cube : public GameRenderable {
public:
    Cube();
    ~Cube();
};

Cube::Cube():GameRenderable(GameRenderableMode::_3D) {
    /* Cube ASCII
          E--------F    A   -0.5f,  0.5f, -0.5f
         /|       /|    B    0.5f,  0.5f, -0.5f
        A--------B |    C   -0.5f, -0.5f, -0.5f
        | |      | |    D    0.5f, -0.5f, -0.5f
        | G------|-H    E   -0.5f,  0.5f,  0.5f
        |/       |/     F    0.5f,  0.5f,  0.5f
        C--------D      G   -0.5f, -0.5f,  0.5f
                        H    0.5f, -0.5f,  0.5f
    */
    float vertices[] = {
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
         0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
    };

    _vertices = new float[sizeof(vertices)];
    memcpy_s(_vertices, sizeof(vertices), vertices, sizeof(float));

    SetupBuffer(36, 0);
    SetupTexture("container.jpg");
}

Cube::~Cube() {
}

当我调用 SetupBuffer() 时,传递给 openGL 的数组始终只有 1 个元素,并且没有绘制任何内容。如果我将 SetupBuffer() 的代码直接放在构造函数中,它就可以工作。

最佳答案

GL 缓冲区问题

sizeof( type ) 运算符返回以 bytes 为单位的大小,例如代码:

std::cout << sizeof(float) << std::endl;

将打印输出:4

所以在下面一行:

_vertices = new float[sizeof(vertices)];

您分配的数据量是存储数组顶点 所需数据量的 4 倍。它应该是这样的:

_vertices = new float[sizeof(vertices) / sizeof(float)];
//this is more ugly but could also be:
_vertices = (float*)(new char[sizeof(vertices)]);
//that works since an ascii 'char' is 1 byte

来自 MSDN 的函数 memcpy_s:

Parameters

dest New buffer.

destSize Size of the destination buffer, in bytes for memcpy_s and wide characters (wchar_t) for wmemcpy_s.

src Buffer to copy from.

count Number of characters to copy.

所以调用应该是这样的:

memcpy_s(_vertices, sizeof(vertices), vertices, sizeof(vertices));
//although, I would just use the regular 'memcpy':
memcpy(_vertices, vertices, sizeof(vertices));

您的 SetupBuffer 函数采用直接输入到 glBufferData 的参数 vs,但是 glBufferData 也采用以字节为单位的大小:

size

Specifies the size in bytes of the buffer object's new data store.

因此输入值 36 是不够的。你想找到一种方法来传递 sizeof(vertices) 的值,尽管你知道每个顶点的步幅(5 个 float ),你可以将调用更改为:

glBufferData(GL_ARRAY_BUFFER, vs * 5 * sizeof(float), _vertices, GL_STATIC_DRAW);

正如提到的许多评论,您还可以使用 std::vector 类来简化一些代码,但是我认为它非常更重要解决您已编写的代码中的误解。

面向对象问题

我很确定以上内容会解决您的问题。但是,只是为了确保构造函数:

Cube::Cube() : GameRenderable(GameRenderableMode::_3D) {

不覆盖GameRenderable构造函数,GameRenderable构造函数将首先被调用(使用参数_3D)所以确保代码在 GameRenderable 构造函数中不会破坏任何东西(因为我看不到)。

关于c++ - 如何从派生类实例化基类中的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52141318/

相关文章:

c++ - CUDA/OGL 互操作崩溃

php - 如何合并两个数组数据并保存一张SQL表

java - 类不是抽象的,也不会覆盖抽象方法

c++ - 指向结构的 std::vector 的指针

ios - 过滤两个数组 Swift

c# - 如何制作具有不同签名的多态方法

C++如何优雅地处理不被继承的友情

c++ - 允许低特权用户启动 Windows 服务

c++ - C++中的ifstream不接受变量

c++ - 我们如何将一个 100 GB 的文件拆分成一百个 1 GB 的文件?