Dinamik UI çalışmaları

Kaptan Yosun

Co-Co Admin
Moderatör
Geliştirici
Yardımsever Üye
Usta Üye
Mesaj
1.440
Çözümler
53
Beğeni
2.267
Puan
1.839
Ticaret Puanı
0
Yeni bir UI dizayn paketi satın aldım, hobi olarak Metin2'ye uyarlamak istedim. Uyarlarken fark ettim ki Metin2'nin arayüz elementlerinin hiç biri dinamik boyutlandırılmıyor. 4k monitör de kullansanız envanterin uzunluğu 560pixel, 480p monitör de kullansanız envanter uzunluğu 560pixel.

Demek istediğim bu:
1080p.webp
720p.webp


Yani 4k monitörde oyunu açsanız envanter karınca duası gibi kalacak.

Ben çalışmaya introselect ve introcreate'ten başladım. Şimdilik yapabildiğim doğru hesap formülünü bulup (Tabiki de yapay zekayla) karakteri bütün çözünürlüklerde ekranın aynı noktasına yerleştirmek ve karakterin göreceli ebatlarının farklı çözünürlüklerde ekrana nazaran aynı oran-orantıda olmasını sağlamak.

introselect_scaling.webp


Arkadaki pencere 1080p, öndeki ufak olan ise 720p, dikkat ederseniz iki savaşçının da ayakları dikdörtgen içindeki şerit desenin ortasına basıyor, ve iki savaşçının da boyu arkadaki dağın azacık altına kadar geliyor.

Ayrıca sağ-sol rotasyon butonlarının aralığı da sabit değil, çözünürlüğünüze göre daralıp açılıyor.

Ne dediğimi tam anlamadıysanız pencere modunda biri 1080p biri 720p oyun açın ve introselect ekranına gelin. Çözünürlüğünüz farketmezsizin rotasyon butonlarınız arasında aynı sayıda pixel konulmuş olacak, bu 1080p oyundaki butonları birbirine yakın, 720p ekrandakileri birbirine uzak gibi gösterecek. Ayrıca karakterleriniz iki ekranda da aynı pixel uzunluğunda olacağı için 1080p ekranda görece ufak, 720p ekranda görece devasa görünecekler.

Umarım derdimi ve hedefimi iyice açıklayabilmişimdir.
 
Windows'un otomatik ölçeklendirmesi Metin2'ye de uyarlanıyor ancak bu sefer texturelerın netliği bozuluyordu. Binalar, karakterlerin zırhları sanki bulanık gibi gözüküyordu. %100 yapınca da textureler netleşiyor ancak ui ve yazıların ufak kalma sorunu oluyordu. Bu çok güzel bi çalışma. Eğer her şey düzgün olursa win tarafındaki ölçeklendirmeyi varsayılan olarak devredışı bıraktırabilirsin
 
Çalışmalarında başarılar dilerim öncelikle hatırlatmak isterim pencere büyüyebilir fakat örneğin karakterin item penceresi büyüse bile orada bir dds kullanıldığı için dds boyutu sabit ama pencere büyüyecektir ve ya envanter içinde öyle. ama diğer pencereler için dinamik yapı oluşturulabilir. Bunun için PythonWindow.h dosyasında uiscripte style olarak kullandığımız flaglar var oraya scale gibi bir flag oluşturup ekran çözünürlüğüne göre font boyutuna göre değişmesini sağlayabilirsin
 
Çalışmalarında başarılar dilerim öncelikle hatırlatmak isterim pencere büyüyebilir fakat örneğin karakterin item penceresi büyüse bile orada bir dds kullanıldığı için dds boyutu sabit ama pencere büyüyecektir ve ya envanter içinde öyle. ama diğer pencereler için dinamik yapı oluşturulabilir. Bunun için PythonWindow.h dosyasında uiscripte style olarak kullandığımız flaglar var oraya scale gibi bir flag oluşturup ekran çözünürlüğüne göre font boyutuna göre değişmesini sağlayabilirsin
Evet henüz resimleri nasıl scale edebilirim bilmiyorum, senin fikir mantıklı. Oyunun resim scale edebilme yeteneği var mı emin değilim ama. Mesela login ekranındaki arkaplan resmi scale olabiliyor, aynı şey acaba oyun içi UI elementleri için de uygulanabilir mi
 
metin2 tarihi boyunca yapılmış/yapılmaya çalışılan en boş çalışma ilan ediyorum
 
Evet henüz resimleri nasıl scale edebilirim bilmiyorum, senin fikir mantıklı. Oyunun resim scale edebilme yeteneği var mı emin değilim ama. Mesela login ekranındaki arkaplan resmi scale olabiliyor, aynı şey acaba oyun içi UI elementleri için de uygulanabilir mi
Asıl sorun şu bir çok görüntü metin2de dds formatında. bir resim scale edilebilir mi dds halindeyken bilmiyorum. metin2nin oyun motoruna bu özellik kazandırılabilir mi emin değilim

Bir fikrim var. Eğer metin2deki bütün gridleri pencerelerideki görüntü dosyalarını eğer svg formatında hazırlayabilirsen costüm ekranı envanter ekranı karakter info ekranları minimap vs hepsini svg formatını hazırlayabilirsen. Görüntü bozulmadan rahatça scale edebilirsin ekran boyutlarına göre
 
Client Src'de SetScale metodu zaten varmış, doğru matematik hesaplarıyla loading bar'ı scale etmeyi başardım.
UiScriptte kullanmak için "x_scale" ve "y_scale" parametrelerine doğru hesaplamayı vermeniz gerek:

Python:
Genişlet Daralt Kopyala
        if True == value.has_key("x_scale") and True == value.has_key("y_scale"):
            window.SetScale(float(value["x_scale"]), float(value["y_scale"]))

1749325309453.webp
 
Biraz zaman geçti aradan, sıkıntıdan geri bakayım dedim. Biraz uğraşıp oyunun ekran yüksekliğine göre scale olan font yaptım. Mesela Loading... textini Tahoma:24 olarak belirlersem 1080p'de düzgün görünüyor ama 720p'de büyük kalıyordu. Şimdi 720p'de otomatik fontu küçültüyor.

1765386816920.webp
 
Biraz zaman geçti aradan, sıkıntıdan geri bakayım dedim. Biraz uğraşıp oyunun ekran yüksekliğine göre scale olan font yaptım. Mesela Loading... textini Tahoma:24 olarak belirlersem 1080p'de düzgün görünüyor ama 720p'de büyük kalıyordu. Şimdi 720p'de otomatik fontu küçültüyor.

27432 eklentisini görüntüle
çiğköfte dürüm ısmarlayana nasıl yaptığını paylaşırım
 
referans belirlesen nasıl olurdu ?

sadece örnek ;

ui_scale = current_height / reference_height

reference_width = 1920
reference_height = 1080

kamerada ise ters orantı uygulanabilir belki ?


Biraz zaman geçti aradan, sıkıntıdan geri bakayım dedim. Biraz uğraşıp oyunun ekran yüksekliğine göre scale olan font yaptım. Mesela Loading... textini Tahoma:24 olarak belirlersem 1080p'de düzgün görünüyor ama 720p'de büyük kalıyordu. Şimdi 720p'de otomatik fontu küçültüyor.
burada ise bilmiyorum hiç denemedim ama kök oran kullanılabilir yani ui scaleden bağımsız font scale


buralarda değişiklik gerekiyor

GrpBase.cpp:
Genişlet Daralt Kopyala
oid CGraphicBase::SetOrtho2D(float hres, float vres, float zres)
{
    //CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_ORTHO_CAMERA);
    D3DXMatrixOrthoOffCenterRH(&ms_matProj, 0, hres, vres, 0, 0, zres);
    //UpdatePipeLineMatrix();
    UpdateProjMatrix();

void CGraphicBase::SetPerspective(float fov, float aspect, float nearz, float farz)
{
    ms_fFieldOfView = fov;

    //if (ms_d3dPresentParameter.BackBufferWidth>0 && ms_d3dPresentParameter.BackBufferHeight>0)
    //  ms_fAspect = float(ms_d3dPresentParameter.BackBufferWidth)/float(ms_d3dPresentParameter.BackBufferHeight);
    //else
    ms_fAspect = aspect;
    ms_fNearY = nearz;
    ms_fFarY = farz;
    //CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA);
    D3DXMatrixPerspectiveFovRH(&ms_matProj, D3DXToRadian(fov), ms_fAspect, nearz, farz);
    //UpdatePipeLineMatrix();
    UpdateProjMatrix();


}




Pythongraphic.cpp:
Genişlet Daralt Kopyala
void CPythonGraphic::SetInterfaceRenderState() const
{
    STATEMANAGER.SetTransform(D3DTS_PROJECTION, &ms_matIdentity);
    STATEMANAGER.SetTransform(D3DTS_VIEW, &ms_matIdentity);
    STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity);

    STATEMANAGER.SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_NONE);
    STATEMANAGER.SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_NONE);
    STATEMANAGER.SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);

    STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

    Instance().SetBlendOperation();
    Instance().SetOrtho2D(ms_iWidth, ms_iHeight, GetOrthoDepth());

    STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
}




