programing

OpenGL (및 OpenGL ES)로 SVG 렌더링

minecode 2021. 1. 16. 09:26
반응형

OpenGL (및 OpenGL ES)로 SVG 렌더링


현재 OpenGL 및 OpenGL ES를 사용하여 SVG 파일에서 벡터 그래픽을 렌더링 할 수있는 가능성을 조사하고 있습니다. Windows와 Android를 타겟팅하려고합니다. 내 이상적인 솔루션은 주어진 SVG 파일에서 다각형 삼각 측량을 생성하는 최소한의 C 라이브러리를 갖는 것입니다. 그런 다음 표준 OpenGL 또는 OpenGL ES 호출을 생성하고 다시 그릴 때 최적화를 위해 표시 목록 또는 vbo를 사용합니다. 변환 및 회전 후 벡터 이미지를 그리는 디스플레이 목록을 간단하게 그려서 다른 OpenGL 호출과 혼합 할 수 있습니다.

지금까지 제안은 먼저 QT 또는 Cairo를 사용하는 것입니다. -이것은 확장 된 라이브러리없이 (내가 달성하려는 컨텍스트에서) 내 자신의 OpenGL 컨텍스트를 관리하려는 경우 옵션이 아닙니다. Android에는 적합하지 않습니다.

두 번째 옵션은 텍스처로 렌더링하는 라이브러리를 사용하는 것입니다. 정적 벡터 그래픽에는 괜찮을 수 있지만 크기 조정 및 회전이 자주 발생하는 게임에는 효율적이거나 실행 가능한 옵션이 아닙니다.

셋째, OpenVG를 사용할 가능성이 있습니다. OpenVG 사양 (ShivaVG 등)의 일부 오픈 소스 구현이 있지만 런타임에 주어진 SVG 파일에서 적절한 OpenVG 호출을 생성 할 수있는 라이브러리를 아직 찾지 못했으며이를 최적화하는 방법을 볼 수 없습니다. 디스플레이 목록이나 vbo를 사용하고 싶을 수도 있습니다.

세 가지 방법 모두 한계가 있습니다. 가장 유망한 옵션은 다른 솔루션이없는 경우 OpenVG 구현을 사용하는 것입니다. 그래서 내 질문은 내가 원하는 것을 수행하거나 내가 원하는 것에 가까운 도서관이 있습니까? 그렇지 않다면 그럴만한 이유가 있습니까? 그리고 대신 처음부터 이것을 시도하는 것이 더 낫습니까?


에서 http://shivavg.svn.sourceforge.net/viewvc/shivavg/trunk/src/shPipeline.c?revision=14&view=markup :

static void shDrawVertices(SHPath *p, GLenum mode)
{
int start = 0;
int size = 0;

/* We separate vertex arrays by contours to properly
handle the fill modes */
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(SHVertex), p->vertices.items);

while (start < p->vertices.size) {
size = p->vertices.items[start].flags;
glDrawArrays(mode, start, size);
start += size;
}

glDisableClientState(GL_VERTEX_ARRAY);
}

그래서 그것은 VBO를 사용합니다. 따라서 자신 만의 SVG 파서를 만들고 미리 만들어진 파서를 사용하고 호출을 ShivaVG로 전달하는 것이 좋습니다.

여전히 ShivaVG가 C (Java가 아님)에 있고 OpenGL 컨텍스트를 생성한다는 문제가 있습니다 (코드를 올바르게 읽으면 opengle이 아님). 따라서 Android의 NDK를 사용하여 컴파일하더라도 코드를 수정해야합니다 (예를 들어 glVertex3f를 몇 개 보았지만 그다지 필요하지 않은 것 같습니다 ... 최선을 기다립니다). 물론 다른 옵션은 C에서 Java로 코드를 이식하는 것입니다. 상상할 수있는 것만 큼 고통스럽지 않을 수도 있습니다.

행운을 빕니다 !


OpenGL ES 위에 API 구현과 같은 OpenVG 인 MonkVG를 확인하세요 .

또한 OpenVG (MonkVG) 위에 SVG 렌더링의 경우 MonkSVG를 확인 하십시오 .

MonkVG는 iOS, OSX 및 Android 플랫폼 용으로 제작되었습니다.

저는 두 도서관의 저자이며 모든 질문에 기꺼이 답변 해 드리겠습니다.


내 대답은 일반적으로 OpenGL을 사용하여 벡터 그래픽을 표시하는 것입니다.이 문제에 대한 모든 솔루션은 특히 애니메이션 SVG (SMIL)를 지원하지 않지만 다소 사소한 SVG를 지원할 수 있기 때문입니다. 애니메이션에 대해 아무 말도하지 않았기 때문에이 질문은 정적 SVG 만 암시한다고 가정합니다.

첫째, 나는 OpenVG에 신경 쓰지 않을 것입니다. MonkVG는 아마도 가장 현대적이고 불완전한 구현 일 것입니다. OpenVG위원회는 2011 년에 접혔으며 모든 구현은 포기되거나 기껏해야 레거시 소프트웨어입니다.

