gpt4 book ai didi

c++ - 在渲染多个对象时,在 C++ 中使用 OpenGL 有困难

转载 作者:行者123 更新时间:2023-11-27 23:01:13 26 4
gpt4 key购买 nike

我在将多个立方体渲染到屏幕时遇到问题。我有一个立方体类,它设置立方体顶点并加载适当的着色器。发生的问题是,当我的类的多个实例是这样创建的:

Cube * cube = new Cube();
Cube * cube1 = new Cube();

然后我像这样初始化立方体对象:

cube->setPos(0, 0, 0);
cube->setType(Cube::Type::Green);
cube->createCube();

cube1->setPos(1, 0, 0);
cube1->setType(Cube::Type::Red);
cube1->createCube();

然后我在渲染方法中将立方体绘制到屏幕上,如下所示:

cube->draw();
cube1->draw();

我的立方体类如下所示:

包含“cube.h”

Shader* shader;

GLuint tex;

GLuint shaderProgram, fragmentShader, vertexShader;

GLuint vbo, ebo;

GLfloat x, y, z;
GLfloat r, g, b;

Cube::Cube() {
}

void Cube::setPos(GLfloat X, GLfloat Y, GLfloat Z) {
x = X;
y = Y;
z = Z;
}

void Cube::setType(Type type) {
switch (type) {
case Type::Red:
r = 1.0f;
g = 0.0f;
b = 0.0f;
break;

case Type::Green:
r = 0.0f;
g = 1.0f;
b = 0.0f;
break;

case Type::Blue:
r = 0.0f;
g = 1.0f;
b = 0.0f;
break;

default:
r = 0.0f;
g = 0.0f;
b = 0.0f;
break;
}
}

Cube::~Cube() {
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);

glDeleteBuffers(1, &ebo);
glDeleteBuffers(1, &vbo);
}

void Cube::createCube() {

createShader();

GLfloat vertices[] = {
//X, Y, Z, R, G, B
x - 0.5f, y - 0.5f, z - 0.5f, r, g, b, // 0
x + 0.5f, y - 0.5f, z - 0.5f, r, g, b, // 1
x + 0.5f, y + 0.5f, z - 0.5f, r, g, b, // 2
x - 0.5f, y + 0.5f, z - 0.5f, r, g, b, // 3

x - 0.5f, y - 0.5f, z + 0.5f, r, g, b, // 4
x + 0.5f, y - 0.5f, z + 0.5f, r, g, b, // 5
x + 0.5f, y + 0.5f, z + 0.5f, r, g, b, // 6
x - 0.5f, y + 0.5f, z + 0.5f, r, g, b, // 7
};

GLuint elements[] = {
0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4,
7, 3, 0, 0, 4, 7,
6, 2, 1, 1, 5, 6,
0, 1, 5, 5, 4, 0,
3, 2, 6, 6, 7, 3
};

// Create a Vertex Buffer Object and copy the vertex data to it
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

// Create an element array
glGenBuffers(1, &ebo);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements,
GL_STATIC_DRAW);

glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);

// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);

GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat),
(void*) (3 * sizeof(GLfloat)));
}

void Cube::update() {
// Calculate transformation
glm::mat4 trans;
trans = glm::rotate(trans, (float) clock() / (float) CLOCKS_PER_SEC * 1.0f,
glm::vec3(0.0f, 0.0f, 1.0f));

GLint uniTrans = glGetUniformLocation(shaderProgram, "model");
glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(trans));
glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(trans));

glm::mat4 view = glm::lookAt(glm::vec3(1.2f, 1.2f, 1.2f), glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 0.0f, 1.0f));
GLint uniView = glGetUniformLocation(shaderProgram, "view");
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));

glm::mat4 proj = glm::perspective(45.0f, 800.0f / 600.0f, 1.0f, 10.0f);
GLint uniProj = glGetUniformLocation(shaderProgram, "proj");
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));
}

void Cube::draw() {
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
}


void Cube::createShader() {
// load vertex shader source
const GLchar* vertexSource = shader->fileRead("src/shaders/vertex.vs");
if (vertexSource != NULL) std::cout << "vertexSource" << std::endl;

// load fragment shader source
const GLchar* fragmentSource = shader->fileRead("src/shaders/fragment.fs");
if (fragmentSource != NULL) std::cout << "fragmentSource" << std::endl;

// Create and compile the vertex shader
vertexShader = shader->compileShader(vertexSource, GL_VERTEX_SHADER);

// Create and compile the fragment shader
fragmentShader = shader->compileShader(fragmentSource, GL_FRAGMENT_SHADER);

// Link the vertex and fragment shader into a shader program
shaderProgram = shader->compileProgram(vertexShader, fragmentShader);
}

长话短说。我创建并初始化了两个立方体。两者都用代码绘制到屏幕上,但当编译程序运行时,屏幕上只显示第二个立方体。我的完整代码的拷贝可从 My GitHub 获得。 ,如果您想克隆和构建它。

我花了几个小时来寻找解决此问题的方法,但做不到,所以我正在联系社区。我感觉这与需要 VAO 有关,但我不知道如何或在何处实现它,我已经尝试了几种不同的方法。

非常感谢任何帮助。提前致谢!

最佳答案

您在 create 函数中设置的任何状态都不会在另一次调用之后持续存在。

首先,您应该将值移动到多维数据集类的成员。

然后在创建中你应该创建并使用一个 vao:

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

在指定顶点布局之前。

然后在绘制调用期间:

void Cube::draw() {
glUseProgram(shaderProgram);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
}

在更新中添加对 glUseProgram(shaderProgram); 的调用。

然而,使用单个静态程序然后在 uniform 中加载模型矩阵会更高效;

void Cube::draw() {
//assume program is already bound and non-cube-specific uniforms are already set
glBindVertexArray(vao);
glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(trans));//kept in a field
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
}

关于c++ - 在渲染多个对象时,在 C++ 中使用 OpenGL 有困难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27463242/

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