0

如何使用 cocos2d v2.0 和 OpenGL ES 2.0 从 svg 文件中绘制形状?

我有一个带有形状的简单 svg 文件。如果我将 svg 文件解析为点集和贝塞尔路径句柄,是否可以使用一些 OpenGL ES 2.0 调用来绘制形状?

我想使用 svg 形状绘制我的游戏关卡的背景,以便在玩家放大和缩小时曲线继续看起来平滑。我看过 LevelSVG,但我正在寻找一个不涉及 box2d 的更简单的解决方案。

换一种方式问:在 OpenGL ES 2 中,如何从 svg 文件中的一组点和贝塞尔曲线绘制填充形状?

这是我由 GIMP 生成的包含形状的测试 svg 文件。

<svg xmlns="http://www.w3.org/2000/svg"
     width="14.2222in" height="10.6667in"
     viewBox="0 0 1024 768">
  <path id="Unnamed"
        fill="purple" stroke="purple" stroke-width="1"
        d="M 165.00,477.00
           C 165.00,477.00 249.00,348.00 325.50,373.50 
             402.00,399.00 318.00,516.00 447.00,507.00
             576.00,498.00 412.50,327.00 480.00,301.50
             547.50,276.00 639.00,429.00 655.50,510.00
             672.00,591.00 597.00,633.00 454.50,607.50
             312.00,582.00 211.50,589.50 184.50,546.00
             157.50,502.50 165.00,477.00 165.00,477.00 Z
           M 486.00,267.00" />
</svg>

这是我长期潜伏后关于SO的第一个问题。谢谢大家!

4

1 回答 1

0

对于我提出的解决方案,您需要加载 xml 文件并将数据顶点重新格式化为 GL 三角形带或三角形扇形格式。我之前在很多游戏中都使用过这种技术来绘制平滑曲线,您只需要创建足够数量的点来使线条平滑即可。

这种技术可用于创建类似于游戏 Tiny Wings 中的彩色曲线的效果。我使用这种绘图技术的一些游戏包括 Enduro Extreme Trials、SnowXross 2 和其他一些游戏。为了创建曲线,我编写了一个脚本引擎来执行函数,这些函数使用诸如正弦函数求和之类的东西来根据关卡脚本传入的参数创建几何图形。

如果您不熟悉 OpenGL 三角带绘图,您应该研究一下,因为它是 OpenGL ES 2.0(和 OpenGL ES 1.1 也是)中非常常见的绘图方式。

glDrawMode是我自己的自定义枚举,用于决定使用哪种绘制方法三角形条可能最适合贝塞尔曲线。

下面代码中的dynamicVerts是一个指向 3 个浮点结构的 C 数组的指针,但您可以将其替换为 CGPoint 并将glVertexAttribPointer参数从 3 更改为 2 以将其设置为二维而不是三个。这个数组违背了你将要拖曳的几何形状。

dynamicVertColors是指向 ccColor4Byte 结构的 C 数组的指针该数组与 glVertexAttribPointer 中的顶点对齐,以对绘制的内容进行着色。

子类CCNode并添加以下draw方法在Cocos2d 2.0中的OpenGL 2.0 ES中绘制。

-(void) draw {

    if (shouldDrawDynicVerts == YES) {

       ccGLUseProgram( shaderProgram->program_ );
        [shaderProgram setUniformForModelViewProjectionMatrix];
        ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position);

        glVertexAttribPointer(kCCVertexAttrib_Position, 3, GL_FLOAT, GL_FALSE, 0, dynamicVerts);    
        glEnableVertexAttribArray(kCCVertexAttribFlag_Position);

        glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, dynamicVertColors);   
        glEnableVertexAttribArray(kCCVertexAttribFlag_Color);



        if (glDrawMode == kDrawTriangleStrip) {
            glDrawArrays(GL_TRIANGLE_STRIP, 0, dynamicVertCount);   

        }else if (glDrawMode == kDrawLines){
            glDrawArrays(GL_LINES, 0, dynamicVertCount);    
            glLineWidth(1);

        }else if (glDrawMode == kDrawPoints){
            glDrawArrays(GL_POINTS, 0, dynamicVertCount);   

        }else if (glDrawMode == kDrawTriangleFan){
            glDrawArrays(GL_TRIANGLE_FAN, 0, dynamicVertCount); 

       }

    }

}

在进行绘图的自定义节点的 init 方法或其他适当的地方,分配 GLES 着色器程序以在绘图时使用。最简单的方法是使用 Coocos2d 内置的。

self.shaderProgram = [[CCShaderCache sharedShaderCache] programForKey:kCCShader_PositionColor];

我创建了一个带有示例 Xcode 项目的教程和免费的绘图助手类:http: //heyalda.com/drawing-with-opengl-es-2-0-in-cocos2d-2-0/

于 2012-08-03T15:40:06.603 回答