Я запутался в VBO и современном openGL. Там прямой вопрос в конце этого поста, значит там их пачка на подходе. Если у вас есть какие-либо сведения об этом, я был бы признателен за ответ. И если вы ответите, пожалуйста, считайте меня полным идиотом, ничего не знающим.
Итак, моя история такова:
У меня есть игра, которая представляет собой 2D-игру сверху вниз. Я использовал режим immideate для рендеринга 2D-спрайтов. Фактические координаты текстур моих текстурных атласов были статическими и предопределенными в отдельном классе. Координаты четырехугольника были определены в каждом объекте и обновлялись по ходу игры. При рендеринге я просто связывал определенную текстуру с именем glBegin(triangles), а затем вызывал метод рендеринга каждого видимого объекта. Это, в свою очередь, отправило координаты квадрата и координаты текстуры моему классу Renderer, который сделал вызовы openGl. Затем я сбросил текстуру, которая вызывает только glEnd().
Я делал это для всех разных атласов и в том порядке, чтобы получилась нужная глубина.
Но времена действительно меняются. Я хочу перейти на использование VBO и шейдеров. Я пытался несколько раз в прошлом, но потерпел неудачу с треском. Есть просто несколько вещей, которые я не могу найти в Google, чтобы дать мне полное представление о нем и о том, как я могу использовать его для ускорения моей игры.
Я знаю основы. Вместо отправки всей информации по шине на графический процессор при каждом вызове рендеринга я могу просто сохранить все, что мне нужно, на этапе инициализации, а затем использовать шейдеры для расчета конечного результата. Но...
У меня есть идея для текстурных координат. Они будут статичными, так как никогда не изменятся. Имеет смысл хранить их на GPU. Но как мне узнать, какие координаты соответствуют каждому QUAD/TRIANGLE. Я думаю, что вместо четырех поплавков у каждого рендеримого объекта в игре может быть какой-то индекс, который он передает как атрибут вершинному шейдеру. вершинный шейдер использует индекс для поиска четырех координат текстуры в VBO. Это осуществимое решение? Как бы вы реализовали нечто подобное?
Но что касается четырехъядерных вершин, я потерялся. Они будут постоянно перемещаться. Они будут видны, затем исчезнут и т. д. Это означает, что мой четырехъядерный VBO будет меняться при каждом вызове рендеринга, а код, который я видел, который обновляет VBO, довольно уродлив. Я видел что-то вроде:
- сохраните 4 четырехъядерных координаты в массиве.
- создать floatbuffer, поместить их туда
- управлять буфером.
- отправить буфер в VBO
Мне кажется довольно дорого. И я не понимаю, как я могу удалить определенную запись (если объект перемещается за пределы экрана и т. д.) и как я могу манипулировать определенной записью (объект перемещается). И если мне придется обновлять VBO таким образом при каждом вызове рендеринга, каков прирост производительности? Для меня это больше похоже на потерю...
Кроме того, как я могу отслеживать «глубину» полученного изображения. Я делаю 2d, но под «глубиной» я подразумеваю порядок рендеринга, например. убедиться, что объект2 отображается поверх объекта1. Возможно, разные VBO для каждой глубины? Или я должен использовать z-координату для этого и enbale глубины глубины. Не даст ли последний хит производительности?
Также есть фактор 2d. Я очень уважаю 3D, но я хочу использовать 2D и воспользоваться тем фактом, что теоретически он должен давать лучшую производительность. Однако, судя по тому, что я собрал, это не так. В opengl 3+ кажется, что для того, чтобы я мог рендерить 2D-материал, мне нужно сначала перевести его в 3D, так как это процессы в аппаратном обеспечении. Мне это кажется странным, так как конечный результат на экране - 2d. Есть ли способ обойти это и сохранить GPU работу 2d -> 3d -> 2d?
Другими словами, как я могу эффективно изменить это:
class main{
void main(){
while(true){
Renderer.bind();
//call render in all gameObjects
Renderer.flush();
}
}
}
class GameObject{
private float X1, X2, Y1, Y2;
private TexureCoordinate tex;
render(float dt){
//update X1, X2...
Renderer.render(tex.getX1(), tex.getX2()... X1, X2 ...);
}
}
class Renderer{
//called once
void bind(Texture texture){
texture.bind();
glBegin(GL_TRIANGLES)
}
//called "nr of visable objects" times
void render(texX1, texX2, texY1, texY2, quadX1, quadX2, quadY1, quadY2){
glTexCoo2d(texX1, texY1)
....
etc.
....
}
void flush(){
glEnd();
}
}
Во что-то, что использует современный openGl?