Okej,所以我有一个非常奇怪的情况,我有三个(或两个,无关紧要)对象,其中一个更新其缓冲区为“动画”。换句话说,一个物体在移动而另一个物体静止不动。奇怪的部分在移动物体移动时进入,但在移动物体之后渲染的物体是精确的动画。移动物体移动但不动画。希望它有意义。
现在一些代码,因为我有故障排除它是缓冲相关我将这些部分:
Object::Object() {
...
glGenVertexArrays(1, &VAO_);
glGenBuffers(2, VBO_);
glGenBuffers(1, &EBO_);
glBindVertexArray(VAO_);
glBindBuffer(GL_ARRAY_BUFFER, VBO_[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4 * 3, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO_[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4 * 2, tex_vert, GL_STREAM_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * 6, indices, GL_STATIC_DRAW);
glBindVertexArray(0); // unbind vertex
glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // unbind buffer
}
void Object::Update() {
...
glBindBuffer(GL_ARRAY_BUFFER, VBO_[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * 4 * 2, tex_vert);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Object::Render() {
...
glUseProgram(Shader_.GetProgramID());
glBindVertexArray(VAO_);
glBindTexture(GL_TEXTURE_2D, Texture_);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
int Main() {
Object m();
Object m2();
Object m3();
while (!glfwWindowShouldClose(engine.window)) {
...
m.Update();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m.Render();
m3.Render();
m2.Render();
glfwSwapBuffers(window);
...
}
}
所以m3得到了格式化,但是m正在移动,如果m3和m2的变化位置,m2将会变得生动。如果我不渲染m2 / m3,m将获得动画和移动。值得一提的是,所有非动画对象都会获得纹理,但会保持初始状态,所以一开始看起来都很好。
VAO,VBO和EBO为每个对象获得了不同的值,但是“错误”缓冲区(VBO_ [1])得到了更新。
我想我尝试了解决这个问题的大多数错误方法,所以如果有人能指出我正确的方向,我将非常感激。
编辑:
有关如何填充缓冲区的添加信息等。
void Object::Update() {
if (Keyboard::KeyPressed(GLFW_KEY_W)) {
if (MovementY_ < 0) {
MovementY_ = 0;
}
MovementY_ += MovementSpeed_ * Engine::GetDeltaTime();
TextureTopLeft_ = glm::vec2((MALE_TEXTURE_SIZE_S * SpriteFrame_) - MALE_TEXTURE_SIZE_S, MALE_UP_STAND_T - MALE_TEXTURE_SIZE_T);
TextureTopRight_ = glm::vec2((MALE_TEXTURE_SIZE_S * SpriteFrame_), MALE_UP_STAND_T - MALE_TEXTURE_SIZE_T);
TextureBottomLeft_ = glm::vec2((MALE_TEXTURE_SIZE_S * SpriteFrame_) - MALE_TEXTURE_SIZE_S, MALE_UP_STAND_T);
TextureBottomRight_ = glm::vec2((MALE_TEXTURE_SIZE_S * SpriteFrame_), MALE_UP_STAND_T);
}
float tex_vert[4][2] = {
{TextureTopRight_.s, TextureTopRight_.t},
{TextureBottomRight_.s, TextureBottomRight_.t},
{TextureBottomLeft_.s, TextureBottomLeft_.t},
{TextureTopLeft_.s, TextureTopLeft_.t},
};
glBindBuffer(GL_ARRAY_BUFFER, VBO_[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * 4 * 2, tex_vert);
glBindBuffer(GL_ARRAY_BUFFER, 0);
PositionX_ += MovementX_;
PositionY_ += MovementY_;
}
void Object::Render() {
glm::mat4 Projection, Model;
Projection = glm::orthoLH(0.0f, float(Engine::GetFrameBufferWidth()), 0.0f, float(Engine::GetFrameBufferHeight()), 0.0f, 1000.0f);
Model = glm::translate(Model, glm::vec3(PositionX_, PositionY_, PositionY_));
glm::mat4 mvp = Projection * Model;
GLint MVP = glGetUniformLocation(Shader_.GetProgramID(), "MVP");
glUniformMatrix4fv(MVP, 1, GL_FALSE, glm::value_ptr(mvp));
glUseProgram(Shader_.GetProgramID());
glBindVertexArray(VAO_);
glBindTexture(GL_TEXTURE_2D, Texture_);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
# These two never change, assigned in object-creation.
float vertices[4][3] = {
{+SpriteWidth_, +SpriteHeight_, 0.0f},
{+SpriteWidth_, -SpriteHeight_, 0.0f},
{-SpriteWidth_, -SpriteHeight_, 0.0f},
{-SpriteWidth_, +SpriteHeight_, 0.0f},
};
unsigned int indices[] = {
2, 1, 0,
2, 0, 3,
};
片段着色器:
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D ourTexture;
void main() {
FragColor = texture(ourTexture, TexCoord);
}
顶点着色器:
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 MVP;
void main() {
gl_Position = MVP * vec4(aPos, 1.0);
TexCoord = aTexCoord;
}
问题不在于VBO_ [1]的更新,也就是应该呈现的纹理位置。
# Correct
glBindBuffer(GL_ARRAY_BUFFER, VBO_[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * 4 * 2, tex_vert);
glBindBuffer(GL_ARRAY_BUFFER, 0);
问题是由于glUseProgram的错位,运动/位置(即MVP)没有更新正确的物体。第一个对象获取空MVP,第二个对象获取第一个对象MVP,第三个对象获取第二个对象MVP,第一个对象获取第三个对象MVP等。如果glUseProgram(0)已经在渲染函数结束时使用,则没有由于MVP从未获得真正的价值,因此对象将被正确放置。
# Updated with correct position of glUseProgram()
glm::mat4 Projection, Model;
Projection = glm::orthoLH(0.0f, float(Engine::GetFrameBufferWidth()), 0.0f, float(Engine::GetFrameBufferHeight()), 0.0f, 1000.0f);
Model = glm::translate(Model, glm::vec3(PositionX_, PositionY_, PositionY_));
glm::mat4 mvp = Projection * Model;
GLint MVP = glGetUniformLocation(Shader_.GetProgramID(), "MVP");
glUseProgram(Shader_.GetProgramID()); // This must be loaded before UniformMatrix4fv
glUniformMatrix4fv(MVP, 1, GL_FALSE, glm::value_ptr(mvp));
glBindVertexArray(VAO_);
glBindTexture(GL_TEXTURE_2D, Texture_);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
所以,对其他人感到困惑的说明:
glUseProgram()
之前的glUniformMatrix4fv()
感谢Rabbid76找到了解决方案!