Объркан съм относно VBO и модерния openGL. Има директен въпрос в края на тази публикация, след това има пакет от тях по пътя натам. Ако имате някаква представа за нещо от това, ще съм благодарен за отговор. И ако отговорите, моля, смятайте ме за пълен идиот, без никакви познания.
И така, моята история е следната:
Имам игра, която е 2d игра отгоре надолу. Използвах режим immideate за изобразяване на 2d спрайтове. Действителните текстурни координати на моите текстурни атласи бяха статични и предварително дефинирани в отделен клас. Координатите на четворката бяха определени във всеки обект и се актуализираха с напредването на играта. Когато изобразих, просто обвързах конкретна текстура, наречена glBegin(triangles), след което извиках метод за изобразяване на всеки видим обект. Това от своя страна изпрати както квадратни координати, така и координати на текстура към моя клас Renderer, който направи openGl извикванията. След това изчистих текстурата, която извиква само glEnd().
Направих това за всички различни атласи и в реда, така че да получа правилната дълбочина.
Но времената наистина се променят. Искам да премина към използване на VBO и шейдъри. Опитвах няколко пъти в миналото, но не успях. Има просто няколко неща, които не мога да намеря в Google, за да ми дадат пълна представа за това и как мога да го използвам, за да ускоря играта си.
Знам основите. Вместо да изпращам цялата информация по шината към графичния процесор при всяко повикване за рендиране, мога просто да съхраня всичко, което ще ми трябва във фазата на инициализация, и след това да използвам шейдъри, за да изчисля крайния резултат. Но...
Имам идея за координатите на текстурата. Те ще бъдат статични, тъй като никога няма да се променят. Би имало смисъл да ги съхранявате на GPU. Но как да разбера кои координати съответстват на всеки КВАДР/ТРИЪГЪЛНИК. Мисля, че вместо четири float, всеки рендерируем обект в играта може да има някакъв вид индекс, който предава като атрибут на върховия шейдър. върховият шейдър използва индекса, за да търси четирите координати на текстурата във VBO. Това осъществимо решение ли е? Как бихте приложили нещо подобно?
Но що се отнася до четворните върхове, аз съм изгубен. Те ще се движат постоянно. Те ще бъдат видими, след това ще изчезнат и т.н. Това означава, че моят quad VBO ще се променя при всяко повикване за рендиране и кодът, който съм виждал, който актуализира VBO, е доста грозен. Виждал съм нещо като:
- съхранявайте 4-те четворни координати в масив.
- създайте плаващ буфер, поставете ги там
- манипулиране на буфера.
- изпрати буфера до VBO
Изглежда ми доста скъпо. И не разбирам как мога да изтрия определен запис (ако обект се премести извън екрана и т.н.), нито как мога да манипулирам определен запис (субект се премести). И ако трябва да актуализирам VBO по този начин при всяко повикване за рендиране, каква е печалбата в производителността? По-скоро ми прилича на загуба...
Също така, как мога да следя "дълбочината" на полученото изображение. Правя 2d, но с "дълбочина" имам предвид реда на изобразяване, напр. като се уверите, че обект2 се изобразява върху обект1. Може би различен VBO за всяка дълбочина? Или трябва да използвам z-координатата за това и да балирам неща с дълбочина. Последният няма ли да даде изпълнителски хит?
Има и фактор 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?