OpenGL ES iPhone - рисование сглаженных линий

Обычно вы используете что-то вроде:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);

glLineWidth(2.0f);

glVertexPointer(2, GL_FLOAT, 0, points);
glEnableClientState(GL_VERTEX_ARRAY);

glDrawArrays(GL_LINE_STRIP, 0, num_points);

glDisableClientState(GL_VERTEX_ARRAY);

Он хорошо выглядит в симуляторе iPhone, но на iPhone линии становятся чрезвычайно тонкими и без каких-либо сглаживания.

Как вы получаете AA на iPhone?

Ответ 1

Эффект антиалиасинга можно добиться очень дешево, используя вершины с непрозрачностью 0. Вот пример изображения, чтобы объяснить:

alt text

Сравнение с AA:

alt text

Вы можете прочитать статью об этом здесь:

http://research.microsoft.com/en-us/um/people/hoppe/overdraw.pdf

Вы можете сделать что-то таким образом:

// Colors is a pointer to unsigned bytes (4 per color).
// Should alternate in opacity.
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
glEnableClientState(GL_COLOR_ARRAY);

// points is a pointer to floats (2 per vertex)
glVertexPointer(2, GL_FLOAT, 0, points);
glEnableClientState(GL_VERTEX_ARRAY);

glDrawArrays(GL_TRIANGLE_STRIP, 0, points_count);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

Ответ 2

Начиная с версии iOS версии 4.0 у вас есть простое решение, теперь можно использовать Antialiasing для всей сцены OpenGL ES всего несколькими строками добавленного кода. (И почти без потери производительности, по крайней мере, на графическом процессоре SGX).

Для кода, пожалуйста, прочитайте следующий форум Dev-Forum. Есть также некоторые примеры фотографий, как он выглядит в моем блоге.

Ответ 3

Используя http://answers.oreilly.com/topic/1669-how-to-render-anti-aliased-lines-with-textures-in-ios-4/ в качестве отправной точки, мне удалось получить сглаженные строки, подобные этим: alt text

Они не идеальны и не так хороши, как те, которые я рисовал с помощью Core Graphics, но они довольно хороши. Я на самом деле рисую одинаковые строки (вершины) дважды - один раз с большей текстурой и цветом, затем с меньшей текстурой и полупрозрачным белым.

Есть артефакты, когда линии перекрываются слишком сильно и альфа начинает накапливаться.

Ответ 4

Один подход к этому ограничению - тесселяция ваших линий в текстурированные треугольные полосы (как показано здесь).

Ответ 5

Проблема заключается в том, что на iPhone OpenGl отображает объект буфера кадра, а не буфер основного кадра, и, насколько я понимаю, FBO не поддерживает мультисэмплинг.

Существуют различные трюки, которые можно сделать, например, рендеринг другому FBO в два раза больше размера экрана, а затем полагаться на фильтрацию текстур, чтобы сгладить ситуацию, а не то, что я пробовал, хотя и не могу прокомментировать, насколько хорошо это работает.

Ответ 6

Я очень точно помню, что я пробовал это, и нет простого способа сделать это с помощью OpenGL на iPhone. Вы можете рисовать, используя CGPaths и CGContextRef, но это будет значительно медленнее.

Ответ 7

Поместите это в свой метод render и setUpFrame buffer... Вы получите сглаженный внешний вид.

/*added*/
//[_context presentRenderbuffer:GL_RENDERBUFFER];

//Bind both MSAA and View FrameBuffers.
glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, msaaFramebuffer); 
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, framebuffer );  
// Call a resolve to combine both buffers 
glResolveMultisampleFramebufferAPPLE();   
// Present final image to screen 
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
[_context presentRenderbuffer:GL_RENDERBUFFER];
/*added*/