我目前正在使用OpenGL创建一个2d格斗游戏,我遇到了一个问题,即OpenGL只在我上次初始化的精灵位置绘制,无论我初始化和尝试绘制多少精灵。即使我初始化sprite1
和sprite2
但只绘制sprite1
,sprite
仍然会被绘制。它从我的精灵类开始,我在屏幕上初始化我想要的图像以及要使用的图像:
Sprite.cpp
Init(int screenCoordinateX, int screenCoordinateY, uint imageWidth, unsigned int imageHeight, std::string imageFilePath)
{
//casting to float since GLSL shader variables vec2,3,4 require vertex data to be in floats
this->x = static_cast<float>(x);
this->y = static_cast<float>(y);
this->width = static_cast<float>(width);
this->height = static_cast<float>(height);
glGenBuffers(1, &vboID);
Blz::Graphics::GLTexture texture(imageFilePath);
this->texture = texture;
float halfWidth = this->width / 2;
//Setting sprite origin at bottom middle of image by subtracting half width
this->vertexData.at(0).SetPosition(glm::vec3{ this->x + (this->width - halfWidth), this->y + this->height, 0.0f });//Top right corner
this->vertexData.at(1).SetPosition(glm::vec3{ this->x - halfWidth, this->y + height, 0.0f });//Top left corner
this->vertexData.at(2).SetPosition(glm::vec3{ this->x - halfWidth, this->y, 0.0f });//Bottom left corner
this->vertexData.at(3).SetPosition(glm::vec3{ this->x - halfWidth, this->y, 0.0f });//Bottom left corner
this->vertexData.at(4).SetPosition(glm::vec3{ this->x + (this->width - halfWidth), this->y, 0.0f });//Bottom right corner
this->vertexData.at(5).SetPosition(glm::vec3{ this->x + (this->width - halfWidth), this->y + this->height, 0.0f });//Top right corner
this->vertexData.at(0).SetUV(glm::vec2{ 1.0f, 1.0f });
this->vertexData.at(1).SetUV(glm::vec2{ 0.0f, 1.0f });
this->vertexData.at(2).SetUV(glm::vec2{ 0.0f, 0.0f });
this->vertexData.at(3).SetUV(glm::vec2{ 0.0f, 0.0f });
this->vertexData.at(4).SetUV(glm::vec2{ 1.0f, 0.0f });
this->vertexData.at(5).SetUV(glm::vec2{ 1.0f, 1.0f });
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, (sizeof(Vector3D) * this->vertexData.size()), &this->vertexData.front(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3D), (void*)offsetof(Vector3D, position));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vector3D), (void*)offsetof(Vector3D, textureCoordinates));
//Unbind
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
然后我尝试渲染精灵传递给渲染器,如下所示:
Renderer.cpp
void Renderer::Draw(Sprite& sprite)
{
glm::mat4 orthoProjection = glm::ortho(0.0f, static_cast<sfloat>(1024), 0.0f, static_cast<sfloat>(768));
GLuint transformationMatrixUniformLocation = this->shaderProgram.GetUniformLocation("transformationMatrix");
glUniformMatrix4fv(transformationMatrixUniformLocation, 1, GL_FALSE, &(orthoProjection[0][0]));
glBindTexture(GL_TEXTURE_2D, sprite.texture.id);
glBindBuffer(GL_ARRAY_BUFFER, sprite.vboID);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
我这是我的main.cpp,我开始称呼所有内容:
int main()
{
Blz::Graphics::Renderer renderer;
Blz::Window window;
Blz::Input input;
Scene scene;
window.Initialize();
renderer.Init();
Sprite sprite1;
sprite.Init(900, 300, 200, 200, "CharImage.png");
Sprite sprite2;
sprite2.Init(100, 100, 200, 200, "CharImage.png");
while (!input.IsKeyPressed(SDLK_ESCAPE))
{
window.ClearBuffers();
renderer.Draw(sprite1);
window.SwapBuffers();
}
return 0;
}
所以即使我要求绘制sprite1
,只有sprite2
在100x 100y的位置会被吸引到屏幕上。即使我手动尝试在renderer.cpp中输入vboID
为1(vboID
sprite1
},它仍会绘制sprite2
的位置。我做错了什么?
如有必要,以下是我的着色器:
VertexShader.glsl
#version 430
in vec3 vertexPosition;
in vec2 textCoord;
out vec2 TextureCoord;
uniform mat4 transformationMatrix;
void main()
{
vec4 position = vec4(vertexPosition, 1.0f);
gl_Position = transformationMatrix * position;
TextureCoord = textCoord;
};
FragmentShader.glsl
#version 430
out vec4 daColor;
in vec2 TextureCoord;
uniform sampler2D basicTexture;
void main()
{
vec4 texel = texture(basicTexture, TextureCoord);
daColor = texel;
};
答案 0 :(得分:0)
所以我想这对任何有志于学习和使用OpenGL的人来说都是一个教训。无论何时使用VBO和vbo id将OpenGL缓冲区绑定到您,还需要在绘制之前再次指定vertexattribpointers。所以我的新renderer.cpp文件如下所示:
void Renderer::Draw(Sprite& sprite)
{
glm::mat4 orthoProjection = glm::ortho(0.0f, static_cast<sfloat>(1024), 0.0f, static_cast<sfloat>(768));
GLuint transformationMatrixUniformLocation = this->shaderProgram.GetUniformLocation("transformationMatrix");
glUniformMatrix4fv(transformationMatrixUniformLocation, 1, GL_FALSE, &(orthoProjection[0][0]));
glBindTexture(GL_TEXTURE_2D, sprite.texture.id);
glBindBuffer(GL_ARRAY_BUFFER, sprite.vboID);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3D), (void*)offsetof(Vector3D, position));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vector3D), (void*)offsetof(Vector3D, textureCoordinates));
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
这个其他的答案给出了原因:is VertexAttribPointer needed after each BindBuffer?。为避免这种情况,您可以使用较新的VAO存储顶点属性信息,这样您就不必每次都指定vertexattribpointer函数。