0

我真的不知道该怎么办了。我已经让我的应用程序使用 VBO,而我的 cpu 使用率仍然进入 70 年代和 80 年代。我的渲染过程是这样的:

如果形状没有被细分,则设置相机变换,对其进行细分。如果它有 VBO,则创建它的 VBO,使用它。

你会注意到我也有显示列表,如果不支持 VBO,我可能会使用这些。我去找了一个 OpenGL 演示,它可以在我的 PC 上以 60fps 的速度渲染一个 32000 多边形网格,并使用 4% 的 cpu。我正在使用 vbos 以 60fps 的速度渲染大约 10,000 个多边形,并且使用 70-80%。

这是我的渲染过程:

        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_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);

}

为什么我会得到如此高的 CPU 使用率?

4

2 回答 2

0

根据您提供的代码片段,您(在某一时刻)有嵌套四层的循环。由于运行这些循环中的每一个的次数非常多,您可能会看到高 CPU 负载。你能告诉我们这些循环必须经过多少次迭代吗?

尝试在每个循环迭代中获取时间戳,并将其与前一个进行比较,以查看运行每个特定循环的一次迭代需要多长时间。这应该可以帮助您确定函数的哪个部分占用了大部分 CPU 时间。

于 2010-06-28T16:24:14.173 回答
0

第一段代码在什么条件下运行?里面有几行看起来很可疑:

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

如果您在每次绘画时都删除并重新创建纹理,那可能会变得昂贵。我不能说 OpenGL 部分会有多昂贵——我希望上传纹理数据相当有效,即使删除和创建纹理名称可能不那么有效——但可能CreateGradient天生就很慢。或者,也许您不小心为您的显卡遇到了某种缓慢的路径。或者该函数正在创建所有 mipmap 级别。等等。

除此之外,一些随机的想法:

  • 现在的间隔是多少?如果缓冲区交换设置为与监视器同步,您可能会因此而产生延迟。(您可以使用 WGL_EXT_swap_control 扩展来调整此值。)

  • 如果所有这些都是为了响应 WM_PAINT 而运行的,请检查您是否由于某种原因没有收到意外的额外 WM_PAINT。

  • 检查多边形镶嵌器InitEnd函数是否没有做任何事情,因为它们每次都被调用,即使没有要进行镶嵌。

于 2010-06-28T16:49:52.173 回答