开发者

problem in rendering triangles in Opengl-es 2.0 [duplicate]

This question already has an answer here: Closed 11 years ago.

Possible Duplicate:

Problem when going from opengl 1.1 to Opengl-es 2.0

I am trying to render an isosurface by drawing triangles which takes its data from a text file and render it using opengl-es 2.0 . I was able to do it in Opengl 1.1 but because in opengl-es 2.0 some functions are not present so I am getting difficulty in buffer or may be some other problem I am actually not able to understand . I am pasting my both draw triangle code opengl and opengl-es 2.0 . Can you tell me why is am not able to get the same result . i am doing coding in ubuntu 10.10 with the use of pvrsdk.

OpenGL-ES 2.0 code :

    for (surfnum=0;surfnum<surftotal;surfnum++)
    {
        glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
        for (i=0;i<triNum[surfnum];i++)
        {
            GLfloat *Vertices[] = {    
                            triArr开发者_开发问答ay[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);
        }
    }

same thing I have done it in OpenGL : OpenGL code :

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 are defined variables. Also i am getting a result but not the same for both and I am also getting a warnig : libegl : software fallback

P.S = here if I try to get first all the vertices and then try to bind it in a single buffer then it gives segmentation fault . May be I am doing that wrong . If thats a correct way you can tell me to how to do that . If you want any other information tell me.

HI christian as you said that I can do this without using glmapbuffer I try to do that but it still gives me error:

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      

}

thats the error I am getting while compiling the above program

libEGL warning: use software fallback


First, don't create a buffer in the drawing function (which is supposed to run often), but in some initialization code (e.g. after loading the data from file), as I suppose it won't change after loaded from the file (and if yes, then just update the buffer data). Second, don't make a buffer for every triangle, but a single one for all triangles (or maybe surftotal buffers, one for each surface).

So first we create surftotal buffers, hopefully not in the draw routine:

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

Next we copy the data (only when it changed, maybe only once after loading, if that's the case, GL_STATIC_DRAW might be better). For each triangle we need to store the position data of its three vertices, making 9 floats per triangle (Your code is quite messed up, storing the addresses of the vertices or not even that). We will allocate storage for the buffer without giving it data and then map the buffer data to write directly into it. This way we don't need to allocate temporary CPU memory for our data ourselves (The driver will do that for us). Of course we unmap it after copying the data, so that the buffer can then be used for rendering:

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

When finally rendering the data, we bind the buffer, tell OpenGL to source the vertex data from it and render it (giving glDrawArrays the number of vertices and not triangles). Of course we do that for each surface:

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

It may be a better idea to pack all surface's triangles into a single buffer to draw all surfaces with a single draw call. It may also be a good idea to consider indexed triangle sets using glDrawElements and the GL_ELEMENT_ARRAY_BUFFER, but I suppose your data structure doesn't even have that information and you first should really understand how arrays and buffers work before complicating things even more (I hope my answer helps with that). Try to understand what each and every line of this answer code really does, querying other sources of documentation if needed. In general, don't learn such complex things like OpenGL or 3d graphics in general by staring at some code samples, but by some real documentation and learning resources, to really understand what you are doing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