commit
fbca397c92
|
@ -1087,8 +1087,9 @@ void Renderer::ApplyState(bool bUseDstAlpha)
|
||||||
SetLogicOpMode();
|
SetLogicOpMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::context->PSSetConstantBuffers(0, 1, &PixelShaderCache::GetConstantBuffer());
|
ID3D11Buffer* const_buffers[2] = {PixelShaderCache::GetConstantBuffer(), VertexShaderCache::GetConstantBuffer()};
|
||||||
D3D::context->VSSetConstantBuffers(0, 1, &VertexShaderCache::GetConstantBuffer());
|
D3D::context->PSSetConstantBuffers(0, 1 + g_ActiveConfig.bEnablePixelLighting, const_buffers);
|
||||||
|
D3D::context->VSSetConstantBuffers(0, 1, const_buffers+1);
|
||||||
|
|
||||||
D3D::context->PSSetShader(PixelShaderCache::GetActiveShader(), nullptr, 0);
|
D3D::context->PSSetShader(PixelShaderCache::GetActiveShader(), nullptr, 0);
|
||||||
D3D::context->VSSetShader(VertexShaderCache::GetActiveShader(), nullptr, 0);
|
D3D::context->VSSetShader(VertexShaderCache::GetActiveShader(), nullptr, 0);
|
||||||
|
|
|
@ -210,7 +210,7 @@ inline float SafeDivide(float n, float d)
|
||||||
|
|
||||||
void LightColor(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, Vec3 &lightCol)
|
void LightColor(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, Vec3 &lightCol)
|
||||||
{
|
{
|
||||||
const LightPointer *light = (const LightPointer*)&xfmem.lights[0x10*lightNum];
|
const LightPointer *light = (const LightPointer*)&xfmem.lights[lightNum];
|
||||||
|
|
||||||
if (!(chan.attnfunc & 1))
|
if (!(chan.attnfunc & 1))
|
||||||
{
|
{
|
||||||
|
@ -295,7 +295,7 @@ void LightColor(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChann
|
||||||
|
|
||||||
void LightAlpha(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, float &lightCol)
|
void LightAlpha(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, float &lightCol)
|
||||||
{
|
{
|
||||||
const LightPointer *light = (const LightPointer*)&xfmem.lights[0x10*lightNum];
|
const LightPointer *light = (const LightPointer*)&xfmem.lights[lightNum];
|
||||||
|
|
||||||
if (!(chan.attnfunc & 1))
|
if (!(chan.attnfunc & 1))
|
||||||
{
|
{
|
||||||
|
@ -476,7 +476,7 @@ void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool s
|
||||||
break;
|
break;
|
||||||
case XF_TEXGEN_EMBOSS_MAP:
|
case XF_TEXGEN_EMBOSS_MAP:
|
||||||
{
|
{
|
||||||
const LightPointer *light = (const LightPointer*)&xfmem.lights[0x10*texinfo.embosslightshift];
|
const LightPointer *light = (const LightPointer*)&xfmem.lights[texinfo.embosslightshift];
|
||||||
|
|
||||||
Vec3 ldir = (light->pos - dst->mvPosition).normalized();
|
Vec3 ldir = (light->pos - dst->mvPosition).normalized();
|
||||||
float d1 = ldir * dst->normal[1];
|
float d1 = ldir * dst->normal[1];
|
||||||
|
|
|
@ -23,7 +23,7 @@ void XFWritten(u32 transferSize, u32 baseAddress)
|
||||||
// fix lights so invalid values don't trash the lighting computations
|
// fix lights so invalid values don't trash the lighting computations
|
||||||
if (baseAddress <= 0x067f && topAddress >= 0x0604)
|
if (baseAddress <= 0x067f && topAddress >= 0x0604)
|
||||||
{
|
{
|
||||||
u32* x = xfmem.lights;
|
u32* x = (u32*)xfmem.lights;
|
||||||
|
|
||||||
// go through all lights
|
// go through all lights
|
||||||
for (int light = 0; light < 8; light++)
|
for (int light = 0; light < 8; light++)
|
||||||
|
|
|
@ -21,11 +21,6 @@ struct PixelShaderConstants
|
||||||
int4 fogcolor;
|
int4 fogcolor;
|
||||||
int4 fogi;
|
int4 fogi;
|
||||||
float4 fogf[2];
|
float4 fogf[2];
|
||||||
|
|
||||||
// For pixel lighting
|
|
||||||
int4 plight_colors[8];
|
|
||||||
float4 plights[32];
|
|
||||||
int4 pmaterials[4];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexShaderConstants
|
struct VertexShaderConstants
|
||||||
|
@ -33,11 +28,18 @@ struct VertexShaderConstants
|
||||||
float4 posnormalmatrix[6];
|
float4 posnormalmatrix[6];
|
||||||
float4 projection[4];
|
float4 projection[4];
|
||||||
int4 materials[4];
|
int4 materials[4];
|
||||||
int4 light_colors[8]; // 8 lights
|
struct Light
|
||||||
float4 lights[32]; // 8 lights * 4 parameters
|
{
|
||||||
|
int4 color;
|
||||||
|
float4 cosatt;
|
||||||
|
float4 distatt;
|
||||||
|
float4 pos;
|
||||||
|
float4 dir;
|
||||||
|
} lights [8];
|
||||||
float4 texmatrices[24];
|
float4 texmatrices[24];
|
||||||
float4 transformmatrices[64];
|
float4 transformmatrices[64];
|
||||||
float4 normalmatrices[32];
|
float4 normalmatrices[32];
|
||||||
float4 posttransformmatrices[64];
|
float4 posttransformmatrices[64];
|
||||||
float4 depthparams;
|
float4 depthparams;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,25 +4,26 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "VideoCommon/ConstantManager.h"
|
||||||
#include "VideoCommon/NativeVertexFormat.h"
|
#include "VideoCommon/NativeVertexFormat.h"
|
||||||
#include "VideoCommon/ShaderGenCommon.h"
|
#include "VideoCommon/ShaderGenCommon.h"
|
||||||
#include "VideoCommon/XFMemory.h"
|
#include "VideoCommon/XFMemory.h"
|
||||||
|
|
||||||
|
|
||||||
#define LIGHT_COL "%s[%d].%s"
|
#define LIGHT_COL "%s[%d].color.%s"
|
||||||
#define LIGHT_COL_PARAMS(lightsColName, index, swizzle) (lightsColName), (index), (swizzle)
|
#define LIGHT_COL_PARAMS(index, swizzle) (I_LIGHTS), (index), (swizzle)
|
||||||
|
|
||||||
#define LIGHT_COSATT "%s[4*%d]"
|
#define LIGHT_COSATT "%s[%d].cosatt"
|
||||||
#define LIGHT_COSATT_PARAMS(lightsName, index) (lightsName), (index)
|
#define LIGHT_COSATT_PARAMS(index) (I_LIGHTS), (index)
|
||||||
|
|
||||||
#define LIGHT_DISTATT "%s[4*%d+1]"
|
#define LIGHT_DISTATT "%s[%d].distatt"
|
||||||
#define LIGHT_DISTATT_PARAMS(lightsName, index) (lightsName), (index)
|
#define LIGHT_DISTATT_PARAMS(index) (I_LIGHTS), (index)
|
||||||
|
|
||||||
#define LIGHT_POS "%s[4*%d+2]"
|
#define LIGHT_POS "%s[%d].pos"
|
||||||
#define LIGHT_POS_PARAMS(lightsName, index) (lightsName), (index)
|
#define LIGHT_POS_PARAMS(index) (I_LIGHTS), (index)
|
||||||
|
|
||||||
#define LIGHT_DIR "%s[4*%d+3]"
|
#define LIGHT_DIR "%s[%d].dir"
|
||||||
#define LIGHT_DIR_PARAMS(lightsName, index) (lightsName), (index)
|
#define LIGHT_DIR_PARAMS(index) (I_LIGHTS), (index)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common uid data used for shader generators that use lighting calculations.
|
* Common uid data used for shader generators that use lighting calculations.
|
||||||
|
@ -37,9 +38,17 @@ struct LightingUidData
|
||||||
u32 light_mask : 32; // 4x8 bits
|
u32 light_mask : 32; // 4x8 bits
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char s_lighting_struct[] =
|
||||||
|
"struct Light {\n"
|
||||||
|
"\tint4 color;\n"
|
||||||
|
"\tfloat4 cosatt;\n"
|
||||||
|
"\tfloat4 distatt;\n"
|
||||||
|
"\tfloat4 pos;\n"
|
||||||
|
"\tfloat4 dir;\n"
|
||||||
|
"};\n";
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, const char* lightsColName, const char* lightsName, int coloralpha)
|
static void GenerateLightShader(T& object, LightingUidData& uid_data, int index, int litchan_index, int coloralpha)
|
||||||
{
|
{
|
||||||
const LitChannel& chan = (litchan_index > 1) ? xfmem.alpha[litchan_index-2] : xfmem.color[litchan_index];
|
const LitChannel& chan = (litchan_index > 1) ? xfmem.alpha[litchan_index-2] : xfmem.color[litchan_index];
|
||||||
const char* swizzle = (coloralpha == 1) ? "xyz" : (coloralpha == 2) ? "w" : "xyzw";
|
const char* swizzle = (coloralpha == 1) ? "xyz" : (coloralpha == 2) ? "w" : "xyzw";
|
||||||
|
@ -53,14 +62,14 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index,
|
||||||
switch (chan.diffusefunc)
|
switch (chan.diffusefunc)
|
||||||
{
|
{
|
||||||
case LIGHTDIF_NONE:
|
case LIGHTDIF_NONE:
|
||||||
object.Write("lacc.%s += " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(lightsColName, index, swizzle));
|
object.Write("lacc.%s += " LIGHT_COL";\n", swizzle, LIGHT_COL_PARAMS(index, swizzle));
|
||||||
break;
|
break;
|
||||||
case LIGHTDIF_SIGN:
|
case LIGHTDIF_SIGN:
|
||||||
case LIGHTDIF_CLAMP:
|
case LIGHTDIF_CLAMP:
|
||||||
object.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(lightsName, index));
|
object.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(index));
|
||||||
object.Write("lacc.%s += int%s(round(%sdot(ldir, _norm0)) * float%s(" LIGHT_COL")));\n",
|
object.Write("lacc.%s += int%s(round(%sdot(ldir, _norm0)) * float%s(" LIGHT_COL")));\n",
|
||||||
swizzle, swizzle_components, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(",
|
swizzle, swizzle_components, chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(",
|
||||||
swizzle_components, LIGHT_COL_PARAMS(lightsColName, index, swizzle));
|
swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
|
||||||
break;
|
break;
|
||||||
default: _assert_(0);
|
default: _assert_(0);
|
||||||
}
|
}
|
||||||
|
@ -69,24 +78,24 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index,
|
||||||
{
|
{
|
||||||
if (chan.attnfunc == 3)
|
if (chan.attnfunc == 3)
|
||||||
{ // spot
|
{ // spot
|
||||||
object.Write("ldir = " LIGHT_POS".xyz - pos.xyz;\n", LIGHT_POS_PARAMS(lightsName, index));
|
object.Write("ldir = " LIGHT_POS".xyz - pos.xyz;\n", LIGHT_POS_PARAMS(index));
|
||||||
object.Write("dist2 = dot(ldir, ldir);\n"
|
object.Write("dist2 = dot(ldir, ldir);\n"
|
||||||
"dist = sqrt(dist2);\n"
|
"dist = sqrt(dist2);\n"
|
||||||
"ldir = ldir / dist;\n"
|
"ldir = ldir / dist;\n"
|
||||||
"attn = max(0.0, dot(ldir, " LIGHT_DIR".xyz));\n",
|
"attn = max(0.0, dot(ldir, " LIGHT_DIR".xyz));\n",
|
||||||
LIGHT_DIR_PARAMS(lightsName, index));
|
LIGHT_DIR_PARAMS(index));
|
||||||
// attn*attn may overflow
|
// attn*attn may overflow
|
||||||
object.Write("attn = max(0.0, " LIGHT_COSATT".x + " LIGHT_COSATT".y*attn + " LIGHT_COSATT".z*attn*attn) / dot(" LIGHT_DISTATT".xyz, float3(1.0,dist,dist2));\n",
|
object.Write("attn = max(0.0, " LIGHT_COSATT".x + " LIGHT_COSATT".y*attn + " LIGHT_COSATT".z*attn*attn) / dot(" LIGHT_DISTATT".xyz, float3(1.0,dist,dist2));\n",
|
||||||
LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_DISTATT_PARAMS(lightsName, index));
|
LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), LIGHT_DISTATT_PARAMS(index));
|
||||||
}
|
}
|
||||||
else if (chan.attnfunc == 1)
|
else if (chan.attnfunc == 1)
|
||||||
{ // specular
|
{ // specular
|
||||||
object.Write("ldir = normalize(" LIGHT_POS".xyz);\n", LIGHT_POS_PARAMS(lightsName, index));
|
object.Write("ldir = normalize(" LIGHT_POS".xyz);\n", LIGHT_POS_PARAMS(index));
|
||||||
object.Write("attn = (dot(_norm0,ldir) >= 0.0) ? max(0.0, dot(_norm0, " LIGHT_DIR".xyz)) : 0.0;\n", LIGHT_DIR_PARAMS(lightsName, index));
|
object.Write("attn = (dot(_norm0,ldir) >= 0.0) ? max(0.0, dot(_norm0, " LIGHT_DIR".xyz)) : 0.0;\n", LIGHT_DIR_PARAMS(index));
|
||||||
// attn*attn may overflow
|
// attn*attn may overflow
|
||||||
object.Write("attn = max(0.0, " LIGHT_COSATT".x + " LIGHT_COSATT".y*attn + " LIGHT_COSATT".z*attn*attn) / (" LIGHT_DISTATT".x + " LIGHT_DISTATT".y*attn + " LIGHT_DISTATT".z*attn*attn);\n",
|
object.Write("attn = max(0.0, " LIGHT_COSATT".x + " LIGHT_COSATT".y*attn + " LIGHT_COSATT".z*attn*attn) / (" LIGHT_DISTATT".x + " LIGHT_DISTATT".y*attn + " LIGHT_DISTATT".z*attn*attn);\n",
|
||||||
LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_COSATT_PARAMS(lightsName, index), LIGHT_COSATT_PARAMS(lightsName, index),
|
LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index), LIGHT_COSATT_PARAMS(index),
|
||||||
LIGHT_DISTATT_PARAMS(lightsName, index), LIGHT_DISTATT_PARAMS(lightsName, index), LIGHT_DISTATT_PARAMS(lightsName, index));
|
LIGHT_DISTATT_PARAMS(index), LIGHT_DISTATT_PARAMS(index), LIGHT_DISTATT_PARAMS(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (chan.diffusefunc)
|
switch (chan.diffusefunc)
|
||||||
|
@ -94,14 +103,14 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index,
|
||||||
case LIGHTDIF_NONE:
|
case LIGHTDIF_NONE:
|
||||||
object.Write("lacc.%s += int%s(round(attn * float%s(" LIGHT_COL")));\n",
|
object.Write("lacc.%s += int%s(round(attn * float%s(" LIGHT_COL")));\n",
|
||||||
swizzle, swizzle_components,
|
swizzle, swizzle_components,
|
||||||
swizzle_components, LIGHT_COL_PARAMS(lightsColName, index, swizzle));
|
swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
|
||||||
break;
|
break;
|
||||||
case LIGHTDIF_SIGN:
|
case LIGHTDIF_SIGN:
|
||||||
case LIGHTDIF_CLAMP:
|
case LIGHTDIF_CLAMP:
|
||||||
object.Write("lacc.%s += int%s(round(attn * %sdot(ldir, _norm0)) * float%s(" LIGHT_COL")));\n",
|
object.Write("lacc.%s += int%s(round(attn * %sdot(ldir, _norm0)) * float%s(" LIGHT_COL")));\n",
|
||||||
swizzle, swizzle_components,
|
swizzle, swizzle_components,
|
||||||
chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(",
|
chan.diffusefunc != LIGHTDIF_SIGN ? "max(0.0," :"(",
|
||||||
swizzle_components, LIGHT_COL_PARAMS(lightsColName, index, swizzle));
|
swizzle_components, LIGHT_COL_PARAMS(index, swizzle));
|
||||||
break;
|
break;
|
||||||
default: _assert_(0);
|
default: _assert_(0);
|
||||||
}
|
}
|
||||||
|
@ -115,7 +124,7 @@ static void GenerateLightShader(T& object, LightingUidData& uid_data, int index,
|
||||||
// inColorName is color in vs and colors_ in ps
|
// inColorName is color in vs and colors_ in ps
|
||||||
// dest is o.colors_ in vs and colors_ in ps
|
// dest is o.colors_ in vs and colors_ in ps
|
||||||
template<class T>
|
template<class T>
|
||||||
static void GenerateLightingShader(T& object, LightingUidData& uid_data, int components, const char* materialsName, const char* lightsColName, const char* lightsName, const char* inColorName, const char* dest)
|
static void GenerateLightingShader(T& object, LightingUidData& uid_data, int components, const char* inColorName, const char* dest)
|
||||||
{
|
{
|
||||||
for (unsigned int j = 0; j < xfmem.numChan.numColorChans; j++)
|
for (unsigned int j = 0; j < xfmem.numChan.numColorChans; j++)
|
||||||
{
|
{
|
||||||
|
@ -136,7 +145,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
|
||||||
}
|
}
|
||||||
else // from color
|
else // from color
|
||||||
{
|
{
|
||||||
object.Write("int4 mat = %s[%d];\n", materialsName, j+2);
|
object.Write("int4 mat = %s[%d];\n", I_MATERIALS, j+2);
|
||||||
}
|
}
|
||||||
|
|
||||||
uid_data.enablelighting |= xfmem.color[j].enablelighting << j;
|
uid_data.enablelighting |= xfmem.color[j].enablelighting << j;
|
||||||
|
@ -157,7 +166,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
|
||||||
}
|
}
|
||||||
else // from color
|
else // from color
|
||||||
{
|
{
|
||||||
object.Write("lacc = %s[%d];\n", materialsName, j);
|
object.Write("lacc = %s[%d];\n", I_MATERIALS, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -179,7 +188,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
|
||||||
}
|
}
|
||||||
else // from color
|
else // from color
|
||||||
{
|
{
|
||||||
object.Write("mat.w = %s[%d].w;\n", materialsName, j+2);
|
object.Write("mat.w = %s[%d].w;\n", I_MATERIALS, j+2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +208,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
|
||||||
}
|
}
|
||||||
else // from color
|
else // from color
|
||||||
{
|
{
|
||||||
object.Write("lacc.w = %s[%d].w;\n", materialsName, j);
|
object.Write("lacc.w = %s[%d].w;\n", I_MATERIALS, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -226,7 +235,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
|
||||||
{
|
{
|
||||||
if (mask & (1<<i))
|
if (mask & (1<<i))
|
||||||
{
|
{
|
||||||
GenerateLightShader<T>(object, uid_data, i, j, lightsColName, lightsName, 3);
|
GenerateLightShader<T>(object, uid_data, i, j, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,9 +245,9 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
if (!(mask&(1<<i)) && (color.GetFullLightMask() & (1<<i)))
|
if (!(mask&(1<<i)) && (color.GetFullLightMask() & (1<<i)))
|
||||||
GenerateLightShader<T>(object, uid_data, i, j, lightsColName, lightsName, 1);
|
GenerateLightShader<T>(object, uid_data, i, j, 1);
|
||||||
if (!(mask&(1<<i)) && (alpha.GetFullLightMask() & (1<<i)))
|
if (!(mask&(1<<i)) && (alpha.GetFullLightMask() & (1<<i)))
|
||||||
GenerateLightShader<T>(object, uid_data, i, j+2, lightsColName, lightsName, 2);
|
GenerateLightShader<T>(object, uid_data, i, j+2, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (color.enablelighting || alpha.enablelighting)
|
else if (color.enablelighting || alpha.enablelighting)
|
||||||
|
@ -252,7 +261,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
if (workingchannel.GetFullLightMask() & (1<<i))
|
if (workingchannel.GetFullLightMask() & (1<<i))
|
||||||
GenerateLightShader<T>(object, uid_data, i, lit_index, lightsColName, lightsName, coloralpha);
|
GenerateLightShader<T>(object, uid_data, i, lit_index, coloralpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
object.Write("lacc = clamp(lacc, 0, 255);");
|
object.Write("lacc = clamp(lacc, 0, 255);");
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "VideoCommon/BPMemory.h"
|
#include "VideoCommon/BPMemory.h"
|
||||||
|
#include "VideoCommon/ConstantManager.h"
|
||||||
#include "VideoCommon/LightingShaderGen.h"
|
#include "VideoCommon/LightingShaderGen.h"
|
||||||
#include "VideoCommon/NativeVertexFormat.h"
|
#include "VideoCommon/NativeVertexFormat.h"
|
||||||
#include "VideoCommon/PixelShaderGen.h"
|
#include "VideoCommon/PixelShaderGen.h"
|
||||||
|
@ -218,9 +219,13 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
|
||||||
out.Write("\n");
|
out.Write("\n");
|
||||||
|
|
||||||
if (ApiType == API_OPENGL)
|
if (ApiType == API_OPENGL)
|
||||||
|
{
|
||||||
out.Write("layout(std140%s) uniform PSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 1" : "");
|
out.Write("layout(std140%s) uniform PSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 1" : "");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
out.Write("cbuffer PSBlock {\n");
|
{
|
||||||
|
out.Write("cbuffer PSBlock : register(b0) {\n");
|
||||||
|
}
|
||||||
out.Write(
|
out.Write(
|
||||||
"\tint4 " I_COLORS"[4];\n"
|
"\tint4 " I_COLORS"[4];\n"
|
||||||
"\tint4 " I_KCOLORS"[4];\n"
|
"\tint4 " I_KCOLORS"[4];\n"
|
||||||
|
@ -232,13 +237,32 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
|
||||||
"\tint4 " I_FOGCOLOR";\n"
|
"\tint4 " I_FOGCOLOR";\n"
|
||||||
"\tint4 " I_FOGI";\n"
|
"\tint4 " I_FOGI";\n"
|
||||||
"\tfloat4 " I_FOGF"[2];\n"
|
"\tfloat4 " I_FOGF"[2];\n"
|
||||||
|
|
||||||
// For pixel lighting - TODO: Should only be defined when per pixel lighting is enabled!
|
|
||||||
"\tint4 " I_PLIGHT_COLORS"[8];\n"
|
|
||||||
"\tfloat4 " I_PLIGHTS"[32];\n"
|
|
||||||
"\tint4 " I_PMATERIALS"[4];\n"
|
|
||||||
"};\n");
|
"};\n");
|
||||||
|
|
||||||
|
if (g_ActiveConfig.bEnablePixelLighting)
|
||||||
|
{
|
||||||
|
out.Write("%s", s_lighting_struct);
|
||||||
|
|
||||||
|
if (ApiType == API_OPENGL)
|
||||||
|
{
|
||||||
|
out.Write("layout(std140%s) uniform VSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 2" : "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.Write("cbuffer VSBlock : register(b1) {\n");
|
||||||
|
}
|
||||||
|
out.Write(
|
||||||
|
"\tfloat4 " I_POSNORMALMATRIX"[6];\n"
|
||||||
|
"\tfloat4 " I_PROJECTION"[4];\n"
|
||||||
|
"\tint4 " I_MATERIALS"[4];\n"
|
||||||
|
"\tLight " I_LIGHTS"[8];\n"
|
||||||
|
"\tfloat4 " I_TEXMATRICES"[24];\n"
|
||||||
|
"\tfloat4 " I_TRANSFORMMATRICES"[64];\n"
|
||||||
|
"\tfloat4 " I_NORMALMATRICES"[32];\n"
|
||||||
|
"\tfloat4 " I_POSTTRANSFORMMATRICES"[64];\n"
|
||||||
|
"\tfloat4 " I_DEPTHPARAMS";\n"
|
||||||
|
"};\n");
|
||||||
|
}
|
||||||
const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED);
|
const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED);
|
||||||
const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) || (!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !forced_early_z);
|
const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) || (!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !forced_early_z);
|
||||||
|
|
||||||
|
@ -351,11 +375,13 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
|
||||||
"\tfloat3 ldir, h;\n"
|
"\tfloat3 ldir, h;\n"
|
||||||
"\tfloat dist, dist2, attn;\n");
|
"\tfloat dist, dist2, attn;\n");
|
||||||
|
|
||||||
out.SetConstantsUsed(C_PLIGHT_COLORS, C_PLIGHT_COLORS+7); // TODO: Can be optimized further
|
// TODO: Our current constant usage code isn't able to handle more than one buffer.
|
||||||
out.SetConstantsUsed(C_PLIGHTS, C_PLIGHTS+31); // TODO: Can be optimized further
|
// So we can't mark the VS constant as used here. But keep them here as reference.
|
||||||
out.SetConstantsUsed(C_PMATERIALS, C_PMATERIALS+3);
|
//out.SetConstantsUsed(C_PLIGHT_COLORS, C_PLIGHT_COLORS+7); // TODO: Can be optimized further
|
||||||
|
//out.SetConstantsUsed(C_PLIGHTS, C_PLIGHTS+31); // TODO: Can be optimized further
|
||||||
|
//out.SetConstantsUsed(C_PMATERIALS, C_PMATERIALS+3);
|
||||||
uid_data.components = components;
|
uid_data.components = components;
|
||||||
GenerateLightingShader<T>(out, uid_data.lighting, components, I_PMATERIALS, I_PLIGHT_COLORS, I_PLIGHTS, "colors_", "colors_");
|
GenerateLightingShader<T>(out, uid_data.lighting, components, "colors_", "colors_");
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK to handle cases where the tex gen is not enabled
|
// HACK to handle cases where the tex gen is not enabled
|
||||||
|
|
|
@ -9,20 +9,6 @@
|
||||||
#include "VideoCommon/ShaderGenCommon.h"
|
#include "VideoCommon/ShaderGenCommon.h"
|
||||||
#include "VideoCommon/VideoCommon.h"
|
#include "VideoCommon/VideoCommon.h"
|
||||||
|
|
||||||
#define I_COLORS "color"
|
|
||||||
#define I_KCOLORS "k"
|
|
||||||
#define I_ALPHA "alphaRef"
|
|
||||||
#define I_TEXDIMS "texdim"
|
|
||||||
#define I_ZBIAS "czbias"
|
|
||||||
#define I_INDTEXSCALE "cindscale"
|
|
||||||
#define I_INDTEXMTX "cindmtx"
|
|
||||||
#define I_FOGCOLOR "cfogcolor"
|
|
||||||
#define I_FOGI "cfogi"
|
|
||||||
#define I_FOGF "cfogf"
|
|
||||||
#define I_PLIGHT_COLORS "cPLightColors"
|
|
||||||
#define I_PLIGHTS "cPLights"
|
|
||||||
#define I_PMATERIALS "cPmtrl"
|
|
||||||
|
|
||||||
// TODO: get rid of them as they aren't used
|
// TODO: get rid of them as they aren't used
|
||||||
#define C_COLORMATRIX 0 // 0
|
#define C_COLORMATRIX 0 // 0
|
||||||
#define C_COLORS 0 // 0
|
#define C_COLORS 0 // 0
|
||||||
|
@ -36,10 +22,7 @@
|
||||||
#define C_FOGI (C_FOGCOLOR + 1) //28
|
#define C_FOGI (C_FOGCOLOR + 1) //28
|
||||||
#define C_FOGF (C_FOGI + 1) //29
|
#define C_FOGF (C_FOGI + 1) //29
|
||||||
|
|
||||||
#define C_PLIGHT_COLORS (C_FOGF + 2)
|
#define C_PENVCONST_END (C_FOGF + 2)
|
||||||
#define C_PLIGHTS (C_PLIGHT_COLORS + 8)
|
|
||||||
#define C_PMATERIALS (C_PLIGHTS + 32)
|
|
||||||
#define C_PENVCONST_END (C_PMATERIALS + 4)
|
|
||||||
|
|
||||||
// Different ways to achieve rendering with destination alpha
|
// Different ways to achieve rendering with destination alpha
|
||||||
enum DSTALPHA_MODE
|
enum DSTALPHA_MODE
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
static bool s_bFogRangeAdjustChanged;
|
static bool s_bFogRangeAdjustChanged;
|
||||||
static bool s_bViewPortChanged;
|
static bool s_bViewPortChanged;
|
||||||
static int nLightsChanged[2]; // min,max
|
|
||||||
|
|
||||||
PixelShaderConstants PixelShaderManager::constants;
|
PixelShaderConstants PixelShaderManager::constants;
|
||||||
bool PixelShaderManager::dirty;
|
bool PixelShaderManager::dirty;
|
||||||
|
@ -29,7 +28,6 @@ void PixelShaderManager::Dirty()
|
||||||
{
|
{
|
||||||
s_bFogRangeAdjustChanged = true;
|
s_bFogRangeAdjustChanged = true;
|
||||||
s_bViewPortChanged = true;
|
s_bViewPortChanged = true;
|
||||||
nLightsChanged[0] = 0; nLightsChanged[1] = 0x80;
|
|
||||||
|
|
||||||
SetColorChanged(0, 0);
|
SetColorChanged(0, 0);
|
||||||
SetColorChanged(0, 1);
|
SetColorChanged(0, 1);
|
||||||
|
@ -100,45 +98,6 @@ void PixelShaderManager::SetConstants()
|
||||||
s_bFogRangeAdjustChanged = false;
|
s_bFogRangeAdjustChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_ActiveConfig.bEnablePixelLighting) // config check added because the code in here was crashing for me inside SetPSConstant4f
|
|
||||||
{
|
|
||||||
if (nLightsChanged[0] >= 0)
|
|
||||||
{
|
|
||||||
// TODO: Outdated comment
|
|
||||||
// lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
|
|
||||||
int istart = nLightsChanged[0] / 0x10;
|
|
||||||
int iend = (nLightsChanged[1] + 15) / 0x10;
|
|
||||||
const float* xfmemptr = (const float*)&xfmem.lights[0x10 * istart];
|
|
||||||
|
|
||||||
for (int i = istart; i < iend; ++i)
|
|
||||||
{
|
|
||||||
u32 color = *(const u32*)(xfmemptr + 3);
|
|
||||||
constants.plight_colors[i][0] = (color >> 24) & 0xFF;
|
|
||||||
constants.plight_colors[i][1] = (color >> 16) & 0xFF;
|
|
||||||
constants.plight_colors[i][2] = (color >> 8) & 0xFF;
|
|
||||||
constants.plight_colors[i][3] = (color) & 0xFF;
|
|
||||||
xfmemptr += 4;
|
|
||||||
|
|
||||||
for (int j = 0; j < 4; ++j, xfmemptr += 3)
|
|
||||||
{
|
|
||||||
if (j == 1 &&
|
|
||||||
fabs(xfmemptr[0]) < 0.00001f &&
|
|
||||||
fabs(xfmemptr[1]) < 0.00001f &&
|
|
||||||
fabs(xfmemptr[2]) < 0.00001f)
|
|
||||||
// dist attenuation, make sure not equal to 0!!!
|
|
||||||
constants.plights[4*i+j][0] = 0.00001f;
|
|
||||||
else
|
|
||||||
constants.plights[4*i+j][0] = xfmemptr[0];
|
|
||||||
constants.plights[4*i+j][1] = xfmemptr[1];
|
|
||||||
constants.plights[4*i+j][2] = xfmemptr[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dirty = true;
|
|
||||||
|
|
||||||
nLightsChanged[0] = nLightsChanged[1] = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_bViewPortChanged)
|
if (s_bViewPortChanged)
|
||||||
{
|
{
|
||||||
constants.zbias[1][0] = xfmem.viewport.farZ;
|
constants.zbias[1][0] = xfmem.viewport.farZ;
|
||||||
|
@ -304,38 +263,6 @@ void PixelShaderManager::SetFogRangeAdjustChanged()
|
||||||
s_bFogRangeAdjustChanged = true;
|
s_bFogRangeAdjustChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderManager::InvalidateXFRange(int start, int end)
|
|
||||||
{
|
|
||||||
if (start < XFMEM_LIGHTS_END && end > XFMEM_LIGHTS)
|
|
||||||
{
|
|
||||||
int _start = start < XFMEM_LIGHTS ? XFMEM_LIGHTS : start-XFMEM_LIGHTS;
|
|
||||||
int _end = end < XFMEM_LIGHTS_END ? end-XFMEM_LIGHTS : XFMEM_LIGHTS_END-XFMEM_LIGHTS;
|
|
||||||
|
|
||||||
if (nLightsChanged[0] == -1 )
|
|
||||||
{
|
|
||||||
nLightsChanged[0] = _start;
|
|
||||||
nLightsChanged[1] = _end;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (nLightsChanged[0] > _start) nLightsChanged[0] = _start;
|
|
||||||
if (nLightsChanged[1] < _end) nLightsChanged[1] = _end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PixelShaderManager::SetMaterialColorChanged(int index, u32 color)
|
|
||||||
{
|
|
||||||
if (g_ActiveConfig.bEnablePixelLighting)
|
|
||||||
{
|
|
||||||
constants.pmaterials[index][0] = (color >> 24) & 0xFF;
|
|
||||||
constants.pmaterials[index][1] = (color >> 16) & 0xFF;
|
|
||||||
constants.pmaterials[index][2] = (color >> 8) & 0xFF;
|
|
||||||
constants.pmaterials[index][3] = (color) & 0xFF;
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PixelShaderManager::DoState(PointerWrap &p)
|
void PixelShaderManager::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
p.Do(constants);
|
p.Do(constants);
|
||||||
|
|
|
@ -39,8 +39,6 @@ public:
|
||||||
static void SetFogColorChanged();
|
static void SetFogColorChanged();
|
||||||
static void SetFogParamChanged();
|
static void SetFogParamChanged();
|
||||||
static void SetFogRangeAdjustChanged();
|
static void SetFogRangeAdjustChanged();
|
||||||
static void InvalidateXFRange(int start, int end);
|
|
||||||
static void SetMaterialColorChanged(int index, u32 color);
|
|
||||||
|
|
||||||
static PixelShaderConstants constants;
|
static PixelShaderConstants constants;
|
||||||
static bool dirty;
|
static bool dirty;
|
||||||
|
|
|
@ -215,3 +215,25 @@ private:
|
||||||
std::map<UidT,std::string> m_shaders;
|
std::map<UidT,std::string> m_shaders;
|
||||||
std::vector<UidT> m_uids;
|
std::vector<UidT> m_uids;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Constant variable names
|
||||||
|
#define I_COLORS "color"
|
||||||
|
#define I_KCOLORS "k"
|
||||||
|
#define I_ALPHA "alphaRef"
|
||||||
|
#define I_TEXDIMS "texdim"
|
||||||
|
#define I_ZBIAS "czbias"
|
||||||
|
#define I_INDTEXSCALE "cindscale"
|
||||||
|
#define I_INDTEXMTX "cindmtx"
|
||||||
|
#define I_FOGCOLOR "cfogcolor"
|
||||||
|
#define I_FOGI "cfogi"
|
||||||
|
#define I_FOGF "cfogf"
|
||||||
|
|
||||||
|
#define I_POSNORMALMATRIX "cpnmtx"
|
||||||
|
#define I_PROJECTION "cproj"
|
||||||
|
#define I_MATERIALS "cmtrl"
|
||||||
|
#define I_LIGHTS "clights"
|
||||||
|
#define I_TEXMATRICES "ctexmtx"
|
||||||
|
#define I_TRANSFORMMATRICES "ctrmtx"
|
||||||
|
#define I_NORMALMATRICES "cnmtx"
|
||||||
|
#define I_POSTTRANSFORMMATRICES "cpostmtx"
|
||||||
|
#define I_DEPTHPARAMS "cDepth" // farZ, zRange
|
||||||
|
|
|
@ -81,6 +81,8 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
|
||||||
_assert_(bpmem.genMode.numtexgens == xfmem.numTexGen.numTexGens);
|
_assert_(bpmem.genMode.numtexgens == xfmem.numTexGen.numTexGens);
|
||||||
_assert_(bpmem.genMode.numcolchans == xfmem.numChan.numColorChans);
|
_assert_(bpmem.genMode.numcolchans == xfmem.numChan.numColorChans);
|
||||||
|
|
||||||
|
out.Write("%s", s_lighting_struct);
|
||||||
|
|
||||||
// uniforms
|
// uniforms
|
||||||
if (api_type == API_OPENGL)
|
if (api_type == API_OPENGL)
|
||||||
out.Write("layout(std140%s) uniform VSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 2" : "");
|
out.Write("layout(std140%s) uniform VSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 2" : "");
|
||||||
|
@ -90,8 +92,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
|
||||||
"\tfloat4 " I_POSNORMALMATRIX"[6];\n"
|
"\tfloat4 " I_POSNORMALMATRIX"[6];\n"
|
||||||
"\tfloat4 " I_PROJECTION"[4];\n"
|
"\tfloat4 " I_PROJECTION"[4];\n"
|
||||||
"\tint4 " I_MATERIALS"[4];\n"
|
"\tint4 " I_MATERIALS"[4];\n"
|
||||||
"\tint4 " I_LIGHT_COLORS"[8];\n"
|
"\tLight " I_LIGHTS"[8];\n"
|
||||||
"\tfloat4 " I_LIGHTS"[32];\n"
|
|
||||||
"\tfloat4 " I_TEXMATRICES"[24];\n"
|
"\tfloat4 " I_TEXMATRICES"[24];\n"
|
||||||
"\tfloat4 " I_TRANSFORMMATRICES"[64];\n"
|
"\tfloat4 " I_TRANSFORMMATRICES"[64];\n"
|
||||||
"\tfloat4 " I_NORMALMATRICES"[32];\n"
|
"\tfloat4 " I_NORMALMATRICES"[32];\n"
|
||||||
|
@ -229,7 +230,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
|
||||||
out.Write("o.colors_0 = float4(1.0, 1.0, 1.0, 1.0);\n");
|
out.Write("o.colors_0 = float4(1.0, 1.0, 1.0, 1.0);\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateLightingShader<T>(out, uid_data.lighting, components, I_MATERIALS, I_LIGHT_COLORS, I_LIGHTS, "color", "o.colors_");
|
GenerateLightingShader<T>(out, uid_data.lighting, components, "color", "o.colors_");
|
||||||
|
|
||||||
if (xfmem.numChan.numColorChans < 2)
|
if (xfmem.numChan.numColorChans < 2)
|
||||||
{
|
{
|
||||||
|
@ -304,7 +305,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ
|
||||||
// transform the light dir into tangent space
|
// transform the light dir into tangent space
|
||||||
uid_data.texMtxInfo[i].embosslightshift = xfmem.texMtxInfo[i].embosslightshift;
|
uid_data.texMtxInfo[i].embosslightshift = xfmem.texMtxInfo[i].embosslightshift;
|
||||||
uid_data.texMtxInfo[i].embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift;
|
uid_data.texMtxInfo[i].embosssourceshift = xfmem.texMtxInfo[i].embosssourceshift;
|
||||||
out.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(I_LIGHTS, texinfo.embosslightshift));
|
out.Write("ldir = normalize(" LIGHT_POS".xyz - pos.xyz);\n", LIGHT_POS_PARAMS(texinfo.embosslightshift));
|
||||||
out.Write("o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0);\n", i, texinfo.embosssourceshift);
|
out.Write("o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0);\n", i, texinfo.embosssourceshift);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -28,19 +28,6 @@
|
||||||
#define SHADER_TEXTURE7_ATTRIB 15
|
#define SHADER_TEXTURE7_ATTRIB 15
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// shader variables
|
|
||||||
#define I_POSNORMALMATRIX "cpnmtx"
|
|
||||||
#define I_PROJECTION "cproj"
|
|
||||||
#define I_MATERIALS "cmtrl"
|
|
||||||
#define I_LIGHT_COLORS "clight_colors"
|
|
||||||
#define I_LIGHTS "clights"
|
|
||||||
#define I_TEXMATRICES "ctexmtx"
|
|
||||||
#define I_TRANSFORMMATRICES "ctrmtx"
|
|
||||||
#define I_NORMALMATRICES "cnmtx"
|
|
||||||
#define I_POSTTRANSFORMMATRICES "cpostmtx"
|
|
||||||
#define I_DEPTHPARAMS "cDepth" // farZ, zRange
|
|
||||||
|
|
||||||
//TODO: get rid of them, they aren't used at all
|
//TODO: get rid of them, they aren't used at all
|
||||||
#define C_POSNORMALMATRIX 0
|
#define C_POSNORMALMATRIX 0
|
||||||
#define C_PROJECTION (C_POSNORMALMATRIX + 6)
|
#define C_PROJECTION (C_POSNORMALMATRIX + 6)
|
||||||
|
|
|
@ -247,32 +247,44 @@ void VertexShaderManager::SetConstants()
|
||||||
// lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
|
// lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
|
||||||
int istart = nLightsChanged[0] / 0x10;
|
int istart = nLightsChanged[0] / 0x10;
|
||||||
int iend = (nLightsChanged[1] + 15) / 0x10;
|
int iend = (nLightsChanged[1] + 15) / 0x10;
|
||||||
const float* xfmemptr = (const float*)&xfmem.lights[0x10 * istart];
|
|
||||||
|
|
||||||
for (int i = istart; i < iend; ++i)
|
for (int i = istart; i < iend; ++i)
|
||||||
{
|
{
|
||||||
u32 color = *(const u32*)(xfmemptr + 3);
|
const Light& light = xfmem.lights[i];
|
||||||
constants.light_colors[i][0] = (color >> 24) & 0xFF;
|
VertexShaderConstants::Light& dstlight = constants.lights[i];
|
||||||
constants.light_colors[i][1] = (color >> 16) & 0xFF;
|
|
||||||
constants.light_colors[i][2] = (color >> 8) & 0xFF;
|
|
||||||
constants.light_colors[i][3] = (color) & 0xFF;
|
|
||||||
xfmemptr += 4;
|
|
||||||
|
|
||||||
for (int j = 0; j < 4; ++j, xfmemptr += 3)
|
// xfmem.light.color is packed as abgr in u8[4], so we have to swap the order
|
||||||
|
dstlight.color[0] = light.color[3];
|
||||||
|
dstlight.color[1] = light.color[2];
|
||||||
|
dstlight.color[2] = light.color[1];
|
||||||
|
dstlight.color[3] = light.color[0];
|
||||||
|
|
||||||
|
dstlight.cosatt[0] = light.cosatt[0];
|
||||||
|
dstlight.cosatt[1] = light.cosatt[1];
|
||||||
|
dstlight.cosatt[2] = light.cosatt[2];
|
||||||
|
|
||||||
|
if (fabs(light.distatt[0]) < 0.00001f &&
|
||||||
|
fabs(light.distatt[1]) < 0.00001f &&
|
||||||
|
fabs(light.distatt[2]) < 0.00001f)
|
||||||
{
|
{
|
||||||
if (j == 1 &&
|
// dist attenuation, make sure not equal to 0!!!
|
||||||
fabs(xfmemptr[0]) < 0.00001f &&
|
dstlight.distatt[0] = .00001f;
|
||||||
fabs(xfmemptr[1]) < 0.00001f &&
|
|
||||||
fabs(xfmemptr[2]) < 0.00001f)
|
|
||||||
{
|
|
||||||
// dist attenuation, make sure not equal to 0!!!
|
|
||||||
constants.lights[4*i+j][0] = 0.00001f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
constants.lights[4*i+j][0] = xfmemptr[0];
|
|
||||||
constants.lights[4*i+j][1] = xfmemptr[1];
|
|
||||||
constants.lights[4*i+j][2] = xfmemptr[2];
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dstlight.distatt[0] = light.distatt[0];
|
||||||
|
}
|
||||||
|
dstlight.distatt[1] = light.distatt[1];
|
||||||
|
dstlight.distatt[2] = light.distatt[2];
|
||||||
|
|
||||||
|
dstlight.pos[0] = light.dpos[0];
|
||||||
|
dstlight.pos[1] = light.dpos[1];
|
||||||
|
dstlight.pos[2] = light.dpos[2];
|
||||||
|
|
||||||
|
// TODO: these likely have to be normalized
|
||||||
|
dstlight.dir[0] = light.ddir[0];
|
||||||
|
dstlight.dir[1] = light.ddir[1];
|
||||||
|
dstlight.dir[2] = light.ddir[2];
|
||||||
}
|
}
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
||||||
|
|
|
@ -194,13 +194,9 @@ union DualTexInfo
|
||||||
struct Light
|
struct Light
|
||||||
{
|
{
|
||||||
u32 useless[3];
|
u32 useless[3];
|
||||||
u32 color; // rgba
|
u8 color[4];
|
||||||
float a0; // attenuation
|
float cosatt[3]; // cos attenuation
|
||||||
float a1;
|
float distatt[3]; // dist attenuation
|
||||||
float a2;
|
|
||||||
float k0; // k stuff
|
|
||||||
float k1;
|
|
||||||
float k2;
|
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
@ -241,7 +237,7 @@ struct XFMemory
|
||||||
u32 normalMatrices[96]; // 0x0400 - 0x045f
|
u32 normalMatrices[96]; // 0x0400 - 0x045f
|
||||||
u32 unk1[160]; // 0x0460 - 0x04ff
|
u32 unk1[160]; // 0x0460 - 0x04ff
|
||||||
u32 postMatrices[256]; // 0x0500 - 0x05ff
|
u32 postMatrices[256]; // 0x0500 - 0x05ff
|
||||||
u32 lights[128]; // 0x0600 - 0x067f
|
Light lights[8]; // 0x0600 - 0x067f
|
||||||
u32 unk2[2432]; // 0x0680 - 0x0fff
|
u32 unk2[2432]; // 0x0680 - 0x0fff
|
||||||
u32 error; // 0x1000
|
u32 error; // 0x1000
|
||||||
u32 diag; // 0x1001
|
u32 diag; // 0x1001
|
||||||
|
|
|
@ -15,7 +15,6 @@ void XFMemWritten(u32 transferSize, u32 baseAddress)
|
||||||
{
|
{
|
||||||
VertexManager::Flush();
|
VertexManager::Flush();
|
||||||
VertexShaderManager::InvalidateXFRange(baseAddress, baseAddress + transferSize);
|
VertexShaderManager::InvalidateXFRange(baseAddress, baseAddress + transferSize);
|
||||||
PixelShaderManager::InvalidateXFRange(baseAddress, baseAddress + transferSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
|
void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
|
||||||
|
@ -61,7 +60,6 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
|
||||||
{
|
{
|
||||||
VertexManager::Flush();
|
VertexManager::Flush();
|
||||||
VertexShaderManager::SetMaterialColorChanged(chan, newValue);
|
VertexShaderManager::SetMaterialColorChanged(chan, newValue);
|
||||||
PixelShaderManager::SetMaterialColorChanged(chan, newValue);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +72,6 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
|
||||||
{
|
{
|
||||||
VertexManager::Flush();
|
VertexManager::Flush();
|
||||||
VertexShaderManager::SetMaterialColorChanged(chan + 2, newValue);
|
VertexShaderManager::SetMaterialColorChanged(chan + 2, newValue);
|
||||||
PixelShaderManager::SetMaterialColorChanged(chan + 2, newValue);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue