opengl 2d游戏只绘制第二个雪碧纹理而不是第一个

问题描述:

我目前正在创建一个利用OpenGL的2D战斗游戏,而且我遇到了一个问题,那里的OpenGL只在我最后初始化的精灵位置绘制,不管有多少个精灵初始化并尝试绘制。即使我初始化sprite1和sprite2,但只绘制sprite1,sprite2仍然会绘制。它从我的精灵类,我初始化在屏幕上我想我的形象,以及使用什么样的形象:opengl 2d游戏只绘制第二个雪碧纹理而不是第一个

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(这是sprite1的vboID),它仍会绘制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

请说明您是否正在使用OpenGL或OpenGL ES并相应地编辑标签。 – Reaper

+0

@Reaper对不起,我摘下了openGL ES。这是openGL – Jason

+0

@ Rabbid76哦对不起。我新的我会忘记发布一些东西。它被设置在我的Renderer :: Init()函数中,这个函数被称为之前的'GLuint uniformLocation = this-> shaderProgram.GetUniformLocation(“basicTexture”);'并且用'glUniform1i(uniformLocation,0)'设置' – Jason

所以我想这是任何有志于学习和使用OpenGL的教训。无论何时,当你使用VBOs和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); 
} 

这其他的SO答案给出了一个理由,为什么:is VertexAttribPointer needed after each BindBuffer?。为了避免这种情况,您可以使用存储顶点属性信息的较新的VAO,这样您就不必每次都指定vertexattribpointer函数。