65.9K
CodeProject 正在变化。 阅读更多。
Home

在DirectX应用程序中,在后台线程中加载耗时的纹理/图像

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.82/5 (4投票s)

2007年7月22日

CPOL

2分钟阅读

viewsIcon

29543

downloadIcon

637

该程序演示了如何在DirectX程序中使用多线程加载纹理等,从而减少程序启动时间。

Screenshot - directX.jpg

引言

该程序演示了如何在后台线程中加载图像/纹理等。程序最初仅加载启动所需的图像。因此,程序将加载更快,并且在程序执行时,后台线程将继续加载剩余的图像。

背景

该程序源于尝试使用DirectX加载和显示纹理到立方体。我遇到的问题是程序在启动时需要一些时间来加载所有纹理(因为程序仅在加载完所有纹理后才开始显示立方体)。为了解决这个问题,现在程序只会加载第一组纹理,一旦完成,就会启动一个线程来加载剩余的纹理。由于线程在后台执行,主程序开始运行并显示第一组纹理,从而大大减少了程序启动时间。

Using the Code

该程序的所有代码都在FormMain.cs中。两个感兴趣的函数是

  • private void LoadTexture()
  • private void ThreadFunction()

函数LoadTexture()在启动时从InitializeDevice()调用。

private void LoadTexture()
{
    Bitmap testImage = null;
    try
    {
        //load the initial set of textures    
            for (int count = 0; count < numberOfFaces; count++)
                {
                    testImage = 
                      (Bitmap)Bitmap.FromFile(@"..\..\textures\sky" + count + ".jpg");
                    texture[0, count] = 
                      Texture.FromBitmap(device, testImage, 0, Pool.Managed);
                }
                Console.WriteLine("skies loaded");

                // we have loaded the first set of textures
                // now the program can start to display the above textures 
                // the rest of the textures will be loaded
                // in a background thread assynchronously... 
                currentTextureLoadingStatus = 1; 

                //start the background thread.
                Thread backgroundLoader = 
                       new Thread(new ThreadStart(ThreadFunction));
                backgroundLoader.Start();
    }
    catch
    {
        MessageBox.Show("Failed loading initial set of textures");
    }
}

在上面的代码中,您会注意到我们首先加载初始纹理集,然后开始启动新线程。

ThreadFunction()将加载剩余的纹理...

private void ThreadFunction()
{
    Bitmap testImage = null;
        int count = 0;

    try
    {
            for (count = 0; count < numberOfFaces; count++)
                {
                    testImage = 
                      (Bitmap)Bitmap.FromFile(@"..\..\textures\sphere" + count + ".jpg");
                    texture[1, count] = 
                      Texture.FromBitmap(device, testImage, 0, Pool.Managed);
                }
                currentTextureLoadingStatus = 2;
                Console.WriteLine("spheres loaded");

        //Similarly load the remaining Texture sets...
        //...

    }
    catch (Exception ex)
    {
        Console.WriteLine("Error Error ! ");
    }
}

运行程序

要切换到不同的纹理集,请在键盘上按空格键。因此,每次您按下空格键时,如果后台线程已经加载了下一个纹理集,程序将转到下一个纹理集。如果后台线程尚未加载下一个纹理集,程序将继续显示当前纹理集。

关注点

该程序在参考了几个在线教程的情况下编写的,例如

纹理是从以下位置获得的

线程代码是我原创的 :)

© . All rights reserved.