Skip to content

Commit

Permalink
Fix bug where you couldn't toggle lighting on RS3 maps
Browse files Browse the repository at this point in the history
  • Loading branch information
Asunaya committed Jan 7, 2017
1 parent 5f40d3a commit a5f3950
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 84 deletions.
1 change: 1 addition & 0 deletions RealSpace2/Include/RBspObjectDraw.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class RBspObjectDraw

POLYVAR_METHOD(Init)
POLYVAR_METHOD(Draw)
POLYVAR_METHOD(SetLighting)
POLYVAR_METHOD(OnInvalidate);
POLYVAR_METHOD(OnRestore);

Expand Down
21 changes: 11 additions & 10 deletions RealSpace2/Include/RBspObjectDrawD3D9.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,19 @@ class RBspObjectDrawD3D9

bool ShowRTsEnabled{};

void SetLighting(bool);

private:
struct SimpleVertex
{
v3 Pos;
v2 Tex;
};

struct LitVertex
{
v3 Pos;
v3 Nor;
v2 Tex;
v4 Tan;
};

void CreateTextures();
void CreateShaderStuff();
void CreateBatches();
bool CreateBuffers();

void CreateRTs();
void ReleaseRTs();
Expand All @@ -54,7 +49,6 @@ class RBspObjectDrawD3D9
LPDIRECT3DTEXTURE9 GetTexture(int Index) const;

u32 GetFVF() const;
size_t GetStride() const;
bool UsingLighting() const;

RBspObject& bsp;
Expand Down Expand Up @@ -94,10 +88,17 @@ class RBspObjectDrawD3D9
template <MaterialType Type>
void RenderMaterials(int StartIndex, int EndIndex);

D3DPtr<IDirect3DVertexBuffer9> VertexBuffer;
struct {
// If SupportsDynamicLighting is true, each of these contain a vertex buffer with their component.
// Otherwise, Positions is the only valid pointer, and it holds an interleaved stream of
// position and texcoord components.
D3DPtr<IDirect3DVertexBuffer9> Positions, TexCoords, Normals, Tangents;
} VBs;

D3DPtr<IDirect3DIndexBuffer9> IndexBuffer;

D3DPtr<IDirect3DVertexDeclaration9> LitVertexDecl;
D3DPtr<IDirect3DVertexDeclaration9> UnlitVertexDecl;

D3DPtr<IDirect3DVertexShader9> DeferredVS;
D3DPtr<IDirect3DPixelShader9> DeferredPS;
Expand Down
2 changes: 2 additions & 0 deletions RealSpace2/Include/RBspObjectDrawVulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class RBspObjectDrawVulkan
void Draw();
void UpdateUniformBuffers();

void SetLighting(bool) {}

private:
// Creates and fills the vertex and index buffers
void CreateBuffers();
Expand Down
10 changes: 9 additions & 1 deletion RealSpace2/Include/RUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,12 @@ inline void SetShaders(const ShaderRefPair& Shaders)

template <typename T> constexpr D3DFORMAT GetD3DFormat();
template <> constexpr D3DFORMAT GetD3DFormat<u16>() { return D3DFMT_INDEX16; }
template <> constexpr D3DFORMAT GetD3DFormat<u32>() { return D3DFMT_INDEX32; }
template <> constexpr D3DFORMAT GetD3DFormat<u32>() { return D3DFMT_INDEX32; }

template <size_t size>
auto CreateVertexDeclaration(const D3DVERTEXELEMENT9(&Decl)[size])
{
D3DPtr<IDirect3DVertexDeclaration9> ptr;
RGetDevice()->CreateVertexDeclaration(Decl, MakeWriteProxy(ptr));
return ptr;
}
2 changes: 2 additions & 0 deletions RealSpace2/Source/RBspObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ void RBspObject::LightMapOnOff(bool bDraw)
return;

