在Opengl es 2.0中渲染三角形的问题

problem in rendering triangles in Opengl-es 2.0

本文关键字:三角形 问题 Opengl es      更新时间:2023-10-16

可能重复:
从opengl 1.1到opengl es 2.0 时的问题

我试图通过绘制三角形来渲染等值面,该三角形从文本文件中获取数据,并使用opengl es 2.0进行渲染。我在opengl 1.1中可以做到这一点,但因为在opengl es 2.0中没有一些功能,所以我在缓冲区遇到了困难,或者可能是其他一些问题,我实际上无法理解。我正在粘贴我的绘制三角形的代码opengl和opengl es 2.0。你能告诉我为什么不能得到相同的结果吗。我正在使用pvrsdk在ubuntu 10.10中进行编码。

OpenGL ES 2.0代码:

    for (surfnum=0;surfnum<surftotal;surfnum++)
    {
        glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
        for (i=0;i<triNum[surfnum];i++)
        {
            GLfloat *Vertices[] = {    
                            triArray[surfnum][i].pt1, 
                            triArray[surfnum][i].pt2,
                            triArray[surfnum][i].pt3
                        };

            glGenBuffers(1, &ui32Vbo);
            glBindBuffer(GL_ARRAY_BUFFER, ui32Vbo);
            unsigned int uiSize = 3 * (sizeof(GLfloat) * 3); 
            glBufferData(GL_ARRAY_BUFFER, uiSize,*Vertices, GL_DYNAMIC_DRAW);
        }
        for(int i = 0; i < 8000; ++i)
        {
            glClear(GL_COLOR_BUFFER_BIT);
            int i32Location = glGetUniformLocation(uiProgramObject, "projmatrix");
            glUniformMatrix4fv( i32Location, 1, GL_FALSE, projmatrix);
            glEnableVertexAttribArray(VERTEX_ARRAY);
            glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0);
            //glDrawElements(GL_TRIANGLE_FAN, triNum[surfnum], GL_UNSIGNED_BYTE,Vertices);
            glDrawArrays(GL_TRIANGLES,0,triNum[surfnum]);
            eglSwapBuffers(eglDisplay, eglSurface);
        }
    }

和我在OpenGL中做的一样:OpenGL代码:

for (surfnum=0;surfnum<surftotal;surfnum++)
{
    for (i=0;i<triNum[surfnum];i++)
    {
        glBegin(GL_TRIANGLES);
        glVertex3fv(triArray[surfnum][i].pt1);
        glVertex3fv(triArray[surfnum][i].pt2);
        glVertex3fv(triArray[surfnum][i].pt3);
        glEnd();
        glFlush();
        glutSwapBuffers();
    }
}

surfnum、vertex_array和surftotal是定义的变量。此外,我得到了一个结果,但两者都不一样,我也得到了一场战争:libegl:软件回退

第页。S=这里,如果我试图首先获得所有顶点,然后尝试将其绑定在一个缓冲区中,那么它会出现分割错误。可能是我做错了。如果这是正确的方法,你可以告诉我怎么做。如果你想要任何其他信息,请告诉我。

嗨,克里斯蒂安,正如你所说,我可以在不使用glmapbuffer的情况下做到这一点。我试着这样做,但它仍然给我错误:

