Я пытаюсь создать 2D-игру, используя OpenGL. Мои вспомогательные библиотеки — GLFW, GLEW, SOIL (для изображений) и glm (для математики).
Мне удалось нарисовать прямоугольник с очень простой текстурой. Но когда я пытаюсь переместить этот прямоугольник, у него часто появляется небольшое мерцание (таймер между мерцаниями почти всегда одинаков), и чем быстрее я перемещаю его, тем более заметным становится.
Еще одна проблема, с которой я сталкиваюсь, это то, что я работаю на ноутбуке, и он хорошо отрисовывается с моей встроенной графикой (нормально, так как она работает, она все еще заикается), но когда я выполняю свою программу с моей видеокартой Nvidia, она просто показывает мой цвет, ничего другого, что очень странно. Мой перевод спрайта происходит в коде runCallback (вызывается в основном цикле) и представляет собой просто умножение матриц. Затем матрица результатов извлекается и используется в коде рисования. В drawCallback есть только вызываемая функция DrawSprite. Также я должен отметить, что я использую OpenGL 3.3.
Я заранее сожалею о довольно большом количестве кода, но после тщательного тестирования и множества попыток я не знаю, в чем заключается моя ошибка …
Если вы хотите помочь мне, но нуждаетесь в дополнительной информации, я предоставлю.
ОБНОВИТЬ:
Проблема с видеокартой Nvidia решена из-за неправильного параметра. Но заикание остается.
КОД ЗАГРУЗКИ ИЗОБРАЖЕНИЯ
SD_Texture::SD_Texture(const char * fileName)
{
texture = new GLuint;
unsigned char* data = SOIL_load_image(fileName, &width, &height, 0, SOIL_LOAD_RGB);
glGenTextures(1, (GLuint*)texture);
glBindTexture(GL_TEXTURE_2D, *((GLuint*)(texture)));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
SOIL_free_image_data(data);
}
void SD_Texture::Bind()
{
glBindTexture(GL_TEXTURE_2D, *(GLuint*)texture);
}
КОД НАСТРОЙКИ ВАО
void SD_Window::SetupVAO()
{
GLfloat vertices[] =
{
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5, 0.0f, 1.0, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GL_FLOAT), (GLvoid*)nullptr);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GL_FLOAT), (GLvoid*)(3 * sizeof(GLfloat)));
glBindVertexArray(0);
}
РИСУНОК
void SD_Window::DrawSprite(SD_Sprite * sprite)
{
glActiveTexture(GL_TEXTURE0);
sprite->GetTexture()->Bind();
glUniformMatrix4fv(transformUniform, 1, GL_FALSE, glm::value_ptr(ortho * sprite->GetTransform()));
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
ГЛАВНЫЙ КОД ПЕТЛИ
void SD_Window::TakeControl(void (*runCallback)(float delta), void (*drawCallback)())
{
double currentTime;
double oldTime = 0.0f;
while (!ShouldClose())
{
currentTime = glfwGetTime();
glClear(GL_COLOR_BUFFER_BIT);
drawCallback();
glfwSwapBuffers(window);
runCallback(currentTime - oldTime);
oldTime = currentTime;
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
}
VERTEX SHADER
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;
out vec2 sCoord;
uniform mat4 transform;
void main()
{
gl_Position = transform * vec4(position, 1.0f);
sCoord = vec2(texCoord.x, 1.0f - texCoord.y);
}
ФРАГМЕНТНАЯ ШЕЙДЕР
#version 330 core
in vec2 sCoord;
out vec4 color;
uniform sampler2D sTexture;
void main()
{
color = texture(sTexture, sCoord);
}
Задача ещё не решена.
Других решений пока нет …