Я следил за учебником SharpGL, который может отображать вращающийся блок. Первоначально у этого были только цвета по умолчанию, нарисованные на нем gl.Color(r, g, b)
. После этого я попытался текстурировать куб с помощью uv-карты.Плохая производительность sharpGL внутри WPF
Когда я запускаю полноэкранный режим приложения, только окрашивая куб (с компонентом sharpGL, покрывающим всю внутреннюю часть приложения), я получаю 70 ~ 80 кадров в секунду только для отображения цветного куба. Когда я включаю OpenGL.GL_TEXTURE_2D
и рисую текстуры на единичном кубе, я получаю 8 ~ 9 кадров в секунду.
Всякий раз, когда растровое изображение загружается для использования в качестве текстуры, оно сохраняется в памяти. Это падение кадров возникает только после включения OpenGL.GL_TEXTURE_2D
и вызова gl.TexCoord(c1, c2)
для всех координат. Фактически перемещение объекта с gl.Rotate(angle, x, y, z)
не оказывает заметного влияния на производительность.
Предоставляемые данные для метода, включая GetBlockUv
и CubeCoordinates
, являются статическими массивами с плавающей запятой.
Предполагается, что SharpGL выполняет это плохо (т. Е. При отображении сингулярного куба), или есть еще одна причина? Я делаю что-то неправильно, что влияет на производительность? Является ли применение текстур, которые могут повлиять на производительность?
Основной розыгрыш событий происходит в блоке:
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 инициализирован в другом месте
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);
}
Все промежуточный GameRunner
делает прямо сейчас называть DrawBlock
рутина.
Что я хотел бы знать, это некоторое понимание производительности, которую я могу ожидать от openGL/sharpGL и есть ли лучшие альтернативы. Я хотел бы продолжать использовать архитектуру WPF, окружающую игру, но если openGL внутри WPF больше понимается как трюк, это может быть не лучший способ действий.
Согласно http://www.dwmkerr.com/sharpgl-2-0-hardware-acceleration/, он должен быть исправлен в SharpGL 2.0 с использованием другого поставщика контекста Render. Я еще не пытался реализовать это, но это объясняет производительность. Спасибо за ваше время, чтобы ответить. – bas