OpenGL отправляет указатели вершин или генерирует буферы - PullRequest
0 голосов
/ 08 декабря 2011

Я только что запустил OpenGL для iPhone, используя GLKit. Мой опыт программирования - почти просто Java и цель c с небольшим, небольшим опытом работы с C, C ++ более десяти лет назад. Все, что осталось, - это отдаленное воспоминание о том, как я боролся с указателями - и мне кажется, что я провалился.

Теперь мне кажется, что все возвращается ко мне ...

Я прошел несколько итераций замечательной, великолепной учебной серии Яна Террела , которая действительно помогла мне (спасибо !!!).

Этот вопрос касается следующих частей кода (которые в основном взяты из учебных пособий):

@interface AAAShape : NSObject
{
  NSMutableData *vertexData;
  // ...
}
@property(readonly) int vertexCount;
@property(readonly) GLKVector2 *vertices; 
//...    
@end

@implementation AAAShape
//...


-(GLKVector2 *)vertices
{
  if(!vertexData)
  {
    vertexData = [NSMutableData dataWithLength:sizeof(GLKVector2)*self.vertexCount];
  }
  return [vertexData mutableBytes];
}

-(void)renderInScene:(AAAScene *)scene 
{
  //... Effect Stuff
  //...
  glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, self.vertices);
  //...
}
//...
@end

//Using the Shape: 
//(AATriangle is of AAAShape and implements the vertextCount with "return 3;")    
AAATriangle *triangle = [[AAATriangle alloc]init];

triangle.vertices[0] = GLKVector2Make(2., .0);
triangle.vertices[1] = GLKVector2Make(-2., .0);
triangle.vertices[2] = GLKVector2Make(.0, -3.);
//...

Все это работает очень хорошо, но потом я наткнулся на следующее в Руководстве Apple по OpenGl :

[...], но неэффективно. Каждый раз, когда вызывается DrawModel, индекс и данные вершин копируются в OpenGL ES и передаются в графическое оборудование. [...] может повлиять на производительность. [...]ваше приложение должен хранить свои данные вершин в объекте буфера вершин (VBO). [...]

Предлагаемый пример кода для этого (другие источники показывают почти то же самое) выглядит следующим образом:

GLuint    vertexBuffer;
void CreateVertexBuffers()
{

    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

} 

и более поздний рисунок с:

void DrawModelUsingVertexBuffers()
{
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(vertexStruct), (void*)offsetof(vertexStruct,position));
    glEnableVertexAttribArray(ATTRIB_POSITION);
   //...
 }

У меня есть несколько вопросов по этому поводу:

  • Насколько значительны упомянутые воздействия на производительность? Нужно ли менять код?
  • Что ... на самом деле происходит в первых примерах кода выше (код Яна / моего)?
    • Почему можно установить вершины [i], если вершины доступны только для чтения и где и как выделяется память для вершин?
  • Где я мог бы поместить приведенный выше код (материал для создания буфера и -binding) в подходе Яна / моего и почему нет связи (в смысле переменных есть вызовы методов или что-то еще) между привязкой и чертежом?

1 Ответ

2 голосов
/ 08 декабря 2011
  • Насколько значительны упомянутые воздействия на производительность? Нужно ли менять код?

Если данные постоянно меняются, VBO мало что дает. Однако, если геометрия статична, это имеет огромное значение, поскольку она экономит драгоценную пропускную способность между процессором и графическим процессором, чтобы не копировать ее постоянно.

  • Что ... на самом деле происходит в первых примерах кода выше (код Яна / мой)?

Массив заполняется данными вершин. Затем указатель в OpenGL устанавливается на эти данные. Когда вызывается glDraw…, указатели разыменовываются, и данные извлекаются из памяти процесса на сторону рендеринга и обрабатываются там в операциях рисования.

  • Почему можно установить вершины [i], если вершины доступны только для чтения и где и как выделяется память для вершин?

Потому что только указатель доступен только для чтения. Переменная, на которую она указывает, - чтение / запись

  • Где я мог бы поместить приведенный выше код (создание и привязку буфера) в подходе Иана / моего подхода

glGenBuffers и glBufferData переходят к созданию данных вершин. glVertexPointer остается там, где он есть. и glBindBuffer используется на обоих сайтах.

и почему нет связи (в смысле переменных есть вызовы методов или что-то в этом роде) между привязкой и чертежом?

Я точно знаю, что вы имеете в виду под этим вопросом.

...