gpt4 book ai didi

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

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

我有一个包含未分配指针 _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

destNew buffer.

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

srcBuffer to copy from.

countNumber 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/

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