diff --git a/src/gx/d3d/CGxDeviceD3d.cpp b/src/gx/d3d/CGxDeviceD3d.cpp index 97d22c4..5d1c939 100644 --- a/src/gx/d3d/CGxDeviceD3d.cpp +++ b/src/gx/d3d/CGxDeviceD3d.cpp @@ -1,6 +1,16 @@ #include "gx/d3d/CGxDeviceD3d.hpp" #include "gx/texture/CGxTex.hpp" +D3DTEXTUREFILTERTYPE CGxDeviceD3d::s_filterModes[GxTexFilters_Last][3] = { + // Min, Mag, Mip + { D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_NONE }, // GxTex_Nearest + { D3DTEXF_LINEAR, D3DTEXF_LINEAR, D3DTEXF_NONE }, // GxTex_Linear + { D3DTEXF_POINT, D3DTEXF_POINT, D3DTEXF_POINT }, // GxTex_NearestMipNearest + { D3DTEXF_LINEAR, D3DTEXF_LINEAR, D3DTEXF_POINT }, // GxTex_LinearMipNearest + { D3DTEXF_LINEAR, D3DTEXF_LINEAR, D3DTEXF_LINEAR }, // GxTex_LinearMipLinear + { D3DTEXF_LINEAR, D3DTEXF_LINEAR, D3DTEXF_LINEAR }, // GxTex_Anisotropic +}; + D3DFORMAT CGxDeviceD3d::s_GxFormatToD3dFormat[] = { D3DFMT_R5G6B5, // Fmt_Rgb565 D3DFMT_X8R8G8B8, // Fmt_ArgbX888 @@ -60,6 +70,11 @@ EGxTexFormat CGxDeviceD3d::s_tolerableTexFmtMapping[] = { GxTex_D24X8, // GxTex_D24X8 }; +D3DTEXTUREADDRESS CGxDeviceD3d::s_wrapModes[] = { + D3DTADDRESS_CLAMP, // GxTex_Clamp + D3DTADDRESS_WRAP, // GxTex_Wrap +}; + ATOM WindowClassCreate() { auto instance = GetModuleHandle(nullptr); @@ -305,6 +320,10 @@ void CGxDeviceD3d::DeviceWM(EGxWM wm, uintptr_t param1, uintptr_t param2) { // TODO } +void CGxDeviceD3d::DsSet(EDeviceState state, uint32_t val) { + // TODO +} + int32_t CGxDeviceD3d::ICreateD3d() { if (CGxDeviceD3d::ILoadD3dLib(this->m_d3dLib, this->m_d3d) && SUCCEEDED(this->m_d3d->GetDeviceCaps(0, D3DDEVTYPE_HAL, &this->m_d3dCaps))) { if (this->m_desktopDisplayMode.Format != D3DFMT_UNKNOWN) { @@ -411,8 +430,38 @@ void CGxDeviceD3d::IDestroyD3dDevice() { // TODO } -void CGxDeviceD3d::IRsSendToHw(EGxRenderState rs) { - // TODO +void CGxDeviceD3d::IRsSendToHw(EGxRenderState which) { + auto state = &this->m_appRenderStates[which]; + + switch (which) { + // TODO handle all render states + + case GxRs_Texture0: + case GxRs_Texture1: + case GxRs_Texture2: + case GxRs_Texture3: + case GxRs_Texture4: + case GxRs_Texture5: + case GxRs_Texture6: + case GxRs_Texture7: + case GxRs_Texture8: + case GxRs_Texture9: + case GxRs_Texture10: + case GxRs_Texture11: + case GxRs_Texture12: + case GxRs_Texture13: + case GxRs_Texture14: + case GxRs_Texture15: { + uint32_t tmu = which - GxRs_Texture0; + auto texture = static_cast(static_cast(state->m_value)); + this->ISetTexture(tmu, texture); + + break; + } + + default: + break; + } } void CGxDeviceD3d::ISetPresentParms(D3DPRESENT_PARAMETERS& d3dpp, const CGxFormat& format) { @@ -481,6 +530,40 @@ void CGxDeviceD3d::ISetPresentParms(D3DPRESENT_PARAMETERS& d3dpp, const CGxForma } } +void CGxDeviceD3d::ISetTexture(uint32_t tmu, CGxTex* texId) { + if (tmu > 15) { + return; + } + + if (texId) { + this->ITexMarkAsUpdated(texId); + this->m_d3dDevice->SetTexture(tmu, static_cast(texId->m_apiSpecificData)); + + // Texture filters + auto& filters = CGxDeviceD3d::s_filterModes[texId->m_flags.m_filter]; + this->DsSet(static_cast(Ds_TssMinFilter0 + tmu), filters[0]); + this->DsSet(static_cast(Ds_TssMagFilter0 + tmu), filters[1]); + this->DsSet(static_cast(Ds_TssMipFilter0 + tmu), filters[2]); + + // Texture addressing + this->DsSet(static_cast(Ds_TssWrapU0 + tmu), CGxDeviceD3d::s_wrapModes[texId->m_flags.m_wrapU]); + this->DsSet(static_cast(Ds_TssWrapV0 + tmu), CGxDeviceD3d::s_wrapModes[texId->m_flags.m_wrapV]); + + // Max anisotropy + this->DsSet(static_cast(Ds_TssMaxAnisotropy0 + tmu), texId->m_flags.m_maxAnisotropy); + + if (tmu < 8) { + // TODO FFP + } + } else { + this->m_d3dDevice->SetTexture(tmu, nullptr); + + if (tmu < 8) { + // TODO FFP + } + } +} + void CGxDeviceD3d::IShaderCreate(CGxShader* shader) { // TODO } diff --git a/src/gx/d3d/CGxDeviceD3d.hpp b/src/gx/d3d/CGxDeviceD3d.hpp index 322f4b6..cb20905 100644 --- a/src/gx/d3d/CGxDeviceD3d.hpp +++ b/src/gx/d3d/CGxDeviceD3d.hpp @@ -196,10 +196,12 @@ class CGxDeviceD3d : public CGxDevice { }; // Static variables + static D3DTEXTUREFILTERTYPE s_filterModes[GxTexFilters_Last][3]; static D3DFORMAT s_GxFormatToD3dFormat[]; static D3DFORMAT s_GxTexFmtToD3dFmt[]; static EGxTexFormat s_GxTexFmtToUse[]; static EGxTexFormat s_tolerableTexFmtMapping[]; + static D3DTEXTUREADDRESS s_wrapModes[]; // Static functions static int32_t ILoadD3dLib(HINSTANCE& d3dLib, LPDIRECT3D9& d3d); @@ -220,7 +222,7 @@ class CGxDeviceD3d : public CGxDevice { // Virtual member functions virtual void ITexMarkAsUpdated(CGxTex* texId); - virtual void IRsSendToHw(EGxRenderState rs); + virtual void IRsSendToHw(EGxRenderState which); virtual int32_t DeviceCreate(long (*windowProc)(void*, uint32_t, uint32_t, long), const CGxFormat& format); virtual int32_t DeviceSetFormat(const CGxFormat& format); virtual void DeviceWM(EGxWM wm, uintptr_t param1, uintptr_t param2); @@ -232,12 +234,14 @@ class CGxDeviceD3d : public CGxDevice { // Member functions CGxDeviceD3d(); + void DsSet(EDeviceState state, uint32_t val); int32_t ICreateD3d(); int32_t ICreateD3dDevice(const CGxFormat& format); bool ICreateWindow(CGxFormat& format); void ISetPresentParms(D3DPRESENT_PARAMETERS& d3dpp, const CGxFormat& format); void IDestroyD3d(); void IDestroyD3dDevice(); + void ISetTexture(uint32_t tmu, CGxTex* texId); void ITexCreate(CGxTex* texId); void ITexUpload(CGxTex* texId); };