开发者

Using VBO's and CPU usage is very high

I'm really not sure what to do anymore. I'v made my application use VBO's and my cpu usage still goes into the 70's and 80's. My render proceedure works like this:

Set the camera transformation if the shape has not been tesselated, tesselate it. create it's VBO if it has a VBO, use it.

You will notice I have display lists too, I might use these if VBO is not supported. I went and found an OpenGL demo that renders a 32000 poly mesh at 60fps on my PC and uses 4% cpu. I'm rendering about 10,000 polys @ 60fps using vbos and its using 70-80%.

Here is my render proc:

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        POINT hh = controls.MainGlFrame.GetMousePos();
        POINTFLOAT S;
        S.x = static_cast<float>(hh.x);
        S.y = static_cast<float>(hh.y);
        POINTFLOAT t;
        t.x = 256;
        t.y = 256;
        POINT dimensions;
        dimensions.x = 512;
        dimensions.y = 512;
        glDeleteTextures(1,&texName);
        texName = functions.CreateGradient(col,t,S,512,512,true);

        itt = true;
    }
    HDC hdc;
    PAINTSTRUCT ps; 
    glEnable(GL_MULTISAMPLE_ARB);
    glEnable(GL_BLEND);

    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    hdc = BeginPaint(controls.MainGlContext.mhWnd,&ps);

    //start OGL code
    glClearColor( 1.0f, 1.0f, 1.0f, 0.0f );
    if(!current.isdrawing)
    glClear( GL_COLOR_BUFFER_BIT );

    glPushMatrix();
    glTranslatef(controls.MainGlFrame.GetCameraX(),
    controls.MainGlFrame.GetCameraY(),0);
    //glTranslatef(current.ScalePoint.x,current.ScalePoint.y,0);


    glScalef(current.ScaleFactor,current.ScaleFactor,current.ScaleFactor);
    //glTranslatef(-current.ScalePoint.x,-current.ScalePoint.y,0);


    if(!current.isdrawing)
    {
        for(unsigned int currentlayer = 0; currentlayer < layer.size(); ++currentlayer)
        {
            PolygonTesselator.Init(); 
            for(unsigned int i = 0; i < layer[currentlayer].Shapes.size(); i++)
            {
                if(layer[currentlayer].Shapes[i].DisplayListInt == -999)
                {
                    gluTessNormal(PolygonTesselator.tobj, 0, 0, 1);
                    PolygonTesselator.Set_Winding_Rule(layer[currentlayer].Shapes[i].WindingRule); 
                    glEnable(GL_TEXTURE_2D);
                    glBindTexture(GL_TEXTURE_2D, texName);

                    layer[currentlayer].Shapes[i].DisplayListInt = glGenLists(1);
                    glNewList(layer[currentlayer].Shapes[i].DisplayListInt,GL_COMPILE);

                    PolygonTesselator.SetDimensions(layer[currentlayer].Shapes[i].Dimensions,layer[currentlayer].Shapes[i].minima);
                    PolygonTesselator.Begin_Polygon(); 
                    for(unsigned int c = 0; c < layer[currentlayer].Shapes[i].Contour.size(); ++c)
                    {
                        if(layer[currentlayer].Shapes[i].Color.a != 0)
                        {
                            PolygonTesselator.Begin_Contour();

                            for(unsigned int j = 0; j < layer[currentlayer].Shapes[i].Contour[c].DrawingPoints.size(); ++j)
                            {
                                gluTessVertex(PolygonTesselator.tobj,&layer[currentlayer].Shapes[i].Contour[c].DrawingPoints[j][0],
                                    &layer[currentlayer].Shapes[i].Contour[c].DrawingPoints[j][0]);
                            }

                            PolygonTesselator.End_Contour();
                        }
                    }
                    PolygonTesselator.End_Polygon();
                    glEndList();
                    PolygonTesselator.TransferVerticies(layer[currentlayer].Shapes[i].OutPoints);
                    glGenBuffersARB(1,&layer[currentlayer].Shapes[i].VBOInt);
                    glBindBufferARB(GL_ARRAY_BUFFER_ARB,layer[currentlayer].Shapes[i].VBOInt);
                    glBufferDataARB(GL_ARRAY_BUFFER_ARB,sizeof(GLfloat) * layer[currentlayer].Shapes[i].OutPoints.size(),
                        &layer[currentlayer].Shapes[i].OutPoints[0], GL_STATIC_DRAW_ARB);

                    InvalidateRect(controls.MainGlFrame.framehWnd,NULL,false);
                }
                else //run vbo
                {
                    //glEnable(GL_TEXTURE开发者_StackOverflow社区_2D);
                    //glDisable(GL_TEXTURE_2D);
                    //glBindTexture(GL_TEXTURE_2D, texName);
                    glColor4f(layer[currentlayer].Shapes[i].Color.r,
                    layer[currentlayer].Shapes[i].Color.g,
                    layer[currentlayer].Shapes[i].Color.b,
                    layer[currentlayer].Shapes[i].Color.a);
                    //glColor4f(1,1,1,1);

                    glBindBufferARB(GL_ARRAY_BUFFER_ARB, layer[currentlayer].Shapes[i].VBOInt);     
                    //glCallList(layer[currentlayer].Shapes[i].DisplayListInt);
                    glEnableClientState(GL_VERTEX_ARRAY);
                    glVertexPointer(2, GL_FLOAT, 0, 0);
                    glDrawArrays(GL_TRIANGLES, 0, layer[currentlayer].Shapes[i].OutPoints.size() / 2);

                    glDisableClientState(GL_VERTEX_ARRAY);
                    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
                }

                glDisable(GL_TEXTURE_2D);
                //Draw outlines
                if(layer[currentlayer].Shapes[i].Outline.OutlinePoints.size() > 4)
                {
                    glColor4f(layer[currentlayer].Shapes[i].Outline.OutlineColor.r
                        ,layer[currentlayer].Shapes[i].Outline.OutlineColor.g
                        ,layer[currentlayer].Shapes[i].Outline.OutlineColor.b
                        ,layer[currentlayer].Shapes[i].Outline.OutlineColor.a);
                }

            }
            PolygonTesselator.End();
        }
    }

    glPopMatrix();

    //end OGL code
    glFlush();
    SwapBuffers(hdc);

    glDisable(GL_MULTISAMPLE_ARB);
    EndPaint(controls.MainGlContext.mhWnd,&ps);

}

