如何在 ES2.0 中使用 VBO 画圆

Posted

技术标签:

【中文标题】如何在 ES2.0 中使用 VBO 画圆【英文标题】:How to draw a circle using VBO in ES2.0 【发布时间】:2014-08-13 05:57:53 【问题描述】:

我正在尝试在 Linux 环境中开发 ES 2.0 应用程序。我的目标 GPU 是 Fujitsu ruby​​ MB86298 。为了优化性能,我决定使用 VBO 概念。我对 VBO 很陌生。我使用 VBO 渲染了三角形和四边形等基本图元,其中没有顶点。为了使用 VBO 渲染牙冠,我计算了所有顶点(超过 200 个)。现在我发现很难将 200 个顶点的数据发送到 VBO。我无法手动输入所有顶点数据并将其存储在数组中并将其传递给 VBO。有没有办法将每个 for 循环的顶点数据(用于计算冠的顶点)发送到 VBO?任何人都可以分享使用 VBO 在 ES 2.0 中绘制圆弧或圆的代码 sn-p 吗?

【问题讨论】:

你使用什么语言? 我用的是C语言 您可能正在寻找函数:glBufferSubData - khronos.org/opengles/sdk/docs/man/xhtml/glBufferSubData.xml 没有。我想创建一个静态缓冲区。我想一次性将皇冠的整个顶点信息发送到 VBO。我不想为 for 循环的每次迭代将冠的顶点数据更新到 VBO。这涉及许多需要花费大量时间的绑定调用。我想在尽可能短的时间内渲染图元 【参考方案1】:

这里有一些用于渲染圆形的代码片段。我尚未编译或运行此代码,因此可能存在(希望是轻微的)拼写错误。

准备VBO,这将完成一次:

// Number of segments the circle is divided into.
const unsigned DIV_COUNT = 32;

// Will use a triangle fan rooted at the origin to draw the circle. So one additional
// point is needed for the origin, and another one because the first point is repeated
// as the last one to close the circle.
GLfloat* coordA = new GLfloat[(DIV_COUNT + 2) * 2];

// Origin.
unsigned coordIdx = 0;
coordA[coordIdx++] = 0.0f;
coordA[coordIdx++] = 0.0f;

// Calculate angle increment from point to point, and its cos/sin.
float angInc = 2.0f * M_PI / static_cast<float>(DIV_COUNT);
float cosInc = cos(angInc);
float sinInc = sin(angInc);

// Start with vector (1.0f, 0.0f), ...
coordA[coordIdx++] = 1.0f;
coordA[coordIdx++] = 0.0f;

// ... and then rotate it by angInc for each point.
float xc = 1.0f;
float yc = 0.0f;
for (unsigned iDiv = 1; iDiv < DIV_COUNT; ++iDiv) 
    float xcNew = cosInc * xc - sinInc * yc;
    yc = sinInc * xc + cosInc * yc;
    xc = xcNew;

    coordA[coordIdx++] = xc;
    coordA[coordIdx++] = yc;


// Repeat first point as last point to close circle.
coordA[coordIdx++] = 1.0f;
coordA[coordIdx++] = 0.0f;

GLuint vboId = 0;
glGenBuffers(1, &circVboId);
glBindBuffer(GL_ARRAY_BUFFER, circVboId);
glBufferData(GL_ARRAY_BUFFER, (DIV_COUNT + 2) * 2 * sizeof(GLfloat), coordA, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

delete[] coordA;

然后进行绘制,posLoc为位置的顶点属性的位置:

glBindBuffer(GL_ARRAY_BUFFER, circVboId);
glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posLoc);

glDrawArrays(GL_TRIANGLE_FAN, 0, DIV_COUNT + 2);

glBindBuffer(GL_ARRAY_BUFFER, 0);

【讨论】:

以上是关于如何在 ES2.0 中使用 VBO 画圆的主要内容,如果未能解决你的问题,请参考以下文章

交错的 VBO 导致 glDrawArrays() 错误

如何在 VBO 中使用 stride 参数?

在ArcGIS中怎么画圆

使用 glDrawArrays() 时如何获取 VBO 的长度以渲染所有顶点?

如何在 OpenGL ES 2 中创建和使用 VBO

如何加载 VBO 并将其呈现在单独的 Java 线程上?