You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SFML中绘制VertexArray的部分顶点(类似glDrawArrays)?

在SFML中绘制VertexArray的部分顶点

SFML的VertexArray本身没有提供类似OpenGL glDrawArrays的直接参数控制,但可以通过以下两种方法实现只绘制前n个顶点:

方法一:创建临时子VertexArray(简单易用)

直接从原数组中复制前n个顶点到新的VertexArray,再绘制这个临时数组。这种方法无需操作底层OpenGL,适合大多数场景:

// 假设原VertexArray为vArr,要绘制的顶点数为n
sf::VertexArray subVertexArray(vArr.getPrimitiveType(), n);
std::copy(vArr.begin(), vArr.begin() + n, subVertexArray.begin());

// 绘制临时数组
window.draw(subVertexArray);

如果需要频繁绘制不同数量的顶点,这种方法会产生一定的内存拷贝开销,此时可以考虑第二种方法。

方法二:直接调用底层OpenGL(性能最优)

利用SFML的OpenGL上下文,直接调用glDrawArrays绘制原VertexArray的指定顶点。需要手动设置顶点属性(对应sf::Vertex的结构),并注意保存/恢复OpenGL状态,避免干扰SFML的正常渲染:

步骤1:映射SFML图元类型到OpenGL枚举值

首先需要一个辅助函数,把SFML的PrimitiveType转换成对应的OpenGL枚举:

GLenum sfmlToGLPrimitive(sf::PrimitiveType type) {
    switch(type) {
        case sf::PrimitiveType::Points:         return GL_POINTS;
        case sf::PrimitiveType::Lines:          return GL_LINES;
        case sf::PrimitiveType::LineStrip:      return GL_LINE_STRIP;
        case sf::PrimitiveType::LineLoop:       return GL_LINE_LOOP;
        case sf::PrimitiveType::Triangles:      return GL_TRIANGLES;
        case sf::PrimitiveType::TriangleStrip:  return GL_TRIANGLE_STRIP;
        case sf::PrimitiveType::TriangleFan:    return GL_TRIANGLE_FAN;
        default:                                return GL_POINTS;
    }
}

步骤2:调用OpenGL绘制指定顶点

// 保存当前OpenGL状态,避免影响SFML后续渲染
glPushAttrib(GL_ALL_ATTRIB_BITS);

const sf::Vertex* vertices = vArr.getVertices();
GLenum glMode = sfmlToGLPrimitive(vArr.getPrimitiveType());

// 设置顶点位置属性
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(sf::Vertex), &vertices[0].position);

// 设置顶点颜色属性
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(sf::Vertex), &vertices[0].color);

// 如果原VertexArray使用了纹理,需额外设置纹理坐标属性
// glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// glTexCoordPointer(2, GL_FLOAT, sizeof(sf::Vertex), &vertices[0].texCoords);

// 绘制前n个顶点
glDrawArrays(glMode, 0, n);

// 恢复之前的OpenGL状态
glPopAttrib();

注意事项

  • 确保在SFML窗口的上下文生效时调用上述代码(即窗口已创建,且在窗口的渲染循环内)。
  • 如果使用纹理,需要确保纹理已绑定,并且SFML的纹理状态正确。

内容的提问来源于stack exchange,提问作者Allay466

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:56:21