Move NoShade out of BlockModel, more work on D3D9 api in C

This commit is contained in:
UnknownShadow200 2017-05-09 11:45:46 +10:00
parent e37dd1a2c7
commit 8888576bcb
6 changed files with 199 additions and 30 deletions

View file

@ -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;
/// <summary> Rotation of the entity's head horizontally. (i.e. looking north or east) </summary>

View file

@ -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) {

View file

@ -27,7 +27,7 @@ namespace ClassicalSharp.Model {
/// the whole model will be moved slightly down. </remarks>
public bool Bobbing = true;
/// <summary> Whether this entity requires downloading of a skin texture. </summary>
/// <summary> Whether this entity requires downloading of a skin texture. </summary>
public bool UsesSkin = true;
/// <summary> Whether humanoid animations should be calculated, instead of normal animations. </summary>
@ -40,7 +40,7 @@ namespace ClassicalSharp.Model {
public virtual Vector3 Drag { get { return new Vector3(0.91f, 0.98f, 0.91f); } }
/// <summary> Friction applied to the entity when is on the ground. </summary>
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); } }
/// <summary> Vertical offset from the model's feet/base that the name texture should be drawn at. </summary>
@ -99,7 +99,7 @@ namespace ClassicalSharp.Model {
return Math.Min(Math.Abs(dist), Math.Min(dMin, dMax));
}
/// <summary> Sets up the state for, then renders an entity model,
/// <summary> Sets up the state for, then renders an entity model,
/// based on the given entity's position and orientation. </summary>
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);

View file

@ -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;

153
src/Client/D3D9Api.c Normal file
View file

@ -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

15
src/Client/D3D9Api.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef CS_D3D9API_H
#define CS_D3D9API_H
#include <d3d9.h>
#include <d3d9caps.h>
#include <d3d9types.h>
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