m_bisDrawLightMap = bDraw;
if (GetRS2().UsingD3D9())
DrawObj.SetLightingStatic<RBspObjectDrawD3D9>(bDraw);

if (bDraw)
{
Expand Down
179 changes: 106 additions & 73 deletions RealSpace2/Source/RBspObjectDrawD3D9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,6 @@ struct MaterialBatch
using namespace rsx;
using IndexType = u32;

template <typename VertexType, typename IndexType>
static bool CreateBuffers(size_t VertexCount, size_t IndexCount, u32 FVF,
D3DPtr<IDirect3DVertexBuffer9>& vb, D3DPtr<IDirect3DIndexBuffer9>& ib)
{
auto hr = RGetDevice()->CreateVertexBuffer(VertexCount * sizeof(VertexType), 0,
FVF, D3DPOOL_MANAGED,
MakeWriteProxy(vb), nullptr);
if (FAILED(hr))
{
MLog("RBspObjectDrawD3D9::Create -- Failed to create vertex buffer\n");
return false;
}

hr = RGetDevice()->CreateIndexBuffer(IndexCount * sizeof(IndexType), 0,
GetD3DFormat<IndexType>(), D3DPOOL_MANAGED,
MakeWriteProxy(ib), nullptr);
if (FAILED(hr))
{
MLog("RBspObjectDrawD3D9::Create -- Failed to create index buffer\n");
return false;
}

return true;
}

RBspObjectDrawD3D9::RBspObjectDrawD3D9(RBspObject& bsp) : bsp{ bsp }, dev{ RGetDevice() } {}
RBspObjectDrawD3D9::RBspObjectDrawD3D9(RBspObjectDrawD3D9&&) = default;
RBspObjectDrawD3D9::~RBspObjectDrawD3D9() = default;
Expand Down Expand Up @@ -129,30 +104,39 @@ void RBspObjectDrawD3D9::CreateTextures()
}
}

static D3DPtr<IDirect3DVertexDeclaration9> CreateLitVertexDecl()
static D3DPtr<IDirect3DVertexDeclaration9> CreateUnlitVertexDecl()
{
D3DVERTEXELEMENT9 Decl[] =
{
D3DVERTEXELEMENT9 Decl[] = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 3 * 4, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 6 * 4, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 0, 8 * 4, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 },
{ 1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()
};
return CreateVertexDeclaration(Decl);
}

D3DPtr<IDirect3DVertexDeclaration9> ptr;
RGetDevice()->CreateVertexDeclaration(Decl, MakeWriteProxy(ptr));
return ptr;
static D3DPtr<IDirect3DVertexDeclaration9> CreateLitVertexDecl()
{
D3DVERTEXELEMENT9 Decl[] = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 3, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 },
D3DDECL_END()
};
return CreateVertexDeclaration(Decl);
}

void RBspObjectDrawD3D9::CreateShaderStuff()
{
SupportsDynamicLighting = SupportsVertexShaderVersion(3, 0) &&
SupportsPixelShaderVersion(3, 0) &&
GetDeviceCaps().NumSimultaneousRTs >= 4;
GetDeviceCaps().NumSimultaneousRTs >= 4 &&
GetDeviceCaps().MaxStreams >= 4;

if (!SupportsDynamicLighting)
return;

UnlitVertexDecl = CreateUnlitVertexDecl();
LitVertexDecl = CreateLitVertexDecl();
DeferredVS = CreateVertexShader(DeferredVSData);
DeferredPS = CreatePixelShader(DeferredPSData);
Expand All @@ -165,6 +149,45 @@ void RBspObjectDrawD3D9::CreateShaderStuff()
CreateRTs();
}

template <typename VertexType>
bool CreateVB(D3DPtr<IDirect3DVertexBuffer9>& ptr, size_t VertexCount, u32 FVF)
{
auto hr = RGetDevice()->CreateVertexBuffer(VertexCount * sizeof(VertexType), 0,
FVF, D3DPOOL_MANAGED,
MakeWriteProxy(ptr), nullptr);
if (FAILED(hr))
{
MLog("RBspObjectDrawD3D9::Create -- Failed to create vertex buffer\n");
return false;
}
return true;
}