GrpDevice.cpp:
Genişlet Daralt Kopyala
int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /*iBit*/, int iReflashRate)
{
    int iRet = CREATE_OK;

    Destroy();

    ms_iWidth = iHres;
    ms_iHeight = iVres;

    ms_hWnd = hWnd;
    ms_hDC = GetDC(hWnd);
    ms_lpd3d = Direct3DCreate9(D3D_SDK_VERSION);

    if (!ms_lpd3d)
        return CREATE_NO_DIRECTX;

    if (!ms_kD3DDetector.Build(*ms_lpd3d, EL3D_ConfirmDevice))
        return CREATE_ENUM;

#ifdef ENABLE_D3D_DETECTION
    if (!ms_kD3DDetector.Find(800, 600, 32, TRUE, &ms_iD3DModeInfo, &ms_iD3DDevInfo, &ms_iD3DAdapterInfo))
        if (!ms_kD3DDetector.Find(iHres, iVres, 32, TRUE, &ms_iD3DModeInfo, &ms_iD3DDevInfo, &ms_iD3DAdapterInfo))
            return CREATE_DETECT;
#endif


Edit : PythonWindowManager.cpp de getscalefactor fonksiyonu içine de eklemeler yapmak lazım sanırım
 
referans belirlesen nasıl olurdu ?

sadece örnek ;

ui_scale = current_height / reference_height

reference_width = 1920
reference_height = 1080

kamerada ise ters orantı uygulanabilir belki ?



burada ise bilmiyorum hiç denemedim ama kök oran kullanılabilir yani ui scaleden bağımsız font scale


buralarda değişiklik gerekiyor

GrpBase.cpp:
Genişlet Daralt Kopyala
oid CGraphicBase::SetOrtho2D(float hres, float vres, float zres)
{
    //CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_ORTHO_CAMERA);
    D3DXMatrixOrthoOffCenterRH(&ms_matProj, 0, hres, vres, 0, 0, zres);
    //UpdatePipeLineMatrix();
    UpdateProjMatrix();

void CGraphicBase::SetPerspective(float fov, float aspect, float nearz, float farz)
{
    ms_fFieldOfView = fov;

    //if (ms_d3dPresentParameter.BackBufferWidth>0 && ms_d3dPresentParameter.BackBufferHeight>0)
    //  ms_fAspect = float(ms_d3dPresentParameter.BackBufferWidth)/float(ms_d3dPresentParameter.BackBufferHeight);
    //else
    ms_fAspect = aspect;
    ms_fNearY = nearz;
    ms_fFarY = farz;
    //CCameraManager::Instance().SetCurrentCamera(CCameraManager::DEFAULT_PERSPECTIVE_CAMERA);
    D3DXMatrixPerspectiveFovRH(&ms_matProj, D3DXToRadian(fov), ms_fAspect, nearz, farz);
    //UpdatePipeLineMatrix();
    UpdateProjMatrix();


}




Pythongraphic.cpp:
Genişlet Daralt Kopyala
void CPythonGraphic::SetInterfaceRenderState() const
{
    STATEMANAGER.SetTransform(D3DTS_PROJECTION, &ms_matIdentity);
    STATEMANAGER.SetTransform(D3DTS_VIEW, &ms_matIdentity);
    STATEMANAGER.SetTransform(D3DTS_WORLD, &ms_matIdentity);

    STATEMANAGER.SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_NONE);
    STATEMANAGER.SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_NONE);
    STATEMANAGER.SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);

    STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

    Instance().SetBlendOperation();
    Instance().SetOrtho2D(ms_iWidth, ms_iHeight, GetOrthoDepth());

    STATEMANAGER.SetRenderState(D3DRS_LIGHTING, FALSE);
}




