Bagaimana saya berhenti melakukan peregangan saat ukuran jendela kembali di XNA?


8

Dalam mode XNA permainan berjendela ketika pengguna mengubah ukuran jendela, game berhenti memperbarui jendela dan bingkai terakhir yang ditarik ditarik dan didistorsi hingga pengguna melepaskan mouse dan ukurannya selesai.

Apakah ada cara agar permainan terus berjalan "normal", memperbarui bingkai dan menggambar ulang layar, selama acara pengubahan ukuran?

Saya menyadari bahwa menjaga agar render tetap berjalan saat mengubah ukuran mungkin tidak dapat atau tidak disarankan karena sumber daya yang dikelola perangkat keras terus-menerus dibuat dan dihancurkan, tetapi apakah ada cara untuk menghentikan peregangan yang jelek? Idealnya dengan membiarkan bingkai yang ada tidak dikunci di kiri atas, atau dengan layar hitam jika itu tidak memungkinkan.


Daftarkan acara untuk mengubah ukuran jendela dan perbarui resolusi GraphicsDevice. Ini dapat memperbarui rasio aspek dan memperbaiki peregangan.
Gustavo Maciel

Saya tidak tahu tentang C # / XNA, tetapi di C ++ / D3D saya baru saja menjalankan render di thread terpisah dari utas utama dengan loop pesan. Utas utama melakukan ukuran buffer ketika peristiwa ukuran terjadi, disinkronkan melalui mutex.

1
Gustavo, saya sudah menangani acara itu untuk tujuan lain dalam permainan. Sayangnya itu tidak menyala sampai setelah pengguna melepaskan mouse ketika ukuran ulang selesai.
Bradley Uffner

Pasangan pertanyaan / jawaban ini mungkin bermanfaat. Ini memberi tahu Anda cara melanjutkan rendering (meskipun tidak memperbaiki peregangan).
Andrew Russell

Jawaban:


3

Setidaknya ada 3 pesan yang bisa Anda lacak.

  • WM_SIZE- pengubahan ukuran jendela, mini / maksimalisasi, pengalihan layar penuh / berjendela. Anda harus membaca wParam untuk mengetahui apa yang sebenarnya terjadi dan untuk lParam untuk ukuran saat ini.
  • WM_ENTERSIZEMOVE - Mulai mengubah ukuran jendela dalam mode berjendela
  • WM_EXITSIZEMOVE - Mengubah ukuran jendela akhir dalam mode berjendela

Biasanya Anda tidak ingin mengubah ukuran aplikasi setiap frame antara WM_ENTERSIZEMOVE dan WM_EXITSIZEMOVE karena terlalu sloow dan jelek. Tapi cobalah, ini jelas bukan peregangan, mungkin Anda akan menyukainya =)

case WM_SIZE:
    // Save the new client area dimensions.
    m_ptViewportSize.x  = LOWORD(lParam);
    m_ptViewportSize.y = HIWORD(lParam);
    if( wParam == SIZE_MINIMIZED )
    {
        m_bAppSuspended = true;
        m_bMinimized = true;
        m_bMaximized = false;
    }
    else if( wParam == SIZE_MAXIMIZED )
    {
        m_bAppSuspended = false;
        m_bMinimized = false;
        m_bMaximized = true;
        OnResize();
    }
    else if( wParam == SIZE_RESTORED )
    {
        // Restoring from minimized state
        if( m_bMinimized )
        {
            m_bAppSuspended = false;
            m_bMinimized = false;
            OnResize();
        }
        // Restoring from maximized state
        else if( m_bMaximized )
        {
            m_bAppSuspended = false;
            m_bMaximized = false;
            OnResize();
        }
        else if( m_bResizing )
        {
            // Resizing in processs
            // You woldn't wanto to handle a massive stream of
            // WM_SIZE here because buffers resizing is very slow
        }
        else
        {
            // Resizing finished and you can handle it. For ex. with 
            // m_SwapChain->SetFullscreenState
            OnResize();
        }

    }
    return 0;

// WM_EXITSIZEMOVE is sent when the user grabs the resize bars.
case WM_ENTERSIZEMOVE:
    m_bAppSuspended = true;
    m_bResizing  = true;
    g_pTimer->Stop();
    return 0;
// WM_EXITSIZEMOVE is sent when the user releases the resize bars.
// Here we reset everything based on the new window dimensions.
case WM_EXITSIZEMOVE:
    m_bAppSuspended = false;
    m_bResizing  = false;
    g_pTimer->Start();
    OnResize();
    return 0;

1
Menangani pesan windows di .NET melibatkan penggantian System.Windows.Forms.Form.WndProc(). Saat bekerja di XNA, Anda tidak memiliki akses langsung ke Formuntuk menimpa metode itu. Meskipun dimungkinkan untuk dilakukan, ini bukan pekerjaan sepele dan harus menghindari desain XNA.
Cypher

Jika seseorang memilih untuk mengambil jalan ini, daftar konstanta wm_ * ini harus terbukti bermanfaat: pinvoke.net/default.aspx/Constants/WM.html
Cypher

Seperti yang dikatakan orang lain, saya masih membutuhkan cara untuk melakukan hubungan pendek "mesin" XNA dan membuatnya menarik kembali selama acara yang benar. Dari apa yang saya tahu XNA semacam "pergi tidur" selama prosedur mengubah ukuran.
Bradley Uffner
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.