2017-07-29 74 views
-2

我目前正在創建一個利用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

回答

0

所以我想這是任何有志於學習和使用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函數。