简体   繁体   English

WPF中SharpGL的性能不佳

[英]Bad Performance of sharpGL inside WPF

I have followed a SharpGL tutorial that can display a rotating block. 我遵循了可以显示旋转块的SharpGL教程。 Initially this only had default colors drawn on it with gl.Color(r, g, b) . 最初,仅使用gl.Color(r, g, b)在其上绘制默认颜色。 After this succeeded I tried to texture the cube with an uv map. 成功之后,我尝试使用uv贴图对多维数据集进行纹理处理。

When I run the application fullscreen while only coloring the cube (with the sharpGL component covering the entire inside of the application) I get 70~80 fps only for displaying a colored cube. 当我全屏运行应用程序时,仅对多维数据集着色(sharpGL组件覆盖了应用程序的整个内部)时,我只能以70〜80 fps的速度显示彩色多维数据集。 When I enable OpenGL.GL_TEXTURE_2D and draw the textures on a singular cube I get 8~9 fps. 当我启用OpenGL.GL_TEXTURE_2D并在单个立方体上绘制纹理时,我得到OpenGL.GL_TEXTURE_2D fps。

Whenever a bitmap is loaded for use as a texture, it is stored in the memory. 每当加载位图以用作纹理时,它就会存储在内存中。 This drop in framerates only occurs after I enable OpenGL.GL_TEXTURE_2D and call gl.TexCoord(c1, c2) for all coordinates. 仅当启用OpenGL.GL_TEXTURE_2D并为所有坐标调用gl.TexCoord(c1, c2)后,才会发生帧速率下降。 Actually moving the object with gl.Rotate(angle, x, y, z) does not noticably affect performance. 实际上使用gl.Rotate(angle, x, y, z)移动对象不会显着影响性能。

The provided data for the method including GetBlockUv and CubeCoordinates are static float-arrays. 为该方法提供的数据(包括GetBlockUvCubeCoordinates是静态浮点数组。

Is SharpGL supposed to perform this poorly (ie on displaying a singular cube) or is there another reason? 是SharpGL应该执行得很差(即显示单个立方体时)还是有其他原因? Am I doing something wrong that is affecting performance? 我做错了什么会影响性能吗? Is applying textures supposed to affect the performance like that? 是否应用纹理会像那样影响性能?

The main draw Event happens in a Block: 主抽奖事件发生在一个区块中:

public void DrawBlock(object sender, OpenGLEventArgs args)
    {
        //  Get the OpenGL instance that's been passed to us.
        OpenGL gl = args.OpenGL;

        //  Reset the modelview.
        gl.LoadIdentity();

        //  Move the block to its location
        gl.Translate(Coord.X, Coord.Y, Coord.Z);

        gl.Rotate(angle, 1.0f, 1.0f, 0.5f);
        angle += 3;

        // retrieve the right texture for this block and bind it. 
        Texture blockTex = BlockTexture.GetBlockTexture(gl, _type);
        blockTex.Bind(gl);

        // retrieve the uv map for this block
        float[] uv = BlockTexture.GetBlockUv(_type);

        // retrieve the coordinates for a cube
        float[] cube = CubeCoordinates();


        gl.Enable(OpenGL.GL_TEXTURE_2D);

        //  Draw the cube with the bound texture. 
        gl.Begin(OpenGL.GL_QUADS);
        //
        //
        // Begin by allowing all colors. 
        gl.Color(1.0f, 1.0f, 1.0f);

        // since the uv index increments with 2 each time, we will be keeping track of this separately. 
        int uvInd = 0;

        // i denotes the current coordinate. Each coordinate consists of 3 
        // values (x, y, z), thus letting us skip 3. 
        //
        // Seeing as we are creating quads, it is expected that cube.Length 
        // is 3 * 4 * N (where n is a whole number)
        for (int i = 0; i < cube.Length; i += 3)
        {
            // color experiment
            //if (i < cube.Length / 3)
            //{
            //    gl.Color(1.0f, 0.00f, 0.00f);
            //}
            //else if (i < 2 * (cube.Length / 3))
            //{
            //    gl.Color(0.0f, 1.0f, 0.0f);
            //}
            //else
            //{
            //    gl.Color(0.0f, 0.0f, 1.0f);
            //}

            try
            {
                // set the coordinate for the texture
                gl.TexCoord(uv[uvInd], uv[uvInd + 1]);

                // set the vertex
                gl.Vertex(cube[i], cube[i + 1], cube[i + 2]);
            }
            catch (IndexOutOfRangeException e)
            {
                throw new IndexOutOfRangeException(
                    "This exception is thrown because the cube map and uv map do not match size");
            }

            // increment the uv index
            uvInd += 2;
        }

        gl.End();
        gl.Disable(OpenGL.GL_TEXTURE_2D);
    }

OpenGL is initialized elsewhere OpenGL在其他地方初始化

 private void OpenGLControl_OpenGLDraw(object sender, OpenGLEventArgs args)
    {
        //  Get the OpenGL instance that's been passed to us.
        OpenGL gl = args.OpenGL;

        //  Clear the color and depth buffers.
        gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);


        // call the draw method of the GameRunner if the 
        // GameRunner has already been created. 
        game?.DrawOpenGL(sender, args);


        //  Flush OpenGL.
        gl.Flush();
    }

    private void OpenGLControl_OpenGLInitialized(object sender, OpenGLEventArgs args)
    {
        //  Enable the OpenGL depth testing functionality.
        args.OpenGL.Enable(OpenGL.GL_DEPTH_TEST);
    }

All the intermediate GameRunner does right now is call the DrawBlock routine. 中间的GameRunner现在所做的所有GameRunner就是调用DrawBlock例程。

What I mainly would want to know is some insight into the performance I can expect of openGL / sharpGL and whether there are better alternatives. 我主要想了解的是我对openGL / sharpGL可以期望的性能的了解,以及是否有更好的选择。 I would like to keep using the WPF architecture surrounding the game, but if openGL inside WPF is more meant as a gimmick, that might not be the best course of action. 我想继续使用围绕游戏的WPF架构,但是如果WPF中的openGL更像是个gi头,那可能不是最好的选择。

I've been having the exact same issue, and it seems to be the case that either SharpGL or the WPF control itself are using software rendering. 我遇到了完全相同的问题,似乎SharpSharp或WPF控件本身都在使用软件渲染。 I tested this by disabling my main display adapter in Device Manager and got the exact same performance as I did with it enabled. 我通过在设备管理器中禁用主显示适配器进行了测试,并获得了与启用它完全相同的性能。

I don't know how to enable hardware acceleration though, so I don't actually know how to fix the issue. 不过,我不知道如何启用硬件加速,因此我实际上不知道如何解决该问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM