From ec7fe00892abbc4798735ed4a354807fd2d48741 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 7 May 2017 14:05:04 +1000 Subject: [PATCH] Port fog and alpha funcs of d3d9 api to C --- src/Client/Direct3D9Api.c | 123 +++++++++++++++++++++++++++++++++++--- src/Client/ErrorHandler.h | 5 +- src/Client/GraphicsAPI.h | 8 +-- 3 files changed, 123 insertions(+), 13 deletions(-) diff --git a/src/Client/Direct3D9Api.c b/src/Client/Direct3D9Api.c index f44da8084..68f5c06fd 100644 --- a/src/Client/Direct3D9Api.c +++ b/src/Client/Direct3D9Api.c @@ -1,5 +1,6 @@ // Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 #include "GraphicsAPI.h" +#include "ErrorHandler.h" #include #include #include @@ -7,14 +8,122 @@ #define USE_DX true #ifdef USE_DX +IDirect3D9* d3d; +IDirect3DDevice9* device; + +#define D3D9_SetRenderState(raw, state, name) \ +ReturnCode hresult = IDirect3DDevice9_SetRenderState(device, state, raw); \ +ErrorHandler_CheckOrFail(hresult, name) + +#define D3D9_SetRenderState2(raw, state, name) \ +hresult = IDirect3DDevice9_SetRenderState(device, state, raw); \ +ErrorHandler_CheckOrFail(hresult, name) + + void Gfx_Init(Game* game) { } -D3DPRIMITIVETYPE modeMappings[2] = { D3DPT_TRIANGLELIST, D3DPT_LINELIST }; -D3DFORMAT depthFormats[6] = { D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D16, D3DFMT_D15S1 }; -D3DFORMAT viewFormats[4] = { D3DFMT_X8R8G8B8, D3DFMT_R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 }; -D3DBLEND blendFuncs[6] = { D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_DESTALPHA, D3DBLEND_INVDESTALPHA }; -D3DCMPFUNC compareFuncs[8] = { D3DCMP_ALWAYS, D3DCMP_NOTEQUAL, D3DCMP_NEVER, D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_EQUAL, D3DCMP_GREATEREQUAL, D3DCMP_GREATER }; -D3DFOGMODE modes[3] = { D3DFOG_LINEAR, D3DFOG_EXP, D3DFOG_EXP2 }; -Int32 formatMappings[2] = { D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 }; + +bool d3d9_fogEnable = false; +void Gfx_SetFog(bool enabled) { + if (d3d9_fogEnable == enabled) return; + + d3d9_fogEnable = enabled; + D3D9_SetRenderState((UInt32)enabled, D3DRS_FOGENABLE, "D3D9_SetFog"); +} + +UInt32 d3d9_fogCol = 0xFF000000; // black +void Gfx_SetFogColour(FastColour col) { + if (col.Packed == d3d9_fogCol) return; + + d3d9_fogCol = col.Packed; + D3D9_SetRenderState(col.Packed, D3DRS_FOGCOLOR, "D3D9_SetFogColour"); +} + +Real32 d3d9_fogDensity = -1.0f; +void Gfx_SetFogDensity(Real32 value) { + if (value == d3d9_fogDensity) return; + + d3d9_fogDensity = value; + UInt32 raw = *(UInt32*)&value; + D3D9_SetRenderState(raw, D3DRS_FOGDENSITY, "D3D9_SetFogDensity"); +} + +void Gfx_SetFogStart(Real32 value) { + UInt32 raw = *(UInt32*)&value; + D3D9_SetRenderState(raw, D3DRS_FOGSTART, "D3D9_SetFogStart"); +} + +Real32 d3d9_fogEnd = -1.0f; +void Gfx_SetFogEnd(Real32 value) { + if (value == d3d9_fogEnd) return; + + d3d9_fogEnd = value; + UInt32 raw = *(UInt32*)&value; + D3D9_SetRenderState(raw, D3DRS_FOGEND, "D3D9_SetFogEnd"); +} + +D3DFOGMODE fogTableMode = D3DFOG_NONE; +void Gfx_SetFogMode(Int32 fogMode) { + D3DFOGMODE mode = d3d9_modes[fogMode]; + if (mode == fogTableMode) return; + + fogTableMode = mode; + D3D9_SetRenderState(mode, D3DRS_FOGTABLEMODE, "D3D9_SetFogMode"); +} + + +void Gfx_SetFaceCulling(bool enabled) { + D3DCULL mode = enabled ? D3DCULL_CW : D3DCULL_NONE; + D3D9_SetRenderState(mode, D3DRS_CULLMODE, "D3D9_SetFaceCulling"); +} + +bool d3d9_alphaTest = false; +void Gfx_SetAlphaTest(bool enabled) { + if (d3d9_alphaTest == enabled) return; + + d3d9_alphaTest = enabled; + D3D9_SetRenderState((UInt32)enabled, D3DRS_ALPHATESTENABLE, "D3D9_SetAlphaTest"); +} + +D3DCMPFUNC d3d9_alphaTestFunc = 0; +Int32 d3d9_alphaTestRef = 0; +void Gfx_SetAlphaTestFunc(Int32 compareFunc, Real32 refValue) { + d3d9_alphaTestFunc = d3d9_compareFuncs[compareFunc]; + D3D9_SetRenderState(d3d9_alphaTestFunc, D3DRS_ALPHAFUNC, "D3D9_SetAlphaTestFunc"); + d3d9_alphaTestRef = (Int32)(refValue * 255); + D3D9_SetRenderState2(d3d9_alphaTestRef, D3DRS_ALPHAREF, "D3D9_SetAlphaTestFunc2"); +} + +bool d3d9_alphaBlend = false; +void Gfx_SetAlphaBlending(bool enabled) { + if (d3d9_alphaBlend == enabled) return; + + d3d9_alphaBlend = enabled; + D3D9_SetRenderState((UInt32)enabled, D3DRS_ALPHABLENDENABLE, "D3D9_SetAlphaBlend"); +} + +D3DBLEND d3d9_srcBlendFunc = 0; +D3DBLEND d3d9_dstBlendFunc = 0; +void Gfx_SetAlphaBlendFunc(Int32 srcBlendFunc, Int32 dstBlendFunc) { + d3d9_srcBlendFunc = d3d9_blendFuncs[srcBlendFunc]; + D3D9_SetRenderState(d3d9_srcBlendFunc, D3DRS_SRCBLEND, "D3D9_SetAlphaBlendFunc"); + d3d9_dstBlendFunc = d3d9_blendFuncs[dstBlendFunc]; + D3D9_SetRenderState(d3d9_dstBlendFunc, D3DRS_DESTBLEND, "D3D9_SetAlphaBlendFunc2"); +} + +void Gfx_SetAlphaArgBlend(bool enabled) { + D3DTEXTUREOP op = enabled ? D3DTOP_MODULATE : D3DTOP_SELECTARG1; + ReturnCode hresult = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, op); + ErrorHandler_CheckOrFail(hresult, "D3D9_SetAlphaArgBlend"); +} + + +D3DPRIMITIVETYPE d3d9_modeMappings[2] = { D3DPT_TRIANGLELIST, D3DPT_LINELIST }; +D3DFORMAT d3d9_depthFormats[6] = { D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D16, D3DFMT_D15S1 }; +D3DFORMAT d3d9_viewFormats[4] = { D3DFMT_X8R8G8B8, D3DFMT_R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 }; +D3DBLEND d3d9_blendFuncs[6] = { D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA, D3DBLEND_DESTALPHA, D3DBLEND_INVDESTALPHA }; +D3DCMPFUNC d3d9_compareFuncs[8] = { D3DCMP_ALWAYS, D3DCMP_NOTEQUAL, D3DCMP_NEVER, D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_EQUAL, D3DCMP_GREATEREQUAL, D3DCMP_GREATER }; +D3DFOGMODE d3d9_modes[3] = { D3DFOG_LINEAR, D3DFOG_EXP, D3DFOG_EXP2 }; +Int32 d3d9_formatMappings[2] = { D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 }; #endif \ No newline at end of file diff --git a/src/Client/ErrorHandler.h b/src/Client/ErrorHandler.h index 8a45574d3..d7c388471 100644 --- a/src/Client/ErrorHandler.h +++ b/src/Client/ErrorHandler.h @@ -20,6 +20,7 @@ bool ErrorHandler_Check(ReturnCode returnCode); /* Shows a message box to user, logs message to disc, then fails. */ void ErrorHandler_Fail(String msg); -/* Checks that the return code of a method is successful. Calls ErrorHandler_Fail if not. */ -void ErrorHandler_CheckOrFail(ReturnCode returnCode, String msg); +/* Checks that the return code of a method is successful. Calls ErrorHandler_Fail if not. +NOTE: raw pointer is used here for performance reasons, DO NOT apply this style elsewhere.*/ +void ErrorHandler_CheckOrFail(ReturnCode returnCode, const UInt8* raw_msg); #endif \ No newline at end of file diff --git a/src/Client/GraphicsAPI.h b/src/Client/GraphicsAPI.h index 0b2bf4432..cbabe90bf 100644 --- a/src/Client/GraphicsAPI.h +++ b/src/Client/GraphicsAPI.h @@ -65,13 +65,13 @@ void Gfx_SetFog(bool enabled); void Gfx_SetFogColour(FastColour col); /* Sets the density of exp and exp^2 fog */ -void Gfx_SetFogDensity(float value); +void Gfx_SetFogDensity(Real32 value); /* Sets the start radius of fog for linear fog. */ -void Gfx_SetFogStart(float value); +void Gfx_SetFogStart(Real32 value); /* Sets the end radius of fog for for linear fog. */ -void Gfx_SetFogEnd(float value); +void Gfx_SetFogEnd(Real32 value); /* Sets the current fog mode. (linear, exp, or exp^2) */ void Gfx_SetFogMode(Int32 fogMode); @@ -84,7 +84,7 @@ void Gfx_SetFaceCulling(bool enabled); void Gfx_SetAlphaTest(bool enabled); /* Sets the alpha test compare function that is used when alpha testing is enabled. */ -void Gfx_SetAlphaTestFunc(Int32 compareFunc, float refValue); +void Gfx_SetAlphaTestFunc(Int32 compareFunc, Real32 refValue); /* Whether alpha blending is currently enabled. */ void Gfx_SetAlphaBlending(bool enabled);