bool RBspObjectDrawD3D9::CreateBuffers()
{
#define CREATE_VB(x) if (!CreateVB<decltype(EluObjectData{}.Meshes[0].x[0])>(VBs.x, \
State.TotalVertexCount, GetFVF())) return false;
CREATE_VB(Positions);
if (SupportsDynamicLighting)
{
CREATE_VB(TexCoords);
CREATE_VB(Normals);
CREATE_VB(Tangents);
}
#undef CREATE_VB

auto hr = RGetDevice()->CreateIndexBuffer(State.TotalIndexCount * sizeof(IndexType), 0,
GetD3DFormat<IndexType>(), D3DPOOL_MANAGED,
MakeWriteProxy(IndexBuffer), nullptr);
if (FAILED(hr))
{
MLog("RBspObjectDrawD3D9::Create -- Failed to create index buffer\n");
return false;
}

return true;
}

void RBspObjectDrawD3D9::CreateBatches()
{
struct DrawPropStuff
Expand Down Expand Up @@ -204,29 +227,12 @@ void RBspObjectDrawD3D9::CreateBatches()
}
}

bool ret{};
if (UsingLighting())
{
ret = CreateBuffers<LitVertex, IndexType>(
State.TotalVertexCount, State.TotalIndexCount,
GetFVF(), VertexBuffer, IndexBuffer);
}
else
{
ret = CreateBuffers<SimpleVertex, IndexType>(
State.TotalVertexCount, State.TotalIndexCount,
GetFVF(), VertexBuffer, IndexBuffer);
}

if (!ret)
if (!CreateBuffers())
{
MLog("RBspObjectDrawD3D9::Create -- Failed to create vertex and index buffers\n");
return;
}

DMLog("Create vertex buffer with %d vertices, index buffer with %d indices\n",
State.TotalVertexCount, State.TotalIndexCount);

// Lock vertex and index buffers.
auto Lock = [](auto& Buffer, auto*& Pointer)
{
Expand All @@ -237,7 +243,19 @@ void RBspObjectDrawD3D9::CreateBatches()
}
return true;
};
char* Verts{}; if (!Lock(VertexBuffer, Verts)) return;
char* Positions{};
char* TexCoords{};
char* Normals{};
char* Tangents{};
#define LOCK(x) Lock(VBs.x, x)
LOCK(Positions);
if (SupportsDynamicLighting)
{
LOCK(TexCoords);
LOCK(Normals);
LOCK(Tangents);
}
#undef LOCK
IndexType* Indices{}; if (!Lock(IndexBuffer, Indices)) return;

// Insert transformed vertices for each object into the vertex buffer
Expand Down Expand Up @@ -269,25 +287,25 @@ void RBspObjectDrawD3D9::CreateBatches()