2011 년부터 최신 기술은 Mark Kilgard의 아기 인 NV_path_rendering 이며, 이름에서 이미 짐작할 수 있듯이 현재 공급 업체 (Nvidia) 확장 일뿐입니다. 그것에 관한 많은 자료가 있습니다.

물론 SVG와 같은 https://www.youtube.com/watch?v=bCrohG6PJQE를 로드 할 수 있습니다 . 경로에 대한 PostScript 구문도 지원합니다. 다음에서 데모 된대로 경로 렌더링을 다른 OpenGL (3D) 항목과 혼합 할 수도 있습니다.

NV_path_rendering은 이제 Google의 Skia 라이브러리에서 사용 가능한 경우 백그라운드에서 사용됩니다. (Nvidia는 2013 년 말과 2014 년에 코드를 제공했습니다.) 카이로 개발자 중 한 명 (Intel 직원이기도 함)도이 코드를 좋아하는 것 같습니다. http://lists.cairographics.org/archives/cairo/2013-March/024134 .html , 비록 cairo가 NV_path_rendering을 사용하려는 구체적인 노력을 [아직] 알지는 못했지만.

NV_path_rendering은 고정 파이프 라인에 약간의 종속성이 있으므로 OpenGL ES에서 사용하는 것이 약간 귀찮을 수 있습니다. 이 문제는 위에 링크 된 공식 확장 문서에 설명되어 있습니다. 해결 방법은 Skia / Chromium이 수행 한 작업 ( https://code.google.com/p/chromium/issues/detail?id=344330)을 참조하세요.

An upstart having even less (or downright no) vendor support or academic glitz is NanoVG, which is currently developed and maintained. (https://github.com/memononen/nanovg) Given the number of 2D libraries over OpenGL that have come and gone over time, you're taking a big bet using something not supported by a major vendor, in my humble opinion.


I am currently investigating the possibility of rendering vector graphics from an SVG file > using OpenGL and OpenGL ES. I intend to target Windows and Android. My ideal solution would be to have a minimal C library that generates a polygon triangulation from a given SVG file. This would then generate standard OpenGL or OpenGL ES calls, and use a display list or vbo for optimization when redrawing. I would simply draw a display list to draw the vector image after translating and rotating, allowing me to mix this with other OpenGL > calls.

If you only want to transform SVG vector shapes into OpenGL|ES, then I suggest to do the parser and the logic yourself. Note that SVG is a huge spec, with different features like paint servers (gradients, patterns ...), references, filters, clipping, font handling, animations, scripting, linking, etc, etc.

If you want full svg support, then there's a library on http://code.google.com/p/enesim called egueb (and particularly esvg) which uses enesim (a rendering library that has software and opengl backends) for the drawing. In most cases it uses shaders and everything is rendered into a texture, the library is very flexible allowing you to adapt to your particular needs like modifying the rendered scene, transform it, etc. Because the gl drawing is done always into a texture.

So far I see that the suggestions are to firstly use QT or Cairo. - This is not an option given that I wish to manage my own OpenGL context without bloated libraries (in the context of what I am trying to achieve). Nor is this suitable for Android.

Second option is to use libraries that render to a texture. While this might be ok for static vector graphics, it's not an efficient or feasible option for games where scaling and rotations occur frequently.

In the particular case of the gl backend, enesim does not create a GLX (or any other window dependent context), you have to provide it, so it adapts perfectly to your situation as it only uses GL calls.

The only drawback is that the library is not complete yet in terms of gl support or full SVG spec support, but depending on your needs, seems to me like a good option.


It needs to be said that rendering SVG or OpenVG with OpenGL or OpenGL ES is fundamentally a bad idea. There are reasons the OpenVG implementations are all so slow and largely abandoned. The process of tessellating paths (the foundation of all SVG/OpenVG rendering) into triangle lists as required by OpenGL is fundamentally slow and inefficient. It basically requires inserting a sort/search algorithm into the 3D rendering pipeline, which cripples performance. There is also the problem that a dynamic memory allocation scheme is required because the size of the data set is unknown since SVG places no limits on the complexity of the path geometry. A really poor design.

SVG and OpenVG were created by developers who had little understanding of how modern 3D graphics hardware engines actually work (triangle lists). They were created to be an open alternative to Adobe Flash, which also has the same flawed architecture that has made Flash reviled in the industry for unpredictable performance.

My advice is to rethink your design and use OpenGL triangle lists directly. You may have to write more code, but your app will perform about a thousand times better and you can more easily debug your code than someone elses.


You can have a look at AmanithVG, they seem to have implemented a good paths -> triangles pipeline. I've tried the iOS GL tiger example, and it seems that triangulation is not a real bottleneck.

ReferenceURL : https://stackoverflow.com/questions/6287650/rendering-svg-with-opengl-and-opengl-es

반응형