glGenBuffers(surftotal, uiVBO);
{
    for(surfnum=0; surfnum<surftotal; ++surfnum)
    {
            glBindBuffer(GL_ARRAY_BUFFER, uiVBO[surfnum]);
            size_t buf_size = 9*sizeof(GLfloat)*triNum[surfnum];
            GLfloat* const pData = (GLfloat*)malloc(buf_size);
            for(i=0; i<triNum[surfnum]; ++i) {
                memcpy(pData+i*9,   triArray[surfnum][i].pt1, 3*sizeof(GLfloat));
                memcpy(pData+i*9+3, triArray[surfnum][i].pt2, 3*sizeof(GLfloat));
                memcpy(pData+i*9+6, triArray[surfnum][i].pt3, 3*sizeof(GLfloat));
            }
            glBufferData(GL_ARRAY_BUFFER, buf_size, pData, GL_STATIC_DRAW);
            free(pData);
    }   
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glEnableVertexAttribArray(VERTEX_ARRAY);
    for(surfnum=0; surfnum<surftotal; ++surfnum)
    {
            glBindBuffer(GL_ARRAY_BUFFER, uiVBO[surfnum]);
            glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0);
            glDrawArrays(GL_TRIANGLES, 0, 3*triNum[surfnum]);
    }
    glBindBuffer(GL_ARRAY_BUFFER, 0);        //clean up, of course      
}

这就是我在编译上述程序时遇到的错误

libEGL警告:使用软件回退

首先,不要在绘图函数中创建缓冲区(应该经常运行),而是在一些初始化代码中(例如,从文件加载数据后),因为我认为从文件加载后不会更改(如果是,则只更新缓冲区数据)。第二,不要为每个三角形创建一个缓冲区,而是为所有三角形创建单个缓冲区(或者surftotal缓冲区,每个曲面一个)。

因此,首先我们创建surftotal缓冲区,希望不是在绘图例程中:

GLuint uiVBO[surftotal];
glGenBuffers(surftotal, uiVBO);

接下来,我们复制数据(只在数据更改时,可能在加载后只复制一次,如果是这样的话,GL_STATIC_DRAW可能会更好)。对于每个三角形,我们需要存储其三个顶点的位置数据,使每个三角形有9个浮动(您的代码非常混乱,存储顶点的地址,甚至没有)。我们将在不给缓冲区数据的情况下为其分配存储空间,然后映射缓冲区数据以直接写入其中。这样我们就不需要自己为数据分配临时CPU内存(驱动程序会为我们这样做)。当然,我们在复制数据后取消映射,这样缓冲区就可以用于渲染:

for(surfnum=0; surfnum<surftotal; ++surfNum)
{
    glBindBuffer(GL_ARRAY_BUFFER, uiVBO[surfnum]);
    glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat)*triNum[surfnum], NULL, GL_DYNAMIC_DRAW);
    GLfloat *pData = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
    for(i=0; i<triNum[surfnum]; ++i,pData+=9)
    {
        mempcy(pData, triArray[surfnum][i].pt1, 3*sizeof(GLfloat));
        mempcy(pData+3, triArray[surfnum][i].pt2, 3*sizeof(GLfloat));
        mempcy(pData+6, triArray[surfnum][i].pt3, 3*sizeof(GLfloat));
    }
    glUnmapBuffer(GL_ARRAY_BUFFER);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);      //clean up behind us

当最终渲染数据时,我们绑定缓冲区,告诉OpenGL从中获取顶点数据并渲染它(给glDrawArrays顶点的数量,而不是三角形)。当然,我们对每个表面都这样做:

glEnableVertexAttribArray(VERTEX_ARRAY);
for(surfnum=0; surfnum<surftotal; ++surfnum)
{
    glBindBuffer(GL_ARRAY_BUFFER, uiVBO[surfnum]);
    glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glDrawArrays(GL_TRIANGLES, 0, 3*triNum[surfnum]);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);        //clean up, of course

最好将所有曲面的三角形打包到一个缓冲区中,用一个绘图调用绘制所有曲面。考虑使用glDrawElementsGL_ELEMENT_ARRAY_BUFFER的索引三角形集可能也是一个好主意,但我认为您的数据结构甚至没有这些信息,在使事情变得更加复杂之前,您应该首先真正了解数组和缓冲区是如何工作的(我希望我的答案能对此有所帮助)。试着理解这个答案代码的每一行到底做了什么,如果需要的话,可以查询其他文档来源。一般来说,不要通过看一些代码示例来学习OpenGL或三维图形之类的复杂事物,而是通过一些真实的文档和学习资源来真正理解你在做什么。