for (size_t i{}; i < Mesh.VertexCount; ++i)
{
auto AddVertexData = [&](auto&& val) {
memcpy(Verts, &val, sizeof(val));
Verts += sizeof(val);
auto AddVertexData = [&](auto& stream, auto&& val) {
memcpy(stream, &val, sizeof(val));
stream += sizeof(val);
};
if (!UsingLighting())
if (!SupportsDynamicLighting)
{
AddVertexData(Mesh.Positions[i] * Mesh.World * Object.World);
AddVertexData(Mesh.TexCoords[i]);
AddVertexData(Positions, Mesh.Positions[i] * Mesh.World * Object.World);
AddVertexData(Positions, Mesh.TexCoords[i]);
}
else
{
AddVertexData(Mesh.Positions[i] * Mesh.World * Object.World);
AddVertexData(TransformNormal(Mesh.Normals[i], Mesh.World * Object.World));
AddVertexData(Mesh.TexCoords[i]);
AddVertexData(Positions, Mesh.Positions[i] * Mesh.World * Object.World);
AddVertexData(Normals, TransformNormal(Mesh.Normals[i], Mesh.World * Object.World));
AddVertexData(TexCoords, Mesh.TexCoords[i]);
v4 tan = Mesh.Tangents[i];
tan.w = 0;
tan = Transform(tan, Mesh.World * Object.World);
tan.w = Mesh.Tangents[i].w;
AddVertexData(tan);
AddVertexData(Tangents, tan);
}
}
CumulativeVertexBase += Mesh.VertexCount;
Expand Down Expand Up @@ -340,7 +358,7 @@ void RBspObjectDrawD3D9::CreateBatches()
DMLog("Added %d vertices, %d indices\n", CumulativeVertexBase, CumulativeIndexBase);

// Unlock vertex and index buffers.
VertexBuffer->Unlock();
VBs.Positions->Unlock(); VBs.TexCoords->Unlock(); VBs.Normals->Unlock(); VBs.Tangents->Unlock();
IndexBuffer->Unlock();

// Sort materials by state changes.
Expand Down Expand Up @@ -375,7 +393,7 @@ void RBspObjectDrawD3D9::CreateRTs()
{
if (!UsingLighting())
return;

for (size_t i{}; i < ArraySize(RTs); ++i)
{
auto& RT = RTs[i];
Expand Down Expand Up @@ -419,7 +437,7 @@ void RBspObjectDrawD3D9::Create(rsx::LoaderState && srcState)
Materials.clear();
TextureMemory.clear();
MaterialBatches.clear();
VertexBuffer.reset();
VBs.Positions.reset(); VBs.TexCoords.reset(); VBs.Normals.reset(); VBs.Tangents.reset();
IndexBuffer.reset();
NormalMaterialsEnd = 0;
OpacityMaterialsEnd = 0;
Expand Down Expand Up @@ -588,11 +606,6 @@ u32 RBspObjectDrawD3D9::GetFVF() const
return D3DFVF_XYZ | D3DFVF_TEX1;
}

size_t RBspObjectDrawD3D9::GetStride() const
{
return UsingLighting() ? sizeof(LitVertex) : sizeof(SimpleVertex);
}

bool RBspObjectDrawD3D9::UsingLighting() const
{
return SupportsDynamicLighting && bsp.m_bisDrawLightMap;
Expand Down Expand Up @@ -772,12 +785,26 @@ void RBspObjectDrawD3D9::SetPrologueStates()
// Map triangles are clockwise, so cull counter-clockwise faces.
dev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

dev->SetStreamSource(0, VertexBuffer.get(), 0, GetStride());
if (!SupportsDynamicLighting)
{
dev->SetStreamSource(0, VBs.Positions.get(), 0, sizeof(SimpleVertex));
}
else
{
dev->SetStreamSource(0, VBs.Positions.get(), 0, sizeof(v3));
dev->SetStreamSource(1, VBs.TexCoords.get(), 0, sizeof(v2));
if (UsingLighting())
{
dev->SetStreamSource(2, VBs.Normals.get(), 0, sizeof(v3));
dev->SetStreamSource(3, VBs.Tangents.get(), 0, sizeof(v4));
}
}
dev->SetIndices(IndexBuffer.get());

if (!UsingLighting())
{
dev->SetFVF(GetFVF());
dev->SetVertexDeclaration(UnlitVertexDecl.get());
dev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
}
else
Expand Down Expand Up @@ -869,4 +896,10 @@ void RBspObjectDrawD3D9::Draw()
SetEpilogueStates();
}

void RBspObjectDrawD3D9::SetLighting(bool b)
{
if (b && !RTs[0])
CreateRTs();
}

_NAMESPACE_REALSPACE2_END

0 comments on commit a5f3950

Please sign in to comment.