naomi2: use TA parser. Use N2light directly with vk, dx11
Use TA parser to handle list type and clipping for Naomi 2 polys. Pass all pass-throuch TA data to TA parser but stop on naomi2 command. Set default projection matrix instead of identity (fixes Area conquered screen invisible in initd). Change N2Light and N2LightModel so they are usable in GLSL (vulkan) and HLSL (dx11). TA parser throws exception for unhandled param. ta_vtx.cpp refactoring. Support for subtractive lights (diffuse+specular). Used in some clubk circuits. Fix vulkan crash when direct FB render.
This commit is contained in:
parent
5b3d36e081
commit
56768f2d3d
|
@ -458,10 +458,13 @@ void Emulator::loadGame(const char *path, LoadProgress *progress)
|
|||
mem_map_default();
|
||||
|
||||
config::Settings::instance().reset();
|
||||
dc_reset(true);
|
||||
config::Settings::instance().load(false);
|
||||
dc_reset(true);
|
||||
memset(&settings.network.md5, 0, sizeof(settings.network.md5));
|
||||
|
||||
if (settings.platform.isNaomi2() && config::RendererType == RenderType::DirectX9)
|
||||
throw FlycastException("DirectX 9 doesn't support Naomi 2 games. Select a different graphics API");
|
||||
|
||||
if (settings.platform.isConsole())
|
||||
{
|
||||
if (settings.content.path.empty())
|
||||
|
|
|
@ -270,11 +270,9 @@ struct State
|
|||
{
|
||||
static constexpr u32 Null = 0xffffffff;
|
||||
|
||||
int listType = -1;
|
||||
u32 gmp = Null;
|
||||
u32 instance = Null;
|
||||
u32 projMatrix = Null;
|
||||
u32 tileclip = 0;
|
||||
u32 lightModel = Null;
|
||||
u32 lights[MAX_LIGHTS] = {
|
||||
Null, Null, Null, Null, Null, Null, Null, Null,
|
||||
|
@ -286,11 +284,9 @@ struct State
|
|||
|
||||
void reset()
|
||||
{
|
||||
listType = -1;
|
||||
gmp = Null;
|
||||
instance = Null;
|
||||
projMatrix = Null;
|
||||
tileclip = 0;
|
||||
lightModel = Null;
|
||||
for (auto& light : lights)
|
||||
light = Null;
|
||||
|
@ -470,21 +466,6 @@ struct State
|
|||
elan::curLights[lightId] = plight;
|
||||
}
|
||||
|
||||
void setClipMode(PCW pcw)
|
||||
{
|
||||
tileclip = (tileclip & ~0xF0000000) | (pcw.userClip << 28);
|
||||
}
|
||||
|
||||
void setClipTiles(u32 xmin, u32 ymin, u32 xmax, u32 ymax)
|
||||
{
|
||||
u32 t = tileclip & 0xF0000000;
|
||||
t |= xmin & 0x3f; // 6 bits
|
||||
t |= (xmax & 0x3f) << 6; // 6 bits
|
||||
t |= (ymin & 0x1f) << 12; // 5 bits
|
||||
t |= (ymax & 0x1f) << 17; // 5 bits
|
||||
tileclip = t;
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
updateMatrix();
|
||||
|
@ -505,11 +486,11 @@ struct State
|
|||
|
||||
void serialize(Serializer& ser)
|
||||
{
|
||||
ser << listType;
|
||||
ser << ta_get_list_type();
|
||||
ser << gmp;
|
||||
ser << instance;
|
||||
ser << projMatrix;
|
||||
ser << tileclip;
|
||||
ser << ta_get_tileclip();
|
||||
ser << lightModel;
|
||||
ser << lights;
|
||||
}
|
||||
|
@ -521,11 +502,15 @@ struct State
|
|||
reset();
|
||||
return;
|
||||
}
|
||||
u32 listType;
|
||||
deser >> listType;
|
||||
ta_set_list_type(listType);
|
||||
deser >> gmp;
|
||||
deser >> instance;
|
||||
deser >> projMatrix;
|
||||
u32 tileclip;
|
||||
deser >> tileclip;
|
||||
ta_set_tileclip(tileclip);
|
||||
deser >> lightModel;
|
||||
deser >> lights;
|
||||
update();
|
||||
|
@ -592,12 +577,18 @@ static void setNormal(Vertex& vd, const T& vs)
|
|||
vd.nz = normal.z;
|
||||
}
|
||||
|
||||
static void addModelColors(glm::vec4& baseCol0, glm::vec4& offsetCol0, glm::vec4& baseCol1, glm::vec4& offsetCol1)
|
||||
static void setModelColors(glm::vec4& baseCol0, glm::vec4& offsetCol0, glm::vec4& baseCol1, glm::vec4& offsetCol1)
|
||||
{
|
||||
baseCol0 += gmpDiffuseColor0;
|
||||
offsetCol0 += gmpSpecularColor0;
|
||||
baseCol1 += gmpDiffuseColor1;
|
||||
offsetCol1 += gmpSpecularColor1;
|
||||
if (curGmp == nullptr)
|
||||
return;
|
||||
if (curGmp->paramSelect.d0)
|
||||
baseCol0 = gmpDiffuseColor0;
|
||||
if (curGmp->paramSelect.s0)
|
||||
offsetCol0 = gmpSpecularColor0;
|
||||
if (curGmp->paramSelect.d1)
|
||||
baseCol1 = gmpDiffuseColor1;
|
||||
if (curGmp->paramSelect.s1)
|
||||
offsetCol1 = gmpSpecularColor1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -609,11 +600,11 @@ void convertVertex(const N2_VERTEX& vs, Vertex& vd)
|
|||
setCoords(vd, vs.x, vs.y, vs.z);
|
||||
setNormal(vd, vs);
|
||||
SetEnvMapUV(vd);
|
||||
glm::vec4 baseCol0(0);
|
||||
glm::vec4 baseCol0(1);
|
||||
glm::vec4 offsetCol0(0);
|
||||
glm::vec4 baseCol1(0);
|
||||
glm::vec4 baseCol1(1);
|
||||
glm::vec4 offsetCol1(0);
|
||||
addModelColors(baseCol0, offsetCol0, baseCol1, offsetCol1);
|
||||
setModelColors(baseCol0, offsetCol0, baseCol1, offsetCol1);
|
||||
|
||||
*(u32 *)vd.col = packColor(baseCol0);
|
||||
*(u32 *)vd.spc = packColor(offsetCol0);
|
||||
|
@ -631,7 +622,7 @@ void convertVertex(const N2_VERTEX_VR& vs, Vertex& vd)
|
|||
glm::vec4 offsetCol0(0);
|
||||
glm::vec4 baseCol1 = unpackColor(vs.rgb.argb1);
|
||||
glm::vec4 offsetCol1(0);
|
||||
addModelColors(baseCol0, offsetCol0, baseCol1, offsetCol1);
|
||||
setModelColors(baseCol0, offsetCol0, baseCol1, offsetCol1);
|
||||
*(u32 *)vd.col = packColor(baseCol0);
|
||||
*(u32 *)vd.spc = packColor(offsetCol0);
|
||||
*(u32 *)vd.col1 = packColor(baseCol1);
|
||||
|
@ -644,11 +635,11 @@ void convertVertex(const N2_VERTEX_VU& vs, Vertex& vd)
|
|||
setCoords(vd, vs.x, vs.y, vs.z);
|
||||
setNormal(vd, vs);
|
||||
setUV(vs, vd);
|
||||
glm::vec4 baseCol0(0);
|
||||
glm::vec4 baseCol0(1);
|
||||
glm::vec4 offsetCol0(0);
|
||||
glm::vec4 baseCol1(0);
|
||||
glm::vec4 baseCol1(1);
|
||||
glm::vec4 offsetCol1(0);
|
||||
addModelColors(baseCol0, offsetCol0, baseCol1, offsetCol1);
|
||||
setModelColors(baseCol0, offsetCol0, baseCol1, offsetCol1);
|
||||
*(u32 *)vd.col = packColor(baseCol0);
|
||||
*(u32 *)vd.spc = packColor(offsetCol0);
|
||||
*(u32 *)vd.col1 = packColor(baseCol1);
|
||||
|
@ -665,7 +656,7 @@ void convertVertex(const N2_VERTEX_VUR& vs, Vertex& vd)
|
|||
glm::vec4 offsetCol0(0);
|
||||
glm::vec4 baseCol1 = unpackColor(vs.rgb.argb1);
|
||||
glm::vec4 offsetCol1(0);
|
||||
addModelColors(baseCol0, offsetCol0, baseCol1, offsetCol1);
|
||||
setModelColors(baseCol0, offsetCol0, baseCol1, offsetCol1);
|
||||
*(u32 *)vd.col = packColor(baseCol0);
|
||||
*(u32 *)vd.spc = packColor(offsetCol0);
|
||||
*(u32 *)vd.col1 = packColor(baseCol1);
|
||||
|
@ -678,11 +669,11 @@ void convertVertex(const N2_VERTEX_VUB& vs, Vertex& vd)
|
|||
setCoords(vd, vs.x, vs.y, vs.z);
|
||||
setNormal(vd, vs);
|
||||
setUV(vs, vd);
|
||||
glm::vec4 baseCol0(0);
|
||||
glm::vec4 baseCol0(1);
|
||||
glm::vec4 offsetCol0(0);
|
||||
glm::vec4 baseCol1(0);
|
||||
glm::vec4 baseCol1(1);
|
||||
glm::vec4 offsetCol1(0);
|
||||
addModelColors(baseCol0, offsetCol0, baseCol1, offsetCol1);
|
||||
setModelColors(baseCol0, offsetCol0, baseCol1, offsetCol1);
|
||||
*(u32 *)vd.col = packColor(baseCol0);
|
||||
*(u32 *)vd.col1 = packColor(baseCol1);
|
||||
// Stuff the bump map normals and parameters in the specular colors
|
||||
|
@ -1101,7 +1092,7 @@ static void sendMVPolygon(ICHList *list, const T *vtx, bool needClipping)
|
|||
mvp.isp.DepthMode &= 3;
|
||||
mvp.mvMatrix = taMVMatrix;
|
||||
mvp.projMatrix = taProjMatrix;
|
||||
ta_add_poly(state.listType, mvp);
|
||||
ta_add_poly(list->pcw.listType, mvp);
|
||||
|
||||
ModifierVolumeClipper clipper(needClipping);
|
||||
glm::vec3 vtx0{};
|
||||
|
@ -1162,11 +1153,11 @@ static void sendLights()
|
|||
model.lightCount = 0;
|
||||
if (curLightModel == nullptr)
|
||||
{
|
||||
model.useBaseOver = false;
|
||||
model.useBaseOver = 0;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
model.ambientMaterialBase[i] = false;
|
||||
model.ambientMaterialOffset[i] = false;
|
||||
model.ambientMaterialBase[i] = 0;
|
||||
model.ambientMaterialOffset[i] = 0;
|
||||
model.ambientBase[i][0] = model.ambientBase[i][1] = model.ambientBase[i][2] = model.ambientBase[i][3] = 1.f;
|
||||
}
|
||||
memset(model.ambientOffset, 0, sizeof(model.ambientOffset));
|
||||
|
@ -1253,7 +1244,6 @@ static void sendLights()
|
|||
static void setStateParams(PolyParam& pp, const ICHList *list)
|
||||
{
|
||||
sendLights();
|
||||
pp.tileclip = state.tileclip;
|
||||
pp.mvMatrix = taMVMatrix;
|
||||
pp.normalMatrix = taNormalMatrix;
|
||||
pp.projMatrix = taProjMatrix;
|
||||
|
@ -1310,7 +1300,7 @@ static void setStateParams(PolyParam& pp, const ICHList *list)
|
|||
pp.specularColor[1] = false;
|
||||
}
|
||||
// else if (pp.pcw.Volume == 1)
|
||||
// printf("2-Volume poly listType %d vtxtype %x gmp params %x diff tcw %08x tsp %08x\n", state.listType, list->flags, curGmp->paramSelect.full,
|
||||
// printf("2-Volume poly listType %d vtxtype %x gmp params %x diff tcw %08x tsp %08x\n", ta_get_list_type(), list->flags, curGmp->paramSelect.full,
|
||||
// pp.tcw.full ^ pp.tcw1.full, pp.tsp.full ^ pp.tsp1.full);
|
||||
}
|
||||
|
||||
|
@ -1325,7 +1315,10 @@ static void sendPolygon(ICHList *list)
|
|||
N2_VERTEX *vtx = (N2_VERTEX *)((u8 *)list + sizeof(ICHList));
|
||||
if (!isBetweenNearAndFar(vtx, list->vtxCount, needClipping))
|
||||
break;
|
||||
if (state.listType & 1)
|
||||
int listType = ta_get_list_type();
|
||||
if (listType == -1)
|
||||
listType = list->pcw.listType;
|
||||
if (listType & 1)
|
||||
sendMVPolygon(list, vtx, needClipping);
|
||||
else
|
||||
{
|
||||
|
@ -1339,7 +1332,7 @@ static void sendPolygon(ICHList *list)
|
|||
pp.tsp = list->tsp0;
|
||||
pp.tsp1 = list->tsp1;
|
||||
setStateParams(pp, list);
|
||||
ta_add_poly(state.listType, pp);
|
||||
ta_add_poly(pp);
|
||||
|
||||
sendVertices(list, vtx, needClipping);
|
||||
}
|
||||
|
@ -1351,7 +1344,10 @@ static void sendPolygon(ICHList *list)
|
|||
N2_VERTEX_VU *vtx = (N2_VERTEX_VU *)((u8 *)list + sizeof(ICHList));
|
||||
if (!isBetweenNearAndFar(vtx, list->vtxCount, needClipping))
|
||||
break;
|
||||
if (state.listType & 1)
|
||||
int listType = ta_get_list_type();
|
||||
if (listType == -1)
|
||||
listType = list->pcw.listType;
|
||||
if (listType & 1)
|
||||
sendMVPolygon(list, vtx, needClipping);
|
||||
else
|
||||
{
|
||||
|
@ -1367,7 +1363,7 @@ static void sendPolygon(ICHList *list)
|
|||
pp.tsp1 = list->tsp1;
|
||||
pp.tcw1 = list->tcw1;
|
||||
setStateParams(pp, list);
|
||||
ta_add_poly(state.listType, pp);
|
||||
ta_add_poly(pp);
|
||||
|
||||
sendVertices(list, vtx, needClipping);
|
||||
}
|
||||
|
@ -1391,7 +1387,7 @@ static void sendPolygon(ICHList *list)
|
|||
pp.tsp1 = list->tsp1;
|
||||
pp.tcw1 = list->tcw1;
|
||||
setStateParams(pp, list);
|
||||
ta_add_poly(state.listType, pp);
|
||||
ta_add_poly(pp);
|
||||
|
||||
sendVertices(list, vtx, needClipping);
|
||||
}
|
||||
|
@ -1412,7 +1408,7 @@ static void sendPolygon(ICHList *list)
|
|||
pp.tsp = list->tsp0;
|
||||
pp.tsp1 = list->tsp1;
|
||||
setStateParams(pp, list);
|
||||
ta_add_poly(state.listType, pp);
|
||||
ta_add_poly(pp);
|
||||
|
||||
sendVertices(list, vtx, needClipping);
|
||||
}
|
||||
|
@ -1437,7 +1433,7 @@ static void sendPolygon(ICHList *list)
|
|||
pp.tsp1 = list->tsp1;
|
||||
pp.tcw1 = list->tcw1;
|
||||
setStateParams(pp, list);
|
||||
ta_add_poly(state.listType, pp);
|
||||
ta_add_poly(pp);
|
||||
|
||||
sendVertices(list, vtx, needClipping);
|
||||
}
|
||||
|
@ -1526,7 +1522,7 @@ static void executeCommand(u8 *data, int size)
|
|||
if (Active)
|
||||
{
|
||||
cullingReversed = model->param.cwCulling == 0;
|
||||
state.setClipMode(model->pcw);
|
||||
ta_set_tileclip((model->pcw.userClip << 28) | (ta_get_tileclip() & 0x0fffffff));
|
||||
openModifierVolume = model->param.openVolume;
|
||||
shadowedVolume = model->pcw.shadow;
|
||||
modelTSP = model->tsp;
|
||||
|
@ -1591,20 +1587,20 @@ static void executeCommand(u8 *data, int size)
|
|||
if (link->offset & 0x80000000)
|
||||
{
|
||||
// elan v10 only
|
||||
DEBUG_LOG(PVR, "Texture DMA from %x to %x (%x)", DMAC_SAR(2), link->_res & 0x1ffffff8, link->size);
|
||||
memcpy(&vram[link->_res & VRAM_MASK], &mem_b[DMAC_SAR(2) & RAM_MASK], link->size);
|
||||
DEBUG_LOG(PVR, "Texture DMA from %x to %x (%x)", DMAC_SAR(2), link->vramAddress & 0x1ffffff8, link->size);
|
||||
memcpy(&vram[link->vramAddress & VRAM_MASK], &mem_b[DMAC_SAR(2) & RAM_MASK], link->size);
|
||||
reg74 |= 1;
|
||||
}
|
||||
else if (link->offset & 0x20000000)
|
||||
{
|
||||
// elan v10 only
|
||||
DEBUG_LOG(PVR, "Texture DMA from eram %x -> %x (%x)", link->offset & 0x01fffff8, link->_res & VRAM_MASK, link->size);
|
||||
memcpy(&vram[link->_res & VRAM_MASK], &RAM[link->offset & ELAN_RAM_MASK], link->size);
|
||||
DEBUG_LOG(PVR, "Texture DMA from eram %x -> %x (%x)", link->offset & ELAN_RAM_MASK, link->vramAddress & VRAM_MASK, link->size);
|
||||
memcpy(&vram[link->vramAddress & VRAM_MASK], &RAM[link->offset & ELAN_RAM_MASK], link->size);
|
||||
reg74 |= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(PVR, "Link to %x (%x)", link->offset & 0x1ffffff8, link->size);
|
||||
DEBUG_LOG(PVR, "Link to %8x (%x)", link->offset, link->size);
|
||||
executeCommand<Active>(&RAM[link->offset & ELAN_RAM_MASK], link->size);
|
||||
}
|
||||
size -= sizeof(Link);
|
||||
|
@ -1630,69 +1626,84 @@ static void executeCommand(u8 *data, int size)
|
|||
break;
|
||||
|
||||
default:
|
||||
DEBUG_LOG(PVR, "Unhandled Elan command %x", cmd->pcw.n2Command);
|
||||
WARN_LOG(PVR, "Unhandled Elan command %x", cmd->pcw.n2Command);
|
||||
size -= 32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 pcw = *(u32 *)data;
|
||||
if ((pcw & 0xd0ffff00) == 0x808c0000) // display list
|
||||
if (Active)
|
||||
{
|
||||
if (Active)
|
||||
{
|
||||
DEBUG_LOG(PVR, "Display list type %d", (pcw >> 24) & 0xf);
|
||||
state.reset();
|
||||
state.listType = (pcw >> 24) & 0xf;
|
||||
// TODO is this the right place for this?
|
||||
SQBuffer eol{};
|
||||
ta_vtx_data32(&eol);
|
||||
u32 pcw = *(u32 *)data;
|
||||
DEBUG_LOG(PVR, "Geometry type %d - %08x", (pcw >> 24) & 0xf, pcw);
|
||||
try {
|
||||
size -= ta_add_ta_data((u32 *)data, size);
|
||||
} catch (const TAParserException& e) {
|
||||
size = 0;
|
||||
}
|
||||
size -= 24 * 4;
|
||||
}
|
||||
else if ((pcw & 0xd0fcff00) == 0x80800000) // User clipping
|
||||
{
|
||||
if (Active)
|
||||
{
|
||||
state.setClipMode((PCW&)pcw);
|
||||
DEBUG_LOG(PVR, "User clip type %d", ((PCW&)pcw).userClip);
|
||||
}
|
||||
size -= 0xE0;
|
||||
}
|
||||
else if ((pcw & 0xd0ffff00) == 0x80000000) // geometry follows or linked?
|
||||
{
|
||||
if (Active)
|
||||
{
|
||||
DEBUG_LOG(PVR, "Geometry type %d - %08x", (pcw >> 24) & 0xf, pcw);
|
||||
state.listType = (pcw >> 24) & 0xf;
|
||||
size -= 32;
|
||||
ta_add_ta_data(state.listType, (u32 *)(data + 32), size - 32);
|
||||
}
|
||||
size = 32;
|
||||
}
|
||||
else if (pcw == 0x20000000)
|
||||
{
|
||||
// User clipping
|
||||
if (Active)
|
||||
{
|
||||
u32 *tiles = (u32 *)data + 4;
|
||||
DEBUG_LOG(PVR, "User clipping %d,%d - %d,%d", tiles[0] * 32, tiles[1] * 32,
|
||||
tiles[2] * 32, tiles[3] * 32);
|
||||
state.setClipTiles(tiles[0], tiles[1], tiles[2], tiles[3]);
|
||||
}
|
||||
size -= 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Active)
|
||||
u32 vertexSize = 32;
|
||||
int listType = ta_get_list_type();
|
||||
int i = 0;
|
||||
while (i < size)
|
||||
{
|
||||
if (pcw != 0)
|
||||
INFO_LOG(PVR, "Unhandled command %x", pcw);
|
||||
for (int i = 0; i < 32; i += 4)
|
||||
DEBUG_LOG(PVR, " %08x: %08x", (u32)(&data[i] - RAM), *(u32 *)&data[i]);
|
||||
PCW pcw = *(PCW *)&data[i];
|
||||
if (pcw.naomi2 == 1)
|
||||
break;
|
||||
switch (pcw.paraType)
|
||||
{
|
||||
case ParamType_End_Of_List:
|
||||
listType = -1;
|
||||
i += 32;
|
||||
break;
|
||||
case ParamType_Object_List_Set:
|
||||
case ParamType_User_Tile_Clip:
|
||||
i += 32;
|
||||
break;
|
||||
case ParamType_Polygon_or_Modifier_Volume:
|
||||
{
|
||||
static const u32 * const PolyTypeLut = TaTypeLut::instance().table;
|
||||
|
||||
if (listType == -1)
|
||||
listType = pcw.listType;
|
||||
if (listType & 1)
|
||||
{
|
||||
// modifier volumes
|
||||
vertexSize = 64;
|
||||
i += 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 polyId = PolyTypeLut[pcw.objectControl];
|
||||
u32 polySize = polyId >> 30;
|
||||
u32 vertexType = (u8)polyId;
|
||||
if (vertexType == 5 || vertexType == 6 || (vertexType >= 11 && vertexType <= 14))
|
||||
vertexSize = 64;
|
||||
else
|
||||
vertexSize = 32;
|
||||
i += polySize == SZ64 ? 64 : 32;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ParamType_Sprite:
|
||||
if (listType == -1)
|
||||
listType = pcw.listType;
|
||||
vertexSize = 64;
|
||||
i += 32;
|
||||
break;
|
||||
case ParamType_Vertex_Parameter:
|
||||
i += vertexSize;
|
||||
break;
|
||||
default:
|
||||
WARN_LOG(PVR, "Invalid param type %d", pcw.paraType);
|
||||
i = size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
size -= 32;
|
||||
size -= i;
|
||||
}
|
||||
}
|
||||
data += oldSize - size;
|
||||
|
|
|
@ -65,6 +65,7 @@ union PCW
|
|||
u32 endOfStrip : 1;
|
||||
u32 paraType : 3;
|
||||
};
|
||||
u8 objectControl;
|
||||
u32 full;
|
||||
};
|
||||
|
||||
|
@ -382,7 +383,7 @@ struct Link : public ElanBase
|
|||
{
|
||||
// 08000f00
|
||||
u32 offset;
|
||||
u32 _res; // 09000000
|
||||
u32 vramAddress; // for texture DMA xfers, otherwise 09000000
|
||||
u32 size;
|
||||
u32 _res0[4];
|
||||
};
|
||||
|
|
|
@ -45,6 +45,7 @@ void reset(bool hard)
|
|||
rend_reset();
|
||||
tactx_Term();
|
||||
elan::reset(hard);
|
||||
ta_parse_reset();
|
||||
}
|
||||
|
||||
void init()
|
||||
|
|
|
@ -263,6 +263,203 @@ static NOINLINE void DYNACALL ta_handle_cmd(u32 trans)
|
|||
|
||||
static OnLoad ol_fillfsm(&fill_fsm);
|
||||
|
||||
/*
|
||||
Volume,Col_Type,Texture,Offset,Gouraud,16bit_UV
|
||||
|
||||
0 0 0 (0) x invalid Polygon Type 0 Polygon Type 0
|
||||
0 0 1 x x 0 Polygon Type 0 Polygon Type 3
|
||||
0 0 1 x x 1 Polygon Type 0 Polygon Type 4
|
||||
|
||||
0 1 0 (0) x invalid Polygon Type 0 Polygon Type 1
|
||||
0 1 1 x x 0 Polygon Type 0 Polygon Type 5
|
||||
0 1 1 x x 1 Polygon Type 0 Polygon Type 6
|
||||
|
||||
0 2 0 (0) x invalid Polygon Type 1 Polygon Type 2
|
||||
0 2 1 0 x 0 Polygon Type 1 Polygon Type 7
|
||||
0 2 1 0 x 1 Polygon Type 1 Polygon Type 8
|
||||
0 2 1 1 x 0 Polygon Type 2 Polygon Type 7
|
||||
0 2 1 1 x 1 Polygon Type 2 Polygon Type 8
|
||||
|
||||
0 3 0 (0) x invalid Polygon Type 0 Polygon Type 2
|
||||
0 3 1 x x 0 Polygon Type 0 Polygon Type 7
|
||||
0 3 1 x x 1 Polygon Type 0 Polygon Type 8
|
||||
|
||||
1 0 0 (0) x invalid Polygon Type 3 Polygon Type 9
|
||||
1 0 1 x x 0 Polygon Type 3 Polygon Type 11
|
||||
1 0 1 x x 1 Polygon Type 3 Polygon Type 12
|
||||
|
||||
1 2 0 (0) x invalid Polygon Type 4 Polygon Type 10
|
||||
1 2 1 x x 0 Polygon Type 4 Polygon Type 13
|
||||
1 2 1 x x 1 Polygon Type 4 Polygon Type 14
|
||||
|
||||
1 3 0 (0) x invalid Polygon Type 3 Polygon Type 10
|
||||
1 3 1 x x 0 Polygon Type 3 Polygon Type 13
|
||||
1 3 1 x x 1 Polygon Type 3 Polygon Type 14
|
||||
|
||||
Sprites :
|
||||
(0) (0) 0 (0) (0) invalid Sprite Sprite Type 0
|
||||
(0) (0) 1 x (0) (1) Sprite Sprite Type 1
|
||||
|
||||
*/
|
||||
//helpers 0-14
|
||||
u32 TaTypeLut::poly_data_type_id(PCW pcw)
|
||||
{
|
||||
if (pcw.Texture)
|
||||
{
|
||||
//textured
|
||||
if (pcw.Volume==0)
|
||||
{ //single volume
|
||||
if (pcw.Col_Type==0)
|
||||
{
|
||||
if (pcw.UV_16bit==0)
|
||||
return 3; //(Textured, Packed Color , 32b uv)
|
||||
else
|
||||
return 4; //(Textured, Packed Color , 16b uv)
|
||||
}
|
||||
else if (pcw.Col_Type==1)
|
||||
{
|
||||
if (pcw.UV_16bit==0)
|
||||
return 5; //(Textured, Floating Color , 32b uv)
|
||||
else
|
||||
return 6; //(Textured, Floating Color , 16b uv)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pcw.UV_16bit==0)
|
||||
return 7; //(Textured, Intensity , 32b uv)
|
||||
else
|
||||
return 8; //(Textured, Intensity , 16b uv)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//two volumes
|
||||
if (pcw.Col_Type==0)
|
||||
{
|
||||
if (pcw.UV_16bit==0)
|
||||
return 11; //(Textured, Packed Color, with Two Volumes)
|
||||
|
||||
else
|
||||
return 12; //(Textured, Packed Color, 16bit UV, with Two Volumes)
|
||||
|
||||
}
|
||||
else if (pcw.Col_Type==1)
|
||||
{
|
||||
//die ("invalid");
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pcw.UV_16bit==0)
|
||||
return 13; //(Textured, Intensity, with Two Volumes)
|
||||
|
||||
else
|
||||
return 14; //(Textured, Intensity, 16bit UV, with Two Volumes)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//non textured
|
||||
if (pcw.Volume==0)
|
||||
{ //single volume
|
||||
if (pcw.Col_Type==0)
|
||||
return 0; //(Non-Textured, Packed Color)
|
||||
else if (pcw.Col_Type==1)
|
||||
return 1; //(Non-Textured, Floating Color)
|
||||
else
|
||||
return 2; //(Non-Textured, Intensity)
|
||||
}
|
||||
else
|
||||
{
|
||||
//two volumes
|
||||
if (pcw.Col_Type==0)
|
||||
return 9; //(Non-Textured, Packed Color, with Two Volumes)
|
||||
else if (pcw.Col_Type==1)
|
||||
{
|
||||
//die ("invalid");
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 10; //(Non-Textured, Intensity, with Two Volumes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//0-4 | 0x80
|
||||
u32 TaTypeLut::poly_header_type_size(PCW pcw)
|
||||
{
|
||||
if (pcw.Volume == 0)
|
||||
{
|
||||
if ( pcw.Col_Type<2 ) //0,1
|
||||
{
|
||||
return 0 | 0; //Polygon Type 0 -- SZ32
|
||||
}
|
||||
else if ( pcw.Col_Type == 2 )
|
||||
{
|
||||
if (pcw.Texture)
|
||||
{
|
||||
if (pcw.Offset)
|
||||
{
|
||||
return 2 | 0x80; //Polygon Type 2 -- SZ64
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1 | 0; //Polygon Type 1 -- SZ32
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1 | 0; //Polygon Type 1 -- SZ32
|
||||
}
|
||||
}
|
||||
else //col_type ==3
|
||||
{
|
||||
return 0 | 0; //Polygon Type 0 -- SZ32
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pcw.Col_Type==0 ) //0
|
||||
{
|
||||
return 3 | 0; //Polygon Type 3 -- SZ32
|
||||
}
|
||||
else if ( pcw.Col_Type==2 ) //2
|
||||
{
|
||||
return 4 | 0x80; //Polygon Type 4 -- SZ64
|
||||
}
|
||||
else if ( pcw.Col_Type==3 ) //3
|
||||
{
|
||||
return 3 | 0; //Polygon Type 3 -- SZ32
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0xFFDDEEAA;//die ("data->pcw.Col_Type==1 && volume ==1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TaTypeLut::TaTypeLut()
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
PCW pcw;
|
||||
pcw.obj_ctrl = i;
|
||||
u32 rv = poly_data_type_id(pcw);
|
||||
u32 type = poly_header_type_size(pcw);
|
||||
|
||||
if (type & 0x80)
|
||||
rv |= SZ64 << 30;
|
||||
else
|
||||
rv |= SZ32 << 30;
|
||||
|
||||
rv |= (type & 0x7F) << 8;
|
||||
|
||||
table[i] = rv;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 opbSize(int n)
|
||||
{
|
||||
return n == 0 ? 0 : 16 << n;
|
||||
|
@ -305,10 +502,13 @@ void ta_vtx_ListInit()
|
|||
|
||||
ta_cur_state = TAS_NS;
|
||||
ta_fsm_cl = 7;
|
||||
if (settings.platform.isNaomi2())
|
||||
ta_parse_reset();
|
||||
}
|
||||
|
||||
void ta_vtx_SoftReset()
|
||||
{
|
||||
ta_cur_state=TAS_NS;
|
||||
ta_cur_state = TAS_NS;
|
||||
}
|
||||
|
||||
static INLINE
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include "ta_ctx.h"
|
||||
#include "hw/sh4/sh4_if.h"
|
||||
|
||||
constexpr u32 SZ32 = 1;
|
||||
constexpr u32 SZ64 = 2;
|
||||
|
||||
struct TA_context;
|
||||
|
||||
void ta_vtx_ListInit();
|
||||
|
@ -25,4 +28,6 @@ public:
|
|||
|
||||
private:
|
||||
TaTypeLut();
|
||||
u32 poly_data_type_id(PCW pcw);
|
||||
u32 poly_header_type_size(PCW pcw);
|
||||
};
|
||||
|
|
|
@ -195,30 +195,34 @@ struct N2Light
|
|||
float color[4];
|
||||
float direction[4]; // For parallel/spot
|
||||
float position[4]; // For spot/point
|
||||
|
||||
int parallel;
|
||||
int diffuse[2];
|
||||
int specular[2];
|
||||
int routing;
|
||||
int dmode;
|
||||
int smode;
|
||||
|
||||
int distAttnMode; // For spot/point
|
||||
int diffuse[2];
|
||||
int specular[2];
|
||||
|
||||
float attnDistA;
|
||||
float attnDistB;
|
||||
float attnAngleA; // For spot
|
||||
float attnAngleB;
|
||||
int distAttnMode; // For spot/point
|
||||
int _pad[3];
|
||||
};
|
||||
|
||||
struct N2LightModel
|
||||
{
|
||||
N2Light lights[16];
|
||||
int lightCount;
|
||||
|
||||
float ambientBase[2][4]; // base ambient colors
|
||||
float ambientOffset[2][4]; // offset ambient colors
|
||||
bool ambientMaterialBase[2]; // base ambient light is multiplied by model material/color
|
||||
bool ambientMaterialOffset[2]; // offset ambient light is multiplied by model material/color
|
||||
bool useBaseOver; // base color overflows into offset color
|
||||
int ambientMaterialBase[2]; // base ambient light is multiplied by model material/color
|
||||
int ambientMaterialOffset[2];// offset ambient light is multiplied by model material/color
|
||||
|
||||
int lightCount;
|
||||
int useBaseOver; // base color overflows into offset color
|
||||
int bumpId1; // Light index for vol0 bump mapping
|
||||
int bumpId2; // Light index for vol1 bump mapping
|
||||
};
|
||||
|
@ -391,11 +395,22 @@ bool rend_framePending();
|
|||
void SerializeTAContext(Serializer& ser);
|
||||
void DeserializeTAContext(Deserializer& deser);
|
||||
|
||||
void ta_add_poly(int type, const PolyParam& pp);
|
||||
void ta_add_poly(int type, const ModifierVolumeParam& mvp);
|
||||
void ta_add_poly(const PolyParam& pp);
|
||||
void ta_add_poly(int listType, const ModifierVolumeParam& mvp);
|
||||
void ta_add_vertex(const Vertex& vtx);
|
||||
void ta_add_triangle(const ModTriangle& tri);
|
||||
float* ta_add_matrix(const float *matrix);
|
||||
N2LightModel *ta_add_light(const N2LightModel& light);
|
||||
void ta_add_ta_data(int listType, u32 *data, u32 size);
|
||||
u32 ta_add_ta_data(u32 *data, u32 size);
|
||||
int getTAContextAddresses(u32 *addresses);
|
||||
u32 ta_get_tileclip();
|
||||
void ta_set_tileclip(u32 tileclip);
|
||||
u32 ta_get_list_type();
|
||||
void ta_set_list_type(u32 listType);
|
||||
void ta_parse_reset();
|
||||
|
||||
class TAParserException : public FlycastException
|
||||
{
|
||||
public:
|
||||
TAParserException() : FlycastException("") {}
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -171,31 +171,26 @@ const char * const DX11N2ColorShader = R"(
|
|||
#define LMODE_THIN_SURFACE 4
|
||||
#define LMODE_BUMP_MAP 5
|
||||
|
||||
#define ROUTING_BASEDIFF_BASESPEC_ADD 0
|
||||
#define ROUTING_BASEDIFF_OFFSSPEC_ADD 1
|
||||
#define ROUTING_OFFSDIFF_BASESPEC_ADD 2
|
||||
#define ROUTING_OFFSDIFF_OFFSSPEC_ADD 3
|
||||
#define ROUTING_ALPHADIFF_ADD 4
|
||||
#define ROUTING_ALPHAATTEN_ADD 5
|
||||
#define ROUTING_FOGDIFF_ADD 6
|
||||
#define ROUTING_FOGATTENUATION_ADD 7
|
||||
#define ROUTING_BASEDIFF_BASESPEC_SUB 8
|
||||
#define ROUTING_BASEDIFF_OFFSSPEC_SUB 9
|
||||
#define ROUTING_OFFSDIFF_BASESPEC_SUB 10
|
||||
#define ROUTING_OFFSDIFF_OFFSSPEC_SUB 11
|
||||
#define ROUTING_ALPHADIFF_SUB 12
|
||||
#define ROUTING_ALPHAATTEN_SUB 13
|
||||
#define ROUTING_SPEC_TO_OFFSET 1
|
||||
#define ROUTING_DIFF_TO_OFFSET 2
|
||||
#define ROUTING_ATTENUATION 1 // not handled
|
||||
#define ROUTING_FOG 2 // not handled
|
||||
#define ROUTING_ALPHA 4
|
||||
#define ROUTING_SUB 8
|
||||
|
||||
struct N2Light
|
||||
{
|
||||
float4 color;
|
||||
float4 direction;
|
||||
float4 position;
|
||||
|
||||
int parallel;
|
||||
int routing;
|
||||
int dmode;
|
||||
int smode;
|
||||
|
||||
int4 diffuse_specular; // diffuse0, diffuse1, specular0, specular1
|
||||
|
||||
float attnDistA;
|
||||
float attnDistB;
|
||||
float attnAngleA;
|
||||
|
@ -207,10 +202,12 @@ struct N2Light
|
|||
cbuffer lightConstants : register(b2)
|
||||
{
|
||||
N2Light lights[16];
|
||||
int lightCount;
|
||||
|
||||
float4 ambientBase[2];
|
||||
float4 ambientOffset[2];
|
||||
int4 ambientMaterial; // base0, base1, offset0, offset1
|
||||
|
||||
int lightCount;
|
||||
int useBaseOver;
|
||||
int bumpId0;
|
||||
int bumpId1;
|
||||
|
@ -256,7 +253,7 @@ void computeColors(inout float4 baseCol, inout float4 offsetCol, in int volIdx,
|
|||
int routing = light.routing;
|
||||
if (light.diffuse_specular[volIdx] == 1) // If light contributes to diffuse
|
||||
{
|
||||
float factor = BASE_FACTOR;
|
||||
float factor = (routing & ROUTING_SUB) != 0 ? -BASE_FACTOR : BASE_FACTOR;
|
||||
switch (light.dmode)
|
||||
{
|
||||
case LMODE_SINGLE_SIDED:
|
||||
|
@ -266,16 +263,19 @@ void computeColors(inout float4 baseCol, inout float4 offsetCol, in int volIdx,
|
|||
factor *= abs(dot(normal, lightDir));
|
||||
break;
|
||||
}
|
||||
if (routing == ROUTING_ALPHADIFF_SUB)
|
||||
diffuseAlpha -= lightColor.r * factor;
|
||||
else if (routing == ROUTING_BASEDIFF_BASESPEC_ADD || routing == ROUTING_BASEDIFF_OFFSSPEC_ADD)
|
||||
diffuse += lightColor * factor;
|
||||
if (routing == ROUTING_OFFSDIFF_BASESPEC_ADD || routing == ROUTING_OFFSDIFF_OFFSSPEC_ADD)
|
||||
specular += lightColor * factor;
|
||||
if ((routing & ROUTING_ALPHA) != 0)
|
||||
diffuseAlpha += lightColor.r * factor;
|
||||
else
|
||||
{
|
||||
if ((routing & ROUTING_DIFF_TO_OFFSET) == 0)
|
||||
diffuse += lightColor * factor;
|
||||
else
|
||||
specular += lightColor * factor;
|
||||
}
|
||||
}
|
||||
if (light.diffuse_specular[2 + volIdx] == 1) // If light contributes to specular
|
||||
{
|
||||
float factor = BASE_FACTOR;
|
||||
float factor = (routing & ROUTING_SUB) != 0 ? -BASE_FACTOR : BASE_FACTOR;
|
||||
switch (light.smode)
|
||||
{
|
||||
case LMODE_SINGLE_SIDED:
|
||||
|
@ -285,12 +285,15 @@ void computeColors(inout float4 baseCol, inout float4 offsetCol, in int volIdx,
|
|||
factor *= saturate(pow(abs(dot(lightDir, reflectDir)), glossCoef[volIdx]));
|
||||
break;
|
||||
}
|
||||
if (routing == ROUTING_ALPHADIFF_SUB)
|
||||
specularAlpha -= lightColor.r * factor;
|
||||
else if (routing == ROUTING_OFFSDIFF_OFFSSPEC_ADD || routing == ROUTING_BASEDIFF_OFFSSPEC_ADD)
|
||||
specular += lightColor * factor;
|
||||
if (routing == ROUTING_BASEDIFF_BASESPEC_ADD || routing == ROUTING_OFFSDIFF_BASESPEC_ADD)
|
||||
diffuse += lightColor * factor;
|
||||
if ((routing & ROUTING_ALPHA) != 0)
|
||||
specularAlpha += lightColor.r * factor;
|
||||
else
|
||||
{
|
||||
if ((routing & ROUTING_SPEC_TO_OFFSET) == 0)
|
||||
diffuse += lightColor * factor;
|
||||
else
|
||||
specular += lightColor * factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ambient with material
|
||||
|
@ -399,46 +402,6 @@ struct N2PolyConstants
|
|||
};
|
||||
static_assert(sizeof(N2PolyConstants) == 256, "sizeof(N2PolyConstants) should be 256");
|
||||
|
||||
struct DX11N2Light
|
||||
{
|
||||
float color[4]; // 0
|
||||
float direction[4]; // 16
|
||||
float position[4]; // 32
|
||||
int parallel; // 48
|
||||
int routing; // 52
|
||||
int dmode; // 56
|
||||
int smode; // 60
|
||||
// int4 diffuse_specular
|
||||
int diffuse[2]; // 64
|
||||
int specular[2]; // 72
|
||||
float attnDistA; // 80
|
||||
float attnDistB; // 84
|
||||
float attnAngleA; // 88
|
||||
float attnAngleB; // 92
|
||||
int distAttnMode; // 96
|
||||
int _pad[3];
|
||||
// 112
|
||||
};
|
||||
static_assert(sizeof(DX11N2Light) == 112, "sizeof(DX11N2Light) should be 112");
|
||||
|
||||
struct N2LightConstants
|
||||
{
|
||||
DX11N2Light lights[16]; // 0
|
||||
int lightCount; // 1792
|
||||
int _pad0[3];
|
||||
float ambientBase[2][4]; // 1808
|
||||
float ambientOffset[2][4]; // 1840
|
||||
// int4 ambientMaterial
|
||||
int ambientMaterialBase[2]; // 1872
|
||||
int ambientMaterialOffset[2]; // 1880
|
||||
int useBaseOver; // 1888
|
||||
int bumpId1; // 1892
|
||||
int bumpId2; // 1896
|
||||
int _pad3; // 1900
|
||||
// 1904
|
||||
};
|
||||
static_assert(sizeof(N2LightConstants) == 1904, "sizeof(N2LightConstants) should be 1904");
|
||||
|
||||
void Naomi2Helper::init(ComPtr<ID3D11Device>& device, ComPtr<ID3D11DeviceContext> deviceContext)
|
||||
{
|
||||
this->deviceContext = deviceContext;
|
||||
|
@ -451,7 +414,7 @@ void Naomi2Helper::init(ComPtr<ID3D11Device>& device, ComPtr<ID3D11DeviceContex
|
|||
if (FAILED(device->CreateBuffer(&desc, nullptr, &polyConstantsBuffer.get())))
|
||||
WARN_LOG(RENDERER, "Per-polygon constants buffer creation failed");
|
||||
|
||||
desc.ByteWidth = sizeof(N2LightConstants);
|
||||
desc.ByteWidth = sizeof(N2LightModel);
|
||||
desc.ByteWidth = (((desc.ByteWidth - 1) >> 4) + 1) << 4;
|
||||
if (FAILED(device->CreateBuffer(&desc, nullptr, &lightConstantsBuffer.get())))
|
||||
WARN_LOG(RENDERER, "Light constants buffer creation failed");
|
||||
|
@ -481,57 +444,13 @@ void Naomi2Helper::setConstants(const PolyParam& pp, u32 polyNumber)
|
|||
if (pp.lightModel != lastModel)
|
||||
{
|
||||
lastModel = pp.lightModel;
|
||||
N2LightConstants lightConstants{};
|
||||
if (pp.lightModel != nullptr)
|
||||
{
|
||||
const N2LightModel& lights = *pp.lightModel;
|
||||
lightConstants.lightCount = lights.lightCount;
|
||||
for (int i = 0; i < lights.lightCount; i++)
|
||||
{
|
||||
DX11N2Light& light = lightConstants.lights[i];
|
||||
memcpy(light.color, lights.lights[i].color, sizeof(light.color));
|
||||
memcpy(light.direction, lights.lights[i].direction, sizeof(light.direction));
|
||||
memcpy(light.position, lights.lights[i].position, sizeof(light.position));
|
||||
light.parallel = lights.lights[i].parallel;
|
||||
light.routing = lights.lights[i].routing;
|
||||
light.dmode = lights.lights[i].dmode;
|
||||
light.smode = lights.lights[i].smode;
|
||||
memcpy(light.diffuse, lights.lights[i].diffuse, sizeof(light.diffuse));
|
||||
memcpy(light.specular, lights.lights[i].specular, sizeof(light.specular));
|
||||
light.attnDistA = lights.lights[i].attnDistA;
|
||||
light.attnDistB = lights.lights[i].attnDistB;
|
||||
light.attnAngleA = lights.lights[i].attnAngleA;
|
||||
light.attnAngleB = lights.lights[i].attnAngleB;
|
||||
light.distAttnMode = lights.lights[i].distAttnMode;
|
||||
}
|
||||
memcpy(lightConstants.ambientBase, lights.ambientBase, sizeof(lightConstants.ambientBase));
|
||||
memcpy(lightConstants.ambientOffset, lights.ambientOffset, sizeof(lightConstants.ambientOffset));
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
lightConstants.ambientMaterialBase[i] = lights.ambientMaterialBase[i];
|
||||
lightConstants.ambientMaterialOffset[i] = lights.ambientMaterialOffset[i];
|
||||
}
|
||||
lightConstants.useBaseOver = lights.useBaseOver;
|
||||
lightConstants.bumpId1 = lights.bumpId1;
|
||||
lightConstants.bumpId2 = lights.bumpId2;
|
||||
}
|
||||
setConstBuffer(lightConstantsBuffer, *pp.lightModel);
|
||||
else
|
||||
{
|
||||
lightConstants.lightCount = 0;
|
||||
float white[] { 1.f, 1.f, 1.f, 1.f };
|
||||
float black[4]{};
|
||||
for (int vol = 0; vol < 2; vol++)
|
||||
{
|
||||
lightConstants.ambientMaterialBase[vol] = 0;
|
||||
lightConstants.ambientMaterialOffset[vol] = 0;
|
||||
memcpy(lightConstants.ambientBase[vol], white, sizeof(white));
|
||||
memcpy(lightConstants.ambientOffset[vol], black, sizeof(black));
|
||||
}
|
||||
lightConstants.useBaseOver = 0;
|
||||
lightConstants.bumpId1 = -1;
|
||||
lightConstants.bumpId2 = -1;
|
||||
N2LightModel lightModel{};
|
||||
setConstBuffer(lightConstantsBuffer, lightModel);
|
||||
}
|
||||
setConstBuffer(lightConstantsBuffer, lightConstants);
|
||||
deviceContext->VSSetConstantBuffers(2, 1, &lightConstantsBuffer.get());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -880,13 +880,16 @@ static void create_modvol_shader()
|
|||
gl.modvol_shader.sp_ShaderColor = glGetUniformLocation(gl.modvol_shader.program, "sp_ShaderColor");
|
||||
gl.modvol_shader.depth_scale = glGetUniformLocation(gl.modvol_shader.program, "depth_scale");
|
||||
|
||||
N2VertexSource n2vertexShader(false, true, false);
|
||||
gl.n2ModVolShader.program = gl_CompileAndLink(n2vertexShader.generate().c_str(), fragmentShader.generate().c_str());
|
||||
gl.n2ModVolShader.ndcMat = glGetUniformLocation(gl.n2ModVolShader.program, "ndcMat");
|
||||
gl.n2ModVolShader.sp_ShaderColor = glGetUniformLocation(gl.n2ModVolShader.program, "sp_ShaderColor");
|
||||
gl.n2ModVolShader.depth_scale = glGetUniformLocation(gl.n2ModVolShader.program, "depth_scale");
|
||||
gl.n2ModVolShader.mvMat = glGetUniformLocation(gl.n2ModVolShader.program, "mvMat");
|
||||
gl.n2ModVolShader.projMat = glGetUniformLocation(gl.n2ModVolShader.program, "projMat");
|
||||
if (gl.gl_major >= 3)
|
||||
{
|
||||
N2VertexSource n2vertexShader(false, true, false);
|
||||
gl.n2ModVolShader.program = gl_CompileAndLink(n2vertexShader.generate().c_str(), fragmentShader.generate().c_str());
|
||||
gl.n2ModVolShader.ndcMat = glGetUniformLocation(gl.n2ModVolShader.program, "ndcMat");
|
||||
gl.n2ModVolShader.sp_ShaderColor = glGetUniformLocation(gl.n2ModVolShader.program, "sp_ShaderColor");
|
||||
gl.n2ModVolShader.depth_scale = glGetUniformLocation(gl.n2ModVolShader.program, "depth_scale");
|
||||
gl.n2ModVolShader.mvMat = glGetUniformLocation(gl.n2ModVolShader.program, "mvMat");
|
||||
gl.n2ModVolShader.projMat = glGetUniformLocation(gl.n2ModVolShader.program, "projMat");
|
||||
}
|
||||
}
|
||||
|
||||
bool gl_create_resources()
|
||||
|
|
|
@ -94,7 +94,7 @@ void main()
|
|||
#if LIGHT_ON == 1
|
||||
// FIXME need offset0 and offset1 for bump maps
|
||||
if (bumpMapping == 1)
|
||||
computeBumpMap(vtx_offs, vtx_offs1, vpos.xyz, vnorm, normalMat);
|
||||
computeBumpMap(vtx_offs, vtx_offs1, vpos.xyz, in_normal, normalMat);
|
||||
else
|
||||
{
|
||||
computeColors(vtx_base1, vtx_offs1, 1, vpos.xyz, vnorm);
|
||||
|
@ -144,20 +144,12 @@ const char* N2ColorShader = R"(
|
|||
#define LMODE_THIN_SURFACE 4
|
||||
#define LMODE_BUMP_MAP 5
|
||||
|
||||
#define ROUTING_BASEDIFF_BASESPEC_ADD 0
|
||||
#define ROUTING_BASEDIFF_OFFSSPEC_ADD 1
|
||||
#define ROUTING_OFFSDIFF_BASESPEC_ADD 2
|
||||
#define ROUTING_OFFSDIFF_OFFSSPEC_ADD 3
|
||||
#define ROUTING_ALPHADIFF_ADD 4
|
||||
#define ROUTING_ALPHAATTEN_ADD 5
|
||||
#define ROUTING_FOGDIFF_ADD 6
|
||||
#define ROUTING_FOGATTENUATION_ADD 7
|
||||
#define ROUTING_BASEDIFF_BASESPEC_SUB 8
|
||||
#define ROUTING_BASEDIFF_OFFSSPEC_SUB 9
|
||||
#define ROUTING_OFFSDIFF_BASESPEC_SUB 10
|
||||
#define ROUTING_OFFSDIFF_OFFSSPEC_SUB 11
|
||||
#define ROUTING_ALPHADIFF_SUB 12
|
||||
#define ROUTING_ALPHAATTEN_SUB 13
|
||||
#define ROUTING_SPEC_TO_OFFSET 1
|
||||
#define ROUTING_DIFF_TO_OFFSET 2
|
||||
#define ROUTING_ATTENUATION 1 // not handled
|
||||
#define ROUTING_FOG 2 // not handled
|
||||
#define ROUTING_ALPHA 4
|
||||
#define ROUTING_SUB 8
|
||||
|
||||
struct N2Light
|
||||
{
|
||||
|
@ -232,33 +224,39 @@ void computeColors(inout vec4 baseCol, inout vec4 offsetCol, int volIdx, vec3 po
|
|||
}
|
||||
if (lights[i].diffuse[volIdx] == 1)
|
||||
{
|
||||
float factor = BASE_FACTOR;
|
||||
float factor = (lights[i].routing & ROUTING_SUB) != 0 ? -BASE_FACTOR : BASE_FACTOR;
|
||||
if (lights[i].dmode == LMODE_SINGLE_SIDED)
|
||||
factor *= max(dot(normal, lightDir), 0.0);
|
||||
else if (lights[i].dmode == LMODE_DOUBLE_SIDED)
|
||||
factor *= abs(dot(normal, lightDir));
|
||||
|
||||
if (lights[i].routing == ROUTING_ALPHADIFF_SUB)
|
||||
diffuseAlpha -= lightColor.r * factor;
|
||||
else if (lights[i].routing == ROUTING_BASEDIFF_BASESPEC_ADD || lights[i].routing == ROUTING_BASEDIFF_OFFSSPEC_ADD)
|
||||
diffuse += lightColor * factor;
|
||||
if (lights[i].routing == ROUTING_OFFSDIFF_BASESPEC_ADD || lights[i].routing == ROUTING_OFFSDIFF_OFFSSPEC_ADD)
|
||||
specular += lightColor * factor;
|
||||
if ((lights[i].routing & ROUTING_ALPHA) != 0)
|
||||
diffuseAlpha += lightColor.r * factor;
|
||||
else
|
||||
{
|
||||
if ((lights[i].routing & ROUTING_DIFF_TO_OFFSET) == 0)
|
||||
diffuse += lightColor * factor;
|
||||
else
|
||||
specular += lightColor * factor;
|
||||
}
|
||||
}
|
||||
if (lights[i].specular[volIdx] == 1)
|
||||
{
|
||||
float factor = BASE_FACTOR;
|
||||
float factor = (lights[i].routing & ROUTING_SUB) != 0 ? -BASE_FACTOR : BASE_FACTOR;
|
||||
if (lights[i].smode == LMODE_SINGLE_SIDED)
|
||||
factor *= clamp(pow(max(dot(lightDir, reflectDir), 0.0), glossCoef[volIdx]), 0.0, 1.0);
|
||||
else if (lights[i].smode == LMODE_DOUBLE_SIDED)
|
||||
factor *= clamp(pow(abs(dot(lightDir, reflectDir)), glossCoef[volIdx]), 0.0, 1.0);
|
||||
|
||||
if (lights[i].routing == ROUTING_ALPHADIFF_SUB)
|
||||
specularAlpha -= lightColor.r * factor;
|
||||
else if (lights[i].routing == ROUTING_OFFSDIFF_OFFSSPEC_ADD || lights[i].routing == ROUTING_BASEDIFF_OFFSSPEC_ADD)
|
||||
specular += lightColor * factor;
|
||||
if (lights[i].routing == ROUTING_BASEDIFF_BASESPEC_ADD || lights[i].routing == ROUTING_OFFSDIFF_BASESPEC_ADD)
|
||||
diffuse += lightColor * factor;
|
||||
if ((lights[i].routing & ROUTING_ALPHA) != 0)
|
||||
specularAlpha += lightColor.r * factor;
|
||||
else
|
||||
{
|
||||
if ((lights[i].routing & ROUTING_SPEC_TO_OFFSET) == 0)
|
||||
diffuse += lightColor * factor;
|
||||
else
|
||||
specular += lightColor * factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ambient with material
|
||||
|
@ -306,6 +304,7 @@ void computeBumpMap(inout vec4 color0, vec4 color1, vec3 position, vec3 normal,
|
|||
// TODO
|
||||
//if (bumpId0 == -1)
|
||||
return;
|
||||
normal = normalize(normal);
|
||||
vec3 tangent = color0.xyz;
|
||||
if (tangent.x > 0.5)
|
||||
tangent.x -= 1.0;
|
||||
|
@ -313,7 +312,7 @@ void computeBumpMap(inout vec4 color0, vec4 color1, vec3 position, vec3 normal,
|
|||
tangent.y -= 1.0;
|
||||
if (tangent.z > 0.5)
|
||||
tangent.z -= 1.0;
|
||||
tangent = normalize(normalMat * vec4(tangent, 0.0)).xyz;
|
||||
tangent = normalize(tangent);
|
||||
vec3 bitangent = color1.xyz;
|
||||
if (bitangent.x > 0.5)
|
||||
bitangent.x -= 1.0;
|
||||
|
@ -321,16 +320,17 @@ void computeBumpMap(inout vec4 color0, vec4 color1, vec3 position, vec3 normal,
|
|||
bitangent.y -= 1.0;
|
||||
if (bitangent.z > 0.5)
|
||||
bitangent.z -= 1.0;
|
||||
bitangent = normalize(normalMat * vec4(bitangent, 0.0)).xyz;
|
||||
bitangent = normalize(bitangent);
|
||||
|
||||
float scaleDegree = color0.w;
|
||||
float scaleOffset = color1.w;
|
||||
|
||||
vec3 lightDir; // direction to the light
|
||||
if (lights[bumpId0].parallel == 1)
|
||||
lightDir = normalize(lights[bumpId0].direction.xyz);
|
||||
lightDir = lights[bumpId0].direction.xyz;
|
||||
else
|
||||
lightDir = normalize(lights[bumpId0].position.xyz - position);
|
||||
lightDir = lights[bumpId0].position.xyz - position;
|
||||
lightDir = normalize(lightDir * mat3(normalMat));
|
||||
|
||||
float n = dot(lightDir, normal);
|
||||
float cosQ = dot(lightDir, tangent);
|
||||
|
@ -349,6 +349,7 @@ void computeBumpMap(inout vec4 color0, vec4 color1, vec3 position, vec3 normal,
|
|||
color0.g = k3;
|
||||
color0.b = q / PI / 2.0;
|
||||
color0.a = k1;
|
||||
color0 = clamp(color0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
)";
|
||||
|
|
|
@ -278,11 +278,10 @@ void Drawer::UploadMainBuffer(const VertexShaderUniforms& vertexUniforms, const
|
|||
offsets.fragmentUniformOffset = packer.addUniform(&fragmentUniforms, sizeof(fragmentUniforms));
|
||||
|
||||
std::vector<u8> n2uniforms;
|
||||
std::vector<u8> n2lights;
|
||||
if (settings.platform.isNaomi2())
|
||||
{
|
||||
packNaomi2Uniforms(packer, offsets, n2uniforms, false);
|
||||
offsets.lightsOffset = packNaomi2Lights(packer, n2lights);
|
||||
offsets.lightsOffset = packNaomi2Lights(packer);
|
||||
}
|
||||
|
||||
BufferData *buffer = GetMainBuffer(packer.size());
|
||||
|
|
|
@ -139,48 +139,20 @@ protected:
|
|||
offsets.naomi2TrModVolOffset = offsets.naomi2OpaqueOffset + trMvOffset;
|
||||
}
|
||||
|
||||
vk::DeviceSize packNaomi2Lights(BufferPacker& packer, std::vector<u8>& n2lights)
|
||||
vk::DeviceSize packNaomi2Lights(BufferPacker& packer)
|
||||
{
|
||||
size_t n2LightSize = sizeof(VkN2LightConstants) + align(sizeof(VkN2LightConstants), GetContext()->GetUniformBufferAlignment());
|
||||
n2lights.resize(pvrrc.lightModels.used() * n2LightSize);
|
||||
size_t bufIdx = 0;
|
||||
for (const N2LightModel& lights : pvrrc.lightModels)
|
||||
{
|
||||
VkN2LightConstants& vkLights = *(VkN2LightConstants *)&n2lights[bufIdx];
|
||||
vkLights.lightCount = lights.lightCount;
|
||||
for (int i = 0; i < lights.lightCount; i++)
|
||||
{
|
||||
VkN2Light& vkLight = vkLights.lights[i];
|
||||
const N2Light& light = lights.lights[i];
|
||||
memcpy(vkLight.color, light.color, sizeof(vkLight.color));
|
||||
memcpy(vkLight.direction, light.direction, sizeof(vkLight.direction));
|
||||
memcpy(vkLight.position, light.position, sizeof(vkLight.position));
|
||||
vkLight.parallel = light.parallel;
|
||||
vkLight.routing = light.routing;
|
||||
vkLight.dmode = light.dmode;
|
||||
vkLight.smode = light.smode;
|
||||
memcpy(vkLight.diffuse, light.diffuse, sizeof(vkLight.diffuse));
|
||||
memcpy(vkLight.specular, light.specular, sizeof(vkLight.specular));
|
||||
vkLight.attnDistA = light.attnDistA;
|
||||
vkLight.attnDistB = light.attnDistB;
|
||||
vkLight.attnAngleA = light.attnAngleA;
|
||||
vkLight.attnAngleB = light.attnAngleB;
|
||||
vkLight.distAttnMode = light.distAttnMode;
|
||||
}
|
||||
memcpy(vkLights.ambientBase, lights.ambientBase, sizeof(vkLights.ambientBase));
|
||||
memcpy(vkLights.ambientOffset, lights.ambientOffset, sizeof(vkLights.ambientOffset));
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
vkLights.ambientMaterialBase[i] = lights.ambientMaterialBase[i];
|
||||
vkLights.ambientMaterialOffset[i] = lights.ambientMaterialOffset[i];
|
||||
}
|
||||
vkLights.useBaseOver = lights.useBaseOver;
|
||||
vkLights.bumpId1 = lights.bumpId1;
|
||||
vkLights.bumpId2 = lights.bumpId2;
|
||||
size_t n2LightSize = sizeof(N2LightModel) + align(sizeof(N2LightModel), GetContext()->GetUniformBufferAlignment());
|
||||
if (n2LightSize == sizeof(N2LightModel))
|
||||
return packer.addUniform(pvrrc.lightModels.head(), pvrrc.lightModels.bytes());
|
||||
|
||||
bufIdx += n2LightSize;
|
||||
vk::DeviceSize offset = (vk::DeviceSize)-1;
|
||||
for (const N2LightModel& model : pvrrc.lightModels)
|
||||
{
|
||||
vk::DeviceSize o = packer.addUniform(&model, sizeof(N2LightModel));
|
||||
if (offset == (vk::DeviceSize)-1)
|
||||
offset = o;
|
||||
}
|
||||
return packer.addUniform(n2lights.data(), bufIdx);
|
||||
return offset;
|
||||
}
|
||||
|
||||
vk::Rect2D baseScissor;
|
||||
|
|
|
@ -238,11 +238,10 @@ void OITDrawer::UploadMainBuffer(const OITDescriptorSets::VertexShaderUniforms&
|
|||
offsets.polyParamsOffset = packer.addStorage(trPolyParams.data(), offsets.polyParamsSize);
|
||||
|
||||
std::vector<u8> n2uniforms;
|
||||
std::vector<u8> n2lights;
|
||||
if (settings.platform.isNaomi2())
|
||||
{
|
||||
packNaomi2Uniforms(packer, offsets, n2uniforms, true);
|
||||
offsets.lightsOffset = packNaomi2Lights(packer, n2lights);
|
||||
offsets.lightsOffset = packNaomi2Lights(packer);
|
||||
}
|
||||
|
||||
BufferData *buffer = GetMainBuffer(packer.size());
|
||||
|
|
|
@ -188,8 +188,8 @@ public:
|
|||
|
||||
if (poly.lightModel != nullptr)
|
||||
{
|
||||
size = sizeof(VkN2LightConstants) + align(sizeof(VkN2LightConstants), uniformAlignment);
|
||||
lightBufferInfo = vk::DescriptorBufferInfo{ buffer, lightOffset + (poly.lightModel - pvrrc.lightModels.head()) * size, sizeof(VkN2LightConstants) };
|
||||
size = sizeof(N2LightModel) + align(sizeof(N2LightModel), uniformAlignment);
|
||||
lightBufferInfo = vk::DescriptorBufferInfo{ buffer, lightOffset + (poly.lightModel - pvrrc.lightModels.head()) * size, sizeof(N2LightModel) };
|
||||
writeDescriptorSets.emplace_back(perPolyDescSet, 3, 0, 1, vk::DescriptorType::eUniformBuffer, nullptr, &lightBufferInfo, nullptr);
|
||||
}
|
||||
// TODO no light
|
||||
|
|
|
@ -105,8 +105,8 @@ public:
|
|||
|
||||
if (poly.lightModel != nullptr)
|
||||
{
|
||||
size = sizeof(VkN2LightConstants) + align(sizeof(VkN2LightConstants), uniformAlignment);
|
||||
lightBufferInfo = vk::DescriptorBufferInfo{ buffer, lightOffset + (poly.lightModel - pvrrc.lightModels.head()) * size, sizeof(VkN2LightConstants) };
|
||||
size = sizeof(N2LightModel) + align(sizeof(N2LightModel), uniformAlignment);
|
||||
lightBufferInfo = vk::DescriptorBufferInfo{ buffer, lightOffset + (poly.lightModel - pvrrc.lightModels.head()) * size, sizeof(N2LightModel) };
|
||||
writeDescriptorSets.emplace_back(perPolyDescSet, 3, 0, 1, vk::DescriptorType::eUniformBuffer, nullptr, &lightBufferInfo, nullptr);
|
||||
}
|
||||
// TODO no light
|
||||
|
|
|
@ -351,20 +351,12 @@ layout (std140, set = 1, binding = 2) uniform N2VertexShaderUniforms
|
|||
#define LMODE_THIN_SURFACE 4
|
||||
#define LMODE_BUMP_MAP 5
|
||||
|
||||
#define ROUTING_BASEDIFF_BASESPEC_ADD 0
|
||||
#define ROUTING_BASEDIFF_OFFSSPEC_ADD 1
|
||||
#define ROUTING_OFFSDIFF_BASESPEC_ADD 2
|
||||
#define ROUTING_OFFSDIFF_OFFSSPEC_ADD 3
|
||||
#define ROUTING_ALPHADIFF_ADD 4
|
||||
#define ROUTING_ALPHAATTEN_ADD 5
|
||||
#define ROUTING_FOGDIFF_ADD 6
|
||||
#define ROUTING_FOGATTENUATION_ADD 7
|
||||
#define ROUTING_BASEDIFF_BASESPEC_SUB 8
|
||||
#define ROUTING_BASEDIFF_OFFSSPEC_SUB 9
|
||||
#define ROUTING_OFFSDIFF_BASESPEC_SUB 10
|
||||
#define ROUTING_OFFSDIFF_OFFSSPEC_SUB 11
|
||||
#define ROUTING_ALPHADIFF_SUB 12
|
||||
#define ROUTING_ALPHAATTEN_SUB 13
|
||||
#define ROUTING_SPEC_TO_OFFSET 1
|
||||
#define ROUTING_DIFF_TO_OFFSET 2
|
||||
#define ROUTING_ATTENUATION 1 // not handled
|
||||
#define ROUTING_FOG 2 // not handled
|
||||
#define ROUTING_ALPHA 4
|
||||
#define ROUTING_SUB 8
|
||||
|
||||
struct N2Light
|
||||
{
|
||||
|
@ -442,33 +434,39 @@ void computeColors(inout vec4 baseCol, inout vec4 offsetCol, in int volIdx, in v
|
|||
}
|
||||
if (n2Lights.lights[i].diffuse[volIdx] == 1)
|
||||
{
|
||||
float factor = BASE_FACTOR;
|
||||
float factor = (n2Lights.lights[i].routing & ROUTING_SUB) != 0 ? -BASE_FACTOR : BASE_FACTOR;
|
||||
if (n2Lights.lights[i].dmode == LMODE_SINGLE_SIDED)
|
||||
factor *= max(dot(normal, lightDir), 0.0);
|
||||
else if (n2Lights.lights[i].dmode == LMODE_DOUBLE_SIDED)
|
||||
factor *= abs(dot(normal, lightDir));
|
||||
|
||||
if (n2Lights.lights[i].routing == ROUTING_ALPHADIFF_SUB)
|
||||
diffuseAlpha -= lightColor.r * factor;
|
||||
else if (n2Lights.lights[i].routing == ROUTING_BASEDIFF_BASESPEC_ADD || n2Lights.lights[i].routing == ROUTING_BASEDIFF_OFFSSPEC_ADD)
|
||||
diffuse += lightColor * factor;
|
||||
if (n2Lights.lights[i].routing == ROUTING_OFFSDIFF_BASESPEC_ADD || n2Lights.lights[i].routing == ROUTING_OFFSDIFF_OFFSSPEC_ADD)
|
||||
specular += lightColor * factor;
|
||||
if ((n2Lights.lights[i].routing & ROUTING_ALPHA) != 0)
|
||||
diffuseAlpha += lightColor.r * factor;
|
||||
else
|
||||
{
|
||||
if ((n2Lights.lights[i].routing & ROUTING_DIFF_TO_OFFSET) == 0)
|
||||
diffuse += lightColor * factor;
|
||||
else
|
||||
specular += lightColor * factor;
|
||||
}
|
||||
}
|
||||
if (n2Lights.lights[i].specular[volIdx] == 1)
|
||||
{
|
||||
float factor = BASE_FACTOR;
|
||||
float factor = (n2Lights.lights[i].routing & ROUTING_SUB) != 0 ? -BASE_FACTOR : BASE_FACTOR;
|
||||
if (n2Lights.lights[i].smode == LMODE_SINGLE_SIDED)
|
||||
factor *= clamp(pow(max(dot(lightDir, reflectDir), 0.0), n2Uniform.glossCoef[volIdx]), 0.0, 1.0);
|
||||
else if (n2Lights.lights[i].smode == LMODE_DOUBLE_SIDED)
|
||||
factor *= clamp(pow(abs(dot(lightDir, reflectDir)), n2Uniform.glossCoef[volIdx]), 0.0, 1.0);
|
||||
|
||||
if (n2Lights.lights[i].routing == ROUTING_ALPHADIFF_SUB)
|
||||
specularAlpha -= lightColor.r * factor;
|
||||
else if (n2Lights.lights[i].routing == ROUTING_OFFSDIFF_OFFSSPEC_ADD || n2Lights.lights[i].routing == ROUTING_BASEDIFF_OFFSSPEC_ADD)
|
||||
specular += lightColor * factor;
|
||||
if (n2Lights.lights[i].routing == ROUTING_BASEDIFF_BASESPEC_ADD || n2Lights.lights[i].routing == ROUTING_OFFSDIFF_BASESPEC_ADD)
|
||||
diffuse += lightColor * factor;
|
||||
if ((n2Lights.lights[i].routing & ROUTING_ALPHA) != 0)
|
||||
specularAlpha += lightColor.r * factor;
|
||||
else
|
||||
{
|
||||
if ((n2Lights.lights[i].routing & ROUTING_SPEC_TO_OFFSET) == 0)
|
||||
diffuse += lightColor * factor;
|
||||
else
|
||||
specular += lightColor * factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
// ambient with material
|
||||
|
@ -514,7 +512,7 @@ void computeEnvMap(inout vec2 uv, in vec3 position, in vec3 normal)
|
|||
void computeBumpMap(inout vec4 color0, in vec4 color1, in vec3 position, in vec3 normal, in mat4 normalMat)
|
||||
{
|
||||
// TODO
|
||||
if (n2Lights.bumpId0 == -1)
|
||||
//if (n2Lights.bumpId0 == -1)
|
||||
return;
|
||||
normal = normalize(normal);
|
||||
vec3 tangent = color0.xyz;
|
||||
|
@ -524,7 +522,6 @@ void computeBumpMap(inout vec4 color0, in vec4 color1, in vec3 position, in vec3
|
|||
tangent.y -= 1.0;
|
||||
if (tangent.z > 0.5)
|
||||
tangent.z -= 1.0;
|
||||
//tangent = normalize(normalMat * vec4(tangent, 0.0)).xyz;
|
||||
tangent = normalize(tangent);
|
||||
vec3 bitangent = color1.xyz;
|
||||
if (bitangent.x > 0.5)
|
||||
|
@ -533,7 +530,6 @@ void computeBumpMap(inout vec4 color0, in vec4 color1, in vec3 position, in vec3
|
|||
bitangent.y -= 1.0;
|
||||
if (bitangent.z > 0.5)
|
||||
bitangent.z -= 1.0;
|
||||
//bitangent = normalize(normalMat * vec4(bitangent, 0.0)).xyz;
|
||||
bitangent = normalize(bitangent);
|
||||
|
||||
float scaleDegree = color0.w;
|
||||
|
@ -563,6 +559,7 @@ void computeBumpMap(inout vec4 color0, in vec4 color1, in vec3 position, in vec3
|
|||
color0.g = k3;
|
||||
color0.b = q / PI / 2.0;
|
||||
color0.a = k1;
|
||||
color0 = clamp(color0, 0.0, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
|
|
|
@ -93,44 +93,6 @@ struct N2VertexShaderUniforms
|
|||
int modelSpecular[2];
|
||||
};
|
||||
|
||||
// std140 alignment required
|
||||
struct VkN2Light
|
||||
{
|
||||
float color[4];
|
||||
float direction[4];
|
||||
float position[4];
|
||||
|
||||
int parallel;
|
||||
int routing;
|
||||
int dmode;
|
||||
int smode;
|
||||
|
||||
int diffuse[2];
|
||||
int specular[2];
|
||||
|
||||
float attnDistA;
|
||||
float attnDistB;
|
||||
float attnAngleA;
|
||||
float attnAngleB;
|
||||
|
||||
int distAttnMode;
|
||||
int _pad[3];
|
||||
};
|
||||
|
||||
// std140 alignment required
|
||||
struct VkN2LightConstants
|
||||
{
|
||||
VkN2Light lights[16];
|
||||
float ambientBase[2][4];
|
||||
float ambientOffset[2][4];
|
||||
int ambientMaterialBase[2];
|
||||
int ambientMaterialOffset[2];
|
||||
int lightCount;
|
||||
int useBaseOver;
|
||||
int bumpId1;
|
||||
int bumpId2;
|
||||
};
|
||||
|
||||
class ShaderManager
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -258,7 +258,8 @@ protected:
|
|||
curTexture->UploadToGPU(width, height, (u8*)pb.data(), false);
|
||||
curTexture->SetCommandBuffer(nullptr);
|
||||
|
||||
Vertex *vtx = ctx->rend.verts.Append(4);
|
||||
// Use background poly vtx and param
|
||||
Vertex *vtx = ctx->rend.verts.head();
|
||||
vtx[0].x = 0.f;
|
||||
vtx[0].y = 0.f;
|
||||
vtx[0].z = 0.1f;
|
||||
|
@ -280,13 +281,13 @@ protected:
|
|||
vtx[3].v = 1.f;
|
||||
|
||||
u32 *idx = ctx->rend.idx.Append(4);
|
||||
idx[0] = ctx->rend.verts.used() - 4;
|
||||
idx[1] = idx[0] + 1;
|
||||
idx[2] = idx[1] + 1;
|
||||
idx[3] = idx[2] + 1;
|
||||
idx[0] = 0;
|
||||
idx[1] = 1;
|
||||
idx[2] = 2;
|
||||
idx[3] = 3;
|
||||
|
||||
PolyParam *pp = ctx->rend.global_param_op.Append(1);
|
||||
pp->first = ctx->rend.idx.used() - 4;
|
||||
PolyParam *pp = ctx->rend.global_param_op.head();
|
||||
pp->first = 0;
|
||||
pp->count = 4;
|
||||
|
||||
pp->isp.full = 0;
|
||||
|
@ -314,7 +315,7 @@ protected:
|
|||
pass->autosort = false;
|
||||
pass->mvo_count = 0;
|
||||
pass->mvo_tr_count = 0;
|
||||
pass->op_count = ctx->rend.global_param_op.used();
|
||||
pass->op_count = 1;
|
||||
pass->pt_count = 0;
|
||||
pass->tr_count = 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue