OpenGL ES iPhone-dibujando líneas anti alias
opengl-es line (7)
Normalmente, usarías algo como:
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);
Se ve bien en el simulador de iPhone, pero en el iPhone las líneas se vuelven extremadamente delgadas y sin ningún anti aliasing.
¿Cómo obtienes AA en iPhone?
A partir de iOS versión 4.0 tiene una solución fácil, ahora es posible usar Antialiasing para toda la escena de OpenGL ES con solo unas líneas de código agregado. (Y casi ninguna pérdida de rendimiento, al menos en la GPU SGX).
Para el código, lea el siguiente subproceso de Apple Dev-Forum . También hay algunas imágenes de muestra de cómo me parece en mi blog.
El problema es que en el iPhone OpenGl se convierte en un objeto de búfer de cuadro en lugar de en el búfer de cuadro principal y, como yo lo entiendo, los FBO no son compatibles con la multimuestreo.
Hay varios trucos que se pueden hacer, como renderizar en otro FBO al doble del tamaño de visualización y luego confiar en el filtrado de texturas para suavizar las cosas, algo que no he probado, por lo que no puedo comentar cómo funciona esto.
Pon esto en tu método de renderizado y setUpBrame buffer ... Obtendrás apariencia anti-aliased.
/*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*/
Recuerdo muy específicamente que probé esto y no hay una manera simple de hacerlo usando OpenGL en el iPhone. Puede dibujar usando CGPaths y un CGContextRef, pero eso será significativamente más lento.
Un enfoque en torno a esta limitación es tiselar sus líneas en tiras triangulares con textura (como se ve here ).
Uno puede lograr el efecto de anti aliasing muy barato utilizando vértices con opacidad 0. Aquí hay un ejemplo de imagen para explicar:
Comparación con AA:
Puedes leer un artículo sobre esto aquí:
http://research.microsoft.com/en-us/um/people/hoppe/overdraw.pdf
Podrías hacer algo de esta manera:
// 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);
Usando http://answers.oreilly.com/topic/1669-how-to-render-anti-aliased-lines-with-textures-in-ios-4/ como punto de partida, pude obtener un anti-aliased líneas como estas:
No son perfectos ni tan bonitos como los que yo había dibujado con Core Graphics, pero son bastante buenos. De hecho, estoy dibujando las mismas líneas (vértices) dos veces, una con mayor textura y color, luego con textura más pequeña y blanco translúcido.
Hay artefactos cuando las líneas se superponen demasiado y las alfas comienzan a acumularse.