回転ブロックを表示できる SharpGL チュートリアルに従いました。当初、これには で描画されたデフォルトの色しかありませんでしたgl.Color(r, g, b)
。これが成功した後、UV マップでキューブをテクスチャリングしようとしました。
立方体を色付けするだけでアプリケーションをフルスクリーンで実行すると (sharpGL コンポーネントがアプリケーションの内部全体をカバーします)、色付けされた立方体を表示する場合にのみ 70 ~ 80 fps が得られます。OpenGL.GL_TEXTURE_2D
単一の立方体でテクスチャを有効にして描画すると、8 ~ 9 fps になります。
テクスチャとして使用するためにビットマップがロードされるたびに、ビットマップはメモリに保存されます。このフレームレートの低下は、すべての座標を有効に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 アーキテクチャを引き続き使用したいと考えていますが、WPF 内の openGL がよりギミックとして意図されている場合、それは最善の方法ではない可能性があります。