VA или делаем быстрее

Вы еще не используете VA? Тогда мы идем к вам!

[spoiler]

VA - VertexArray
Это некий массив где храняться параметры вершин. Что сокращает количество вызовов передоваемых видеокарте.

И так, вы решили нарисовать что либо с помощью VA, для этого выделяют 4 шага:
1) включить режим рисования VA
2) загрузить меш в огл
3) нарисовать
4) выключить режим рисования VA

И так погнали
Для Того что бы включить режим VA нужно написать следкющее
glEnableClientState(mode);
mode может принимать
/*http://esate.ru, isaer*/

    
    GL_VERTEX_ARRAY
    GL_COLOR_ARRAY
    GL_NORMAL_ARRAY
    GL_FOG_COORDINATE_ARRAY
    GL_TEXTURE_COORD_ARRAY
    GL_EDGE_FLAG_ARRAY
    GL_SECONDARY_COLOR_ARRAY
    GL_INDEX_ARRAY

из названия понятно какие опции они включают
Для того что бы выключить режим (после рисования) мы пишем
glDisableClientState(mode);
mode принимает тоже самое что и при enableclientstate (логично =))

после того как мы активировали VA надо передать параметры ему это делается с помощью gl * Pointer(argc);
* может принимать
/*http://esate.ru, isaer*/


  Vertex
  Color
  SecondaryColor
  и тд, как и в mode glEnableClientState

параметры у каждого поинтера разные

/*http://esate.ru, isaer*/


  glVertexPointer(       size, type, stride, pointer);
  glColorPointer(       size, type, stride, pointer);
  glSecondaryColorPointer( size, type, stride, pointer);
  glTexCoordPointer(     size, type, stride, pointer);
  glNormalPointer(           type, stride, pointer);
  glFogCoordPointer(         type, stride, pointer);
  glEdgeFlagPointer(             stride, pointer);


теперь что делают параметры
size - это размерность, например если у нас вершины имеют 3 координаты (xyz) то требуется установить 3 на size
type - тип переменных лежащих в массиве, тут все ясно, главное, что бы они были переведены в gl'овские, например float - GL_FLOAT и тд
stride - смещение (в байтах) до следующего параметра (если массив с данными однородный то 0)
pointer - ссылка на первый элемент (0 если массив однородный)

Теперь перейдем к этапу отрисовки нашего массива

Есть несколько комманд для этого:

------glArrayElement(i);
С помощью ее мы может нарисовать какую нибуть(i) точку из массива
Внимание, команда не рисует точку, она просто возврощяет соотвецтвующий вызов glVertex glTexCoord glNormal и тд, для конкретного индекса, что бы нарисовать надо будет сделать цикл по всем элементам и обернуть в стандартный glBegin/glEnd

------glDrawRangeElements(mode, start, end, count, type, indices);
тоже что и glDrawElements только может выводиьт не с начала и не до конца

------glDrawElements(mode, count, type, indices);
с помощью этой команды мы можем рисовать по индексам передоваемым в indices, count и type должны быть понятны
все же напомню count - количество вершин которые нужно отрисовать, type - тип данных массива indices
mode - GL_POLYGON, GL_TRIANGLES, и тд

------glMultiDrawElements(mode, count, type, indices, pcount);
эта команда вызывает glDrawElements pcount раз
тут есть особенность в отличии от drawelements параметр count должен быть не числом а одномерным массивом размером pcount (от туда будут браться количество точек) и параметр indices должен быть массивом указателей на список вершин

------glDrawArrays(mode, first, count);
mode уже понятен, first - с какого элемента начинать, count сколько рисовать
эта команда выводит активированный массив (glEnable * State)

------glMultiDrawArrays(mode, first, count, pcount);
так же как и glMultiDrawElements только вызывает glDrawArrays

ну вот и все, комбинируйте параметрами что бы получить нужный результат

Пример использования

/*http://esate.ru, isaer*/


#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <iostream>

using namespace std;

void init()
{  
  glClearColor(0, 0, 0, 0);
  glClearDepth(1);
  
  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  glOrtho(-1, 1, -1, 1, -1, 1);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  
  glShadeModel(GL_SMOOTH);
  
  glEnable(GL_DEPTH_TEST);
  glDepthFunc(GL_LEQUAL);
}

void free()
{}

