【问题标题】:Draw a filled shape made of bezier curves in openGL 2.0在 openGL 2.0 中绘制由贝塞尔曲线构成的填充形状
【发布时间】:2012-08-03 02:09:59
【问题描述】:

如何使用 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 的第一个问题。谢谢大家!

【问题讨论】:

    标签: opengl-es cocos2d-iphone bezier


    【解决方案1】:

    对于我提出的解决方案,您需要加载 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,在Cocos2d 2.0的OpenGL 2.0 ES中添加如下draw方法。

    -(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/

    【讨论】:

    • 谢谢吉姆,这对我有很大帮助。唯一的麻烦是,当用户放大时,我需要重新计算曲线上的点,否则需要大量的点来使曲线平滑。 OpenGL 只渲染三角形吗?
    • 我只在 iOS 中使用了不同的三角形和直线几何形状。主要是三角带。在 Open GLES 1.1 中,我创建了具有 50,000 个点的游戏,这些点定义了三角形条带以及四个 1024x1024 精灵表和 Chipmunk 物理,每帧更新执行 10 个更新循环,我仍然可以在 3GS 和更新的设备上获得 60FPS。但我也使用帧缓冲区对象来利用 GPU 来提高绘制几何图形的效率。我知道如何在 gles 1.1 中做到这一点,但还没有花时间在 2.0 中弄清楚。
    • 关于平滑度,为最接近的放大相机设置创建足够的点,你应该没问题。还应该研究缠绕方向以及如何使用单个三角形网格绘制多个单独的对象。还可能想尝试使用 CCDirectorIOS 中的 kmMat4PerspectiveProjection 函数来设置 Cocos2d 使用的默认 3D 投影。的最小和最大缩放值设置为 0.1f,zeye*2。可以更改这些以启用更大的缩放范围,即最小和最大缩放为 0.1 和 5000。
    • @JimRange 知道这是一个旧帖子,这可能被认为是一个颠簸......但是你显然有使用这种技术创建游戏的经验我想知道你是否可以帮助我解决这个问题我我有:stackoverflow.com/questions/13915531/… 如果您没有时间,请不要担心 :) 但很高兴能得到一些体面的建议!
    猜你喜欢
    • 1970-01-01
    • 2017-11-18
    • 2018-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 2013-08-21
    相关资源
    最近更新 更多