如何用 VBO 绘制三角形?

Posted

技术标签:

【中文标题】如何用 VBO 绘制三角形?【英文标题】:How can I draw a triangle with a VBO? 【发布时间】:2012-06-15 03:29:22 【问题描述】:

我正在尝试让我的 VBO 进行绘图,但我什么也看不到。我正在尝试绘制一个三角形(在我看来,一个三角形是朝着正确方向的良好开端)。一切都编译并运行而不会中断。

void initGraphics(int width, int height) 
    glViewport(0, 0, width, height);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, width, height, 0.0);
    glMatrixMode(GL_MODELVIEW);


GLuint vboId;

void initVbo(void) 
    GLsizei dataSize;
    GLfloat* vertices;
    int vCount = 3;

    dataSize = sizeof(GLfloat) * 3 * vCount;

    vertices = (GLfloat*)malloc(dataSize);

    vertices[0] = 0;
    vertices[1] = 0;
    vertices[2] = 0;

    vertices[3] = 100;
    vertices[4] = 0;
    vertices[5] = 0;

    vertices[6] = 100;
    vertices[7] = 100;
    vertices[8] = 0;

    glewInit();

    glGenBuffersARB(1, &vboId);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);

    glBufferDataARB(GL_ARRAY_BUFFER_ARB, dataSize, vertices, GL_STATIC_DRAW_ARB);

    free(vertices);

    //glDeleteBuffersARB(1, &vboId); // edit #1


unsigned int indices[] =  0, 1, 2 ; // edit #3

void drawVbo(void) 

    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(1.0, 1.0, 1.0, 1.0);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, 0);
//edit #1, #2
    glDrawElements(GL_TRIANGLES, 3 /*1*/, /*GL_UNSIGNED_BYTE*/ GL_UNSIGNED_INT, &indices);

    glDisableClientState(GL_VERTEX_ARRAY);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); 

这些是被调用的函数。我在 Windows 上运行,我正在避免发布一堆与 Windows 相关的代码...

编辑#1

修改了代码以反映 genpfault 的建议。

编辑#2

修改了代码以反映 Nicol Bolas 的建议。

评论 #1

以下代码有效(只是为了证明投影设置正确):

glBegin(GL_TRIANGLES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(100.0, 0.0, 0.0);
glVertex3f(100.0, 100.0, 0.0);
glEnd();

编辑#3

修改了代码以反映 Nicol Bolas 的建议。

更新 #1

修改后的代码现在可以工作了。虽然我很好奇如何让 glDrawArrays 正常工作......我的实现看起来像:

glDrawArrays(GL_TRIANGLES, 0, 0);

这对我来说似乎不对,但spec 说:

mode:指定要渲染的图元类型。可接受符号常量 GL_POINTS、GL_LINE_STRIP、GL_LINE_LOOP、GL_LINES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN、GL_TRIANGLES、GL_QUAD_STRIP、GL_QUADS 和 GL_POLYGON。

first:指定启用数组中的起始索引。

count:指定要渲染的索引数。

根据 Nicol Bolas 所说的,因为我不应该需要索引,所以 0, 0 作为参数是有意义的。对吧?

【问题讨论】:

【参考方案1】:
glGenBuffersARB(1, &vboId);

glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, dataSize, vertices, GL_STATIC_DRAW_ARB);

free(vertices);
glDeleteBuffersARB(1, &vboId);  // wat

glDeleteBuffersARB() 调用后,指向的 VBO ID 无效,不能在 glBindBufferARB() 中使用。

还有:

glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, &indices);

您已将indices 定义为unsigned int,因此您应该使用GL_UNSIGNED_INT 而不是GL_UNSIGNED_BYTE

【讨论】:

我已更新我的代码以反映您的建议,但我仍然遇到同样的问题。【参考方案2】:
 glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_INT, &indices);

您可能知道,三角形由三个顶点组成。您正在发送 one(第二个参数)。您不能从一个位置绘制三角形。

【讨论】:

我已经更新了我的代码以反映您的建议,但我仍然遇到同样的问题。 你必须实际使用三个索引。您的数组中只有一个元素。另外,您为什么要使用glDrawElements 根本?为什么不使用glDrawArrays,这是您在没有索引时使用的。喜欢你的代码。 Tbh...这是因为我试图跟随这个:songho.ca/opengl/gl_vbo.html 我现在将尝试使用 glDrawArrays。

以上是关于如何用 VBO 绘制三角形?的主要内容,如果未能解决你的问题,请参考以下文章

为啥绘制我的 OpenGL-ES VBO 网格会阻止其他三角形显示?

android opengl GLES20:如何用每个模型矩阵绘制多个三角形? (表现不错))

我的OpenGL学习进阶之旅介绍顶点缓冲区对象VBO和元素数组缓冲区对象EBO,并对比使用VBO和不使用VBO绘制三角形的效果

如何用android 画出三角形

如何用android 画出三角形

在每一帧上更新整个 VBO 是绘制许多变化的独特三角形的最有效方法吗?