在openGL 2.0中绘制由贝塞尔曲线构成的填充形状

时间:2012-08-03 02:10:00

标签: opengl-es cocos2d-iphone bezier

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

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

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

问另一种方法:在OpenGL ES 2中,如何从一组点和bezier曲线中绘制填充形状,如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>

这是我作为长期潜伏者之后的第一个问题。谢谢大家!

1 个答案:

答案 0 :(得分:0)

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

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

如果你不熟悉OpenGL三角形条画,你应该研究一下,因为它是在OpenGL ES 2.0(以及OpenGL ES 1.1)中绘制的一种非常常见的方式。

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

下面代码中的 dynamicVerts 是指向3个float结构的C数组的指针,但您可以将其替换为CGPoint并将 glVertexAttribPointer 参数从3更改为2将其设置为两个维度而不是三个维度。这个数组会破坏您将要拖拽的几何体。

dynamicVertColors 是指向ccColor4Byte结构的C数组的指针。此数组与glVertexAttribPointer中的顶点对齐,以为绘制的颜色着色。

子类CCNode并添加以下绘制方法以在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/