From 8888576bcb8c0a9c40cf2786e57aedbb10079038 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Tue, 9 May 2017 11:45:46 +1000 Subject: [PATCH] Move NoShade out of BlockModel, more work on D3D9 api in C --- ClassicalSharp/Entities/Entity.cs | 1 + ClassicalSharp/Entities/Model/BlockModel.cs | 41 +++-- ClassicalSharp/Entities/Model/IModel.cs | 17 +- ClassicalSharp/Rendering/HeldBlockRenderer.cs | 2 +- src/Client/D3D9Api.c | 153 ++++++++++++++++++ src/Client/D3D9Api.h | 15 ++ 6 files changed, 199 insertions(+), 30 deletions(-) create mode 100644 src/Client/D3D9Api.c create mode 100644 src/Client/D3D9Api.h diff --git a/ClassicalSharp/Entities/Entity.cs b/ClassicalSharp/Entities/Entity.cs index c207b6e67..e6d6d326a 100644 --- a/ClassicalSharp/Entities/Entity.cs +++ b/ClassicalSharp/Entities/Entity.cs @@ -49,6 +49,7 @@ namespace ClassicalSharp.Entities { public AnimatedComponent anim; public float uScale = 1, vScale = 1; protected DateTime lastModelChange = new DateTime(1, 1, 1); + public bool NoShade = false; /// Rotation of the entity's head horizontally. (i.e. looking north or east) diff --git a/ClassicalSharp/Entities/Model/BlockModel.cs b/ClassicalSharp/Entities/Model/BlockModel.cs index c93b5f172..c458d663c 100644 --- a/ClassicalSharp/Entities/Model/BlockModel.cs +++ b/ClassicalSharp/Entities/Model/BlockModel.cs @@ -22,7 +22,7 @@ namespace ClassicalSharp.Model { TerrainAtlas1D atlas; bool bright; Vector3 minBB, maxBB; - public bool NoShade = false, SwitchOrder = false; + public bool SwitchOrder = false; ModelCache cache; public BlockModel(Game game) : base(game) { @@ -54,12 +54,10 @@ namespace ClassicalSharp.Model { public void CalcState(BlockID block) { if (game.BlockInfo.Draw[block] == DrawType.Gas) { - bright = false; minBB = Vector3.Zero; maxBB = Vector3.One; height = 1; } else { - bright = game.BlockInfo.FullBright[block]; minBB = game.BlockInfo.MinBB[block]; maxBB = game.BlockInfo.MaxBB[block]; height = maxBB.Y - minBB.Y; @@ -74,7 +72,7 @@ namespace ClassicalSharp.Model { return base.RenderDistance(p); } - int lastTexId = -1, col; + int lastTexId = -1; public override void DrawModel(Entity p) { // TODO: using 'is' is ugly, but means we can avoid creating // a string every single time held block changes. @@ -83,11 +81,12 @@ namespace ClassicalSharp.Model { } else { block = Utils.FastByte(p.ModelName); } - col = cols[0]; CalcState(block); - if (!(p is FakePlayer)) NoShade = bright; - if (bright) col = FastColour.WhitePacked; + if (game.BlockInfo.FullBright[block]) { + for (int i = 0; i < cols.Length; i++) + cols[i] = FastColour.WhitePacked; + } if (game.BlockInfo.Draw[block] == DrawType.Gas) return; lastTexId = -1; @@ -150,19 +149,19 @@ namespace ClassicalSharp.Model { drawer.Tinted = game.BlockInfo.Tinted[block]; drawer.TintColour = game.BlockInfo.FogColour[block]; - drawer.Bottom(1, Colour(FastColour.ShadeYBottom), GetTex(Side.Bottom), cache.vertices, ref index); + drawer.Bottom(1, cols[1], GetTex(Side.Bottom), cache.vertices, ref index); if (SwitchOrder) { - drawer.Right(1, Colour(FastColour.ShadeX), GetTex(Side.Right), cache.vertices, ref index); - drawer.Back(1, Colour(FastColour.ShadeZ), GetTex(Side.Back), cache.vertices, ref index); - drawer.Left(1, Colour(FastColour.ShadeX), GetTex(Side.Left), cache.vertices, ref index); - drawer.Front(1, Colour(FastColour.ShadeZ), GetTex(Side.Front), cache.vertices, ref index); + drawer.Right(1, cols[5], GetTex(Side.Right), cache.vertices, ref index); + drawer.Back(1, cols[2], GetTex(Side.Back), cache.vertices, ref index); + drawer.Left(1, cols[4], GetTex(Side.Left), cache.vertices, ref index); + drawer.Front(1, cols[3], GetTex(Side.Front), cache.vertices, ref index); } else { - drawer.Front(1, Colour(FastColour.ShadeZ), GetTex(Side.Front), cache.vertices, ref index); - drawer.Right(1, Colour(FastColour.ShadeX), GetTex(Side.Right), cache.vertices, ref index); - drawer.Back(1, Colour(FastColour.ShadeZ), GetTex(Side.Back), cache.vertices, ref index); - drawer.Left(1, Colour(FastColour.ShadeX), GetTex(Side.Left), cache.vertices, ref index); + drawer.Front(1, cols[3], GetTex(Side.Front), cache.vertices, ref index); + drawer.Right(1, cols[5], GetTex(Side.Right), cache.vertices, ref index); + drawer.Back(1, cols[2], GetTex(Side.Back), cache.vertices, ref index); + drawer.Left(1, cols[4], GetTex(Side.Left), cache.vertices, ref index); } - drawer.Top(1, Colour(1.0f), GetTex(Side.Top), cache.vertices, ref index); + drawer.Top(1, cols[0], GetTex(Side.Top), cache.vertices, ref index); } } @@ -174,10 +173,6 @@ namespace ClassicalSharp.Model { return texId; } - int Colour(float shade) { - return NoShade ? col : FastColour.ScalePacked(col, shade); - } - void SpriteZQuad(int side, bool firstPart) { SpriteZQuad(side, firstPart, false); SpriteZQuad(side, firstPart, true); @@ -189,7 +184,7 @@ namespace ClassicalSharp.Model { FlushIfNotSame(texIndex); if (height != 1) rec.V2 = rec.V1 + height * atlas.invElementSize * (15.99f/16f); - int col = this.col; + int col = cols[0]; float p1 = 0, p2 = 0; if (firstPart) { // Need to break into two quads for when drawing a sprite model in hand. @@ -217,7 +212,7 @@ namespace ClassicalSharp.Model { FlushIfNotSame(texIndex); if (height != 1) rec.V2 = rec.V1 + height * atlas.invElementSize * (15.99f/16f); - int col = this.col; + int col = cols[0]; float x1 = 0, x2 = 0, z1 = 0, z2 = 0; if (firstPart) { diff --git a/ClassicalSharp/Entities/Model/IModel.cs b/ClassicalSharp/Entities/Model/IModel.cs index 62bfc13b6..797742e86 100644 --- a/ClassicalSharp/Entities/Model/IModel.cs +++ b/ClassicalSharp/Entities/Model/IModel.cs @@ -27,7 +27,7 @@ namespace ClassicalSharp.Model { /// the whole model will be moved slightly down. public bool Bobbing = true; - /// Whether this entity requires downloading of a skin texture. + /// Whether this entity requires downloading of a skin texture. public bool UsesSkin = true; /// Whether humanoid animations should be calculated, instead of normal animations. @@ -40,7 +40,7 @@ namespace ClassicalSharp.Model { public virtual Vector3 Drag { get { return new Vector3(0.91f, 0.98f, 0.91f); } } /// Friction applied to the entity when is on the ground. - public virtual Vector3 GroundFriction { get { return new Vector3(0.6f, 1.0f, 0.6f); } } + public virtual Vector3 GroundFriction { get { return new Vector3(0.6f, 1.0f, 0.6f); } } /// Vertical offset from the model's feet/base that the name texture should be drawn at. @@ -99,7 +99,7 @@ namespace ClassicalSharp.Model { return Math.Min(Math.Abs(dist), Math.Min(dMin, dMax)); } - /// Sets up the state for, then renders an entity model, + /// Sets up the state for, then renders an entity model, /// based on the given entity's position and orientation. public void Render(Entity p) { Vector3 pos = p.Position; @@ -122,9 +122,14 @@ namespace ClassicalSharp.Model { uScale = 1 / 64f; vScale = 1 / 32f; cols[0] = col; - cols[1] = FastColour.ScalePacked(col, FastColour.ShadeYBottom); - cols[2] = FastColour.ScalePacked(col, FastColour.ShadeZ); cols[3] = cols[2]; - cols[4] = FastColour.ScalePacked(col, FastColour.ShadeX); cols[5] = cols[4]; + if (!p.NoShade) { + cols[1] = FastColour.ScalePacked(col, FastColour.ShadeYBottom); + cols[2] = FastColour.ScalePacked(col, FastColour.ShadeZ); + cols[4] = FastColour.ScalePacked(col, FastColour.ShadeX); + } else { + cols[1] = col; cols[2] = col; cols[4] = col; + } + cols[3] = cols[2]; cols[5] = cols[4]; float yawDelta = p.HeadY - p.RotY; cosHead = (float)Math.Cos(yawDelta * Utils.Deg2Rad); diff --git a/ClassicalSharp/Rendering/HeldBlockRenderer.cs b/ClassicalSharp/Rendering/HeldBlockRenderer.cs index 61cbdfcf8..5b24efe21 100644 --- a/ClassicalSharp/Rendering/HeldBlockRenderer.cs +++ b/ClassicalSharp/Rendering/HeldBlockRenderer.cs @@ -27,7 +27,6 @@ namespace ClassicalSharp.Renderers { public void Init(Game game) { this.game = game; block = new BlockModel(game); - block.NoShade = true; held = new FakePlayer(game); game.Events.ProjectionChanged += ProjectionChanged; @@ -124,6 +123,7 @@ namespace ClassicalSharp.Renderers { internal class FakePlayer : Player { public FakePlayer(Game game) : base(game) { + NoShade = true; } public BlockID Block; diff --git a/src/Client/D3D9Api.c b/src/Client/D3D9Api.c new file mode 100644 index 000000000..cc8c27fdb --- /dev/null +++ b/src/Client/D3D9Api.c @@ -0,0 +1,153 @@ +// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 +#include "GraphicsAPI.h" +#include "D3D9Api.h" +#include "ErrorHandler.h" + +#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) { +} + + +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_SetRenderState2(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"); +} + +UInt32 d3d9_clearCol = 0xFF000000; +void Gfx_Clear() { + DWORD flags = D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER; + ReturnCode hresult = IDirect3DDevice9_Clear(device, 0, NULL, flags, d3d9_clearCol, 1.0f, 0); + ErrorHandler_CheckOrFail(hresult, "D3D9_Clear"); +} + +void Gfx_ClearColour(FastColour col) { + d3d9_clearCol = col.Packed; +} + + +bool d3d9_depthTest = false; +void Gfx_SetDepthTest(bool enabled) { + d3d9_depthTest = enabled; + D3D9_SetRenderState((UInt32)enabled, D3DRS_ZENABLE, "D3D9_SetDepthTest"); +} + +D3DCMPFUNC d3d9_depthTestFunc = 0; +void Gfx_SetDepthTestFunc(Int32 compareFunc) { + d3d9_depthTestFunc = d3d9_compareFuncs[compareFunc]; + D3D9_SetRenderState(d3d9_alphaTestFunc, D3DRS_ZFUNC, "D3D9_SetDepthTestFunc"); +} + +void Gfx_SetColourWrite(bool enabled) { + UInt32 channels = enabled ? 0xF : 0x0; + D3D9_SetRenderState(channels, D3DRS_COLORWRITEENABLE, "D3D9_SetColourWrite"); +} + +bool d3d9_depthWrite = false; +void Gfx_SetDepthWrite(bool enabled) { + d3d9_depthWrite = enabled; + D3D9_SetRenderState((UInt32)enabled, D3DRS_ZWRITEENABLE, "D3D9_SetDepthWrite"); +} +#endif \ No newline at end of file diff --git a/src/Client/D3D9Api.h b/src/Client/D3D9Api.h new file mode 100644 index 000000000..fb6abdcb7 --- /dev/null +++ b/src/Client/D3D9Api.h @@ -0,0 +1,15 @@ +#ifndef CS_D3D9API_H +#define CS_D3D9API_H +#include +#include +#include + +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