[英]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. 为该方法提供的数据(包括GetBlockUv
和CubeCoordinates
是静态浮点数组。
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.