void render()
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_COLOR_ARRAY);
  
  static float mesh[] = {
    -1, -1, 0, 1, 0, 0,
     0,  1, 0, 1, 0, 1,
     1, -1, 0, 1, 1, 0
  };  
  
  glVertexPointer(3, GL_FLOAT, 6*sizeof(float), &mesh[0]);
  glColorPointer(3, GL_FLOAT, 6*sizeof(float), &mesh[3]);
  glDrawArrays(GL_TRIANGLES, 0, 3);

  static float mesh2[] = {
    -0.1, -1, 0, 1, 0, 0,
     0.3  ,  1, 0, 1, 0, 0,
     1, -1, 0, 1, 0, 0
  };  
  
  glVertexPointer(3, GL_FLOAT, 6*sizeof(float), &mesh2[0]);
  glColorPointer(3, GL_FLOAT, 6*sizeof(float), &mesh2[3]);
  glDrawArrays(GL_TRIANGLES, 0, 3);

  glDisableClientState(GL_COLOR_ARRAY);  
  glDisableClientState(GL_VERTEX_ARRAY);
  
  glutSwapBuffers();
}

void kb(unsigned char key, int x, int y)
{
  if(key == 27)
    exit(0);
}

int main(int argc, char** argv)
{
  glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  glutInitWindowSize(640, 480);
   glutCreateWindow("VBO");
   
   init();

  glutKeyboardFunc(kb);
  glutDisplayFunc(render);
  glutMainLoop();
   
   free();
}


В следующей статье будет про использование VBO, а пока что отписывайте что не так написал, что исправить, комментарии да и вобще что хотите
0      3076        02.09.2012        6

0 
02.09.2012 00:00:00
пробовал glArrayElement(i); в цикле, что то не работает.
glColorPointer(3, GL_FLOAT, 6*sizeof(float), &mesh2[3]);
а почему 6*sizeof(float) и там, и там?
0 
02.09.2012 00:00:00
когда ты делаешь в массиве много данных и в одной строке у тебя будет 25 элементов, то ты указываешь смещение для каждого 25*sizeof(type) потому, что они у тебя ведь указываются откуда берется начало (последний аргумент), вот посмотри

static float mesh[] = {
-1, -1, 0, 1, 0, 0, 1, 0, 0, 0,
0, 1, 0, 1, 0, 1, 1, 0, 0, 0,
1, -1, 0, 1, 1, 0, 1, 0, 0, 0
};

glVertexPointer(3, GL_FLOAT, 10*sizeof(float), &mesh[0]);
glColorPointer(4, GL_FLOAT, 10*sizeof(float), &mesh[3]);


вершина начинается в mesh[0] и заканьчивается в mesh[2] потом идет цвет mesh[3] и конец в mesh[6] потом 3 ненужные ячейки, и в mesh[10] у тебя опять начало вершины и в nesh[13] начало цвета, смотрим mesh[10] — mesh[0] = 10 mesh[13] — mesh[3] = 10
и там и там смещение 10
0 
02.09.2012 00:00:00
ой не знаю как я тут объяснил но надеюсь понятно
0 
02.09.2012 00:00:00
насчет glArrayElement
забыл написать, он не рисует, он просто преобразовывает в соотвецтвующий вызов glVertex
те что бы с ним что нибуть нарисовать надо сделать вот так:

glBegin(GL_TRIANGLES);
for(int i = 0; i < 3; i++)
glArrayElement(i);
glEnd();


не особо крутой метод =)
0 
03.09.2012 00:00:00
Ясно. А почему плохой метод?
А можно не отключать glDisableClientState, если у меня все через VA рисуется?
0 
03.09.2012 00:00:00
можно не отключать, но это только сделает дополнительную память, сразу как не надо, тут же отключил, и все, меньше будет жрать
метод плохой потому что рисуется все тот же glBegin/glEnd VA не используется, просто тебе не приходится писать для каждой вершины по 150 команд для задания всего, текстурных координат, геом гоординат и тд, а все береться из твоих glVertexPoiter и тд
^
Регистрация
Регистрируясь, вы принимаете правила сайта. Если вы не получили код подтв. регистрации - не забудьте проверить папку спам.
Логин*
Email*
Пароль*
Подтверждение пароля*
 
Логин*
Код*
 
×
Восстановление пароля
Пожалуйста, заполните поля, после чего вы получите код подтверждения на ваш Email. Если код не пришел в течении нескольких минут - проверьте папку спам.
Логин

или Email
Логин*
Код подтверждения*
Новый пароль*
Подтверждение пароля*
×
Авторизация
  • Используйте вашу учетную запись на Facebook.com для входа на сайт.
  • Используйте вашу учетную запись VKontakte для входа на сайт.
  • Используйте вашу учетную запись Google для входа на сайт.
Авторизуйтесь с помощью соц. сети или с помощью аккаунта на сайте:
×