OpenGL 2D игра только рисование второго спрайта текстуры, а не первый

В настоящее время я создаю 2D-игру с использованием OpenGL, и я столкнулся с проблемой, когда 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 обращается к экрану. Даже если я вручную попытаюсь ввести vboID из 1 (который является vboID из sprite1) в пределах renderer.cpp, он все еще рисует 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;
};

-1

Решение

Так что я думаю, что это урок для тех, кто стремится изучать и использовать OpenGL. Каждый раз, когда вы используете VBO и vbo-идентификаторы для привязки буфера 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 ответ дает причину: нужен VertexAttribPointer после каждого BindBuffer?. Чтобы избежать этого, вы должны использовать более новые VAO, в которых хранится информация об атрибутах вершин, чтобы вам не приходилось каждый раз указывать функции vertexattribpointer.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]