GrpDevice.cpp:
Genişlet Daralt Kopyala
int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /*iBit*/, int iReflashRate)
{
    int iRet = CREATE_OK;

    Destroy();

    ms_iWidth = iHres;
    ms_iHeight = iVres;

    ms_hWnd = hWnd;
    ms_hDC = GetDC(hWnd);
    ms_lpd3d = Direct3DCreate9(D3D_SDK_VERSION);

    if (!ms_lpd3d)
        return CREATE_NO_DIRECTX;

    if (!ms_kD3DDetector.Build(*ms_lpd3d, EL3D_ConfirmDevice))
        return CREATE_ENUM;

#ifdef ENABLE_D3D_DETECTION
    if (!ms_kD3DDetector.Find(800, 600, 32, TRUE, &ms_iD3DModeInfo, &ms_iD3DDevInfo, &ms_iD3DAdapterInfo))
        if (!ms_kD3DDetector.Find(iHres, iVres, 32, TRUE, &ms_iD3DModeInfo, &ms_iD3DDevInfo, &ms_iD3DAdapterInfo))
            return CREATE_DETECT;
#endif


Edit : PythonWindowManager.cpp de getscalefactor fonksiyonu içine de eklemeler yapmak lazım sanırım
Zaten çoğu hesabı referansa göre yapıyorum dediğin gibi


Python:
Genişlet Daralt Kopyala
UI_BASE_WIDTH = 1920
UI_BASE_HEIGHT = 1080
Python:
Genişlet Daralt Kopyala
from ui import UI_BASE_WIDTH, UI_BASE_HEIGHT

X_SCALE = float(SCREEN_WIDTH) / UI_BASE_WIDTH
Y_SCALE = float(SCREEN_HEIGHT) / UI_BASE_HEIGHT
Python:
Genişlet Daralt Kopyala
                {
                    "name" : "FullGage",
                    "type" : "expanded_image",

                    "x" : ((LOADING_BAR_EMPTY_FRAME_WIDTH - LOADING_BAR_FILL_WIDTH) / 2.0) * (X_SCALE),
                    "y" : ((LOADING_BAR_EMPTY_FRAME_HEIGHT - LOADING_BAR_FILL_HEIGHT) / 2.0) * (Y_SCALE),

                    "image" : "d:/ymir work/uiloading/loading_bar_fill.png",

                    "x_scale": X_SCALE,
                    "y_scale": Y_SCALE,
                },

Gibi
 
Zaten çoğu hesabı referansa göre yapıyorum dediğin gibi


Python:
Genişlet Daralt Kopyala
UI_BASE_WIDTH = 1920
UI_BASE_HEIGHT = 1080
Python:
Genişlet Daralt Kopyala
from ui import UI_BASE_WIDTH, UI_BASE_HEIGHT

X_SCALE = float(SCREEN_WIDTH) / UI_BASE_WIDTH
Y_SCALE = float(SCREEN_HEIGHT) / UI_BASE_HEIGHT
Python:
Genişlet Daralt Kopyala
                {
                    "name" : "FullGage",
                    "type" : "expanded_image",

                    "x" : ((LOADING_BAR_EMPTY_FRAME_WIDTH - LOADING_BAR_FILL_WIDTH) / 2.0) * (X_SCALE),
                    "y" : ((LOADING_BAR_EMPTY_FRAME_HEIGHT - LOADING_BAR_FILL_HEIGHT) / 2.0) * (Y_SCALE),

                    "image" : "d:/ymir work/uiloading/loading_bar_fill.png",

                    "x_scale": X_SCALE,
                    "y_scale": Y_SCALE,
                },

Gibi


c++ da da ayni mantığı uyarlamak lazım ( SetOrtho2D ) karakterler için ise ; SetPerspective

yani c++ tarafında aynı referans çözünürlüğü kullanarak scale factor hesaplamak
 
c++ da da ayni mantığı uyarlamak lazım ( SetOrtho2D ) karakterler için ise ; SetPerspective

yani c++ tarafında aynı referans çözünürlüğü kullanarak scale factor hesaplamak
Ben onu da Python tarafinda yaptım, belki c++ tarafından daha mantıklı olabilir tabi.
 
Ben onu da Python tarafinda yaptım, belki c++ tarafından daha mantıklı olabilir tabi.
sadece python yeterli değil , ui için;
Instance().SetOrtho2D(ms_iWidth, ms_iHeight, GetOrthoDepth()); bu satır c++ tarafında çağriliyo matrixi ayarlıyo yani uyumsuzluk olabilir

karakterler için ise aspect ratio çözünülüğüne göre ayarlanmalı.
 
Geri
Üst