Why could I be getting such high cpu usage?


Under what conditions is that first bit of code run? There's a couple of suspicious-looking lines in there:

glDeleteTextures(1,&texName);
texName = functions.CreateGradient(col,t,S,512,512,true);

If you're deleting and recreating a texture every time you paint, that could get expensive. I couldn't say how expensive the OpenGL parts would be -- I'd expect uploading texture data to be reasonably efficient, even if deleting and creating texture names might be less so -- but perhaps CreateGradient is inherently slow. Or maybe you're accidentally hitting some kind of slow path for your graphics card. Or the function is creating all the mipmap levels. And so on.

Aside from that, some random ideas:

  • What is the present interval? If the buffer swap is set to sync with the monitor, you may incur a delay because of that. (You can use the WGL_EXT_swap_control extension to tweak this value.)

  • If all of this is being run in response to a WM_PAINT, check that you aren't getting unexpected extra WM_PAINTs for some reason.

  • Check that the polygon tesselator Init and End functions aren't doing anything, since they're being called every time, even if there's no tesselating to be done.


Based on the code snippet you have provided, you have (at one point) loops nested four layers deep. You may be seeing high CPU load due to running each of these loops an extremely large number of times. Can you give us any idea how many iterations these loops are having to run through?

Try grabbing a timestamp inside each loop iteration and compare it against the previous to see how long it is taking to run one iteration of each particular loop. This should help you determine what part of the function is taking up the bulk of your CPU time.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