Added fog to the collision shader, made changes to enable rendering different collision materials separately (also, murry crimmas)
This commit is contained in:
parent
c0fb54888d
commit
78baa42bce
|
@ -9,8 +9,25 @@ out vec4 PixelColor;
|
|||
// Uniforms
|
||||
uniform vec4 TintColor;
|
||||
|
||||
// Functions
|
||||
float InterpolateDecelerate(float Min, float Max, float t, float Factor)
|
||||
{
|
||||
float Alpha = (1.0 - pow(1.0 - t, Factor));
|
||||
return mix(Min, Max, Alpha);
|
||||
}
|
||||
|
||||
// Main
|
||||
void main()
|
||||
{
|
||||
PixelColor = LightColor * TintColor;
|
||||
const float kMaxDepth = 75.0; // Controls the max depth range that kDepthTintNear and kDepthTintFar are interpolated between
|
||||
const float kDepthTintNear = 0.0; // Sets the pixel color offset for pixels close to the screen
|
||||
const float kDepthTintFar = -0.2; // Sets the pixel color offset for pixels far from the screen
|
||||
const float kDepthCurveFactor = 2; // Controls the strength of the interpolation curve (higher = color chabges faster from up close and slower from further away)
|
||||
|
||||
// Apply some fake fog so pixels closer to the camera appear slightly brighter
|
||||
float Depth = ( (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near) ) / gl_FragCoord.w;
|
||||
float DepthAlpha = min(Depth, kMaxDepth) / kMaxDepth;
|
||||
DepthAlpha = clamp(DepthAlpha, 0.0, 1.0);
|
||||
float DepthTint = InterpolateDecelerate(kDepthTintNear, kDepthTintFar, DepthAlpha, kDepthCurveFactor);
|
||||
PixelColor = (LightColor + vec4(DepthTint, DepthTint, DepthTint, 1.0)) * TintColor;
|
||||
}
|
||||
|
|
|
@ -18,12 +18,17 @@ layout(std140) uniform MVPBlock
|
|||
// Main
|
||||
void main()
|
||||
{
|
||||
const vec3 kLightDir = normalize( vec3(0.3, 0, -1) ); // Sets the direction of the light
|
||||
const float kLightColorMin = 0.5; // Sets the minimum light color (color of a vertex facing away from the light)
|
||||
const float kLightColorMax = 0.9; // Sets the maximum light color (color of a vertex facing towards the light)
|
||||
|
||||
// Calculate vertex position
|
||||
mat4 MVP = ModelMtx * ViewMtx * ProjMtx;
|
||||
gl_Position = vec4(RawPosition, 1) * MVP;
|
||||
|
||||
// Fake lighting; render one white skylight pointing straight down with an ambient 0.5
|
||||
float LightDot = dot(RawNormal, vec3(0, 0, -1));
|
||||
// Apply some simple lighting
|
||||
float LightDot = dot(RawNormal, kLightDir);
|
||||
float Alpha = (-LightDot + 1.0) / 2;
|
||||
float LightAlpha = mix(0.5, 0.9, Alpha);
|
||||
float LightAlpha = mix(kLightColorMin, kLightColorMax, Alpha);
|
||||
LightColor = vec4(LightAlpha, LightAlpha, LightAlpha, 1.0);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "CCollisionMesh.h"
|
||||
#include "Core/Render/CRenderer.h"
|
||||
#include "Core/Render/CDrawUtil.h"
|
||||
#include <Common/Assert.h>
|
||||
|
||||
CCollisionMesh::CCollisionMesh()
|
||||
{
|
||||
|
@ -31,20 +32,39 @@ void CCollisionMesh::BufferGL()
|
|||
mBuffered = false;
|
||||
}
|
||||
|
||||
// Add all the relevant indices to the IBO
|
||||
mVBO.Reserve(mCollisionFaces.size() * 3);
|
||||
mIBO.Reserve(mCollisionFaces.size() * 3);
|
||||
// Create new list of collision faces sorted by material index
|
||||
std::vector<CCollisionFace> SortedTris = mCollisionFaces;
|
||||
std::sort(SortedTris.begin(), SortedTris.end(), [](CCollisionFace& rLeft, CCollisionFace& rRight) -> bool {
|
||||
return rLeft.MaterialIdx < rRight.MaterialIdx;
|
||||
});
|
||||
|
||||
for (u32 iVtx = 0; iVtx < mCollisionFaces.size(); iVtx++)
|
||||
// Add all the relevant indices to the IBO
|
||||
mVBO.Reserve(SortedTris.size() * 3);
|
||||
mIBO.Reserve(SortedTris.size() * 3);
|
||||
|
||||
mMaterialOffsets.reserve(mMaterials.size());
|
||||
u32 CurMat = 0;
|
||||
|
||||
for (u32 iTri = 0; iTri < SortedTris.size(); iTri++)
|
||||
{
|
||||
u16 Verts[3];
|
||||
|
||||
CCollisionFace *pFace = &mCollisionFaces[iVtx];
|
||||
CCollisionFace *pFace = &SortedTris[iTri];
|
||||
CCollisionLine *pLineA = GetLine(pFace->Lines[0]);
|
||||
CCollisionLine *pLineB = GetLine(pFace->Lines[1]);
|
||||
Verts[0] = pLineA->Vertices[0];
|
||||
Verts[1] = pLineA->Vertices[1];
|
||||
|
||||
// Check if we've reached a new material
|
||||
if (pFace->MaterialIdx != CurMat)
|
||||
{
|
||||
while (CurMat != pFace->MaterialIdx)
|
||||
{
|
||||
mMaterialOffsets.push_back(mIBO.GetSize());
|
||||
CurMat++;
|
||||
}
|
||||
}
|
||||
|
||||
// We have two vertex indices; the last one is one of the ones on line B, but we're not sure which one
|
||||
if ((pLineB->Vertices[0] != Verts[0]) &&
|
||||
(pLineB->Vertices[0] != Verts[1]))
|
||||
|
@ -53,7 +73,7 @@ void CCollisionMesh::BufferGL()
|
|||
Verts[2] = pLineB->Vertices[1];
|
||||
|
||||
// Some faces have a property that indicates they need to be inverted
|
||||
if (pFace->Properties.Invert)
|
||||
if (GetMaterial(pFace->MaterialIdx).FlippedTri)
|
||||
{
|
||||
u16 V0 = Verts[0];
|
||||
Verts[0] = Verts[2];
|
||||
|
@ -79,6 +99,14 @@ void CCollisionMesh::BufferGL()
|
|||
}
|
||||
}
|
||||
|
||||
while (CurMat != mMaterials.size())
|
||||
{
|
||||
mMaterialOffsets.push_back(mIBO.GetSize());
|
||||
CurMat++;
|
||||
}
|
||||
|
||||
ASSERT(mMaterialOffsets.size() == mMaterials.size());
|
||||
|
||||
// Buffer, and done
|
||||
mVBO.Buffer();
|
||||
mIBO.Buffer();
|
||||
|
@ -94,6 +122,18 @@ void CCollisionMesh::Draw()
|
|||
mVBO.Unbind();
|
||||
}
|
||||
|
||||
void CCollisionMesh::DrawMaterial(u32 MatIdx)
|
||||
{
|
||||
if (!mBuffered) BufferGL();
|
||||
ASSERT(MatIdx < mMaterials.size());
|
||||
|
||||
mVBO.Bind();
|
||||
u32 StartIdx = (MatIdx == 0 ? 0 : mMaterialOffsets[MatIdx - 1]);
|
||||
u32 NumElements = mMaterialOffsets[MatIdx] - StartIdx;
|
||||
mIBO.DrawElements(StartIdx, NumElements);
|
||||
mVBO.Unbind();
|
||||
}
|
||||
|
||||
void CCollisionMesh::DrawWireframe()
|
||||
{
|
||||
CDrawUtil::UseColorShader(CColor::skBlack);
|
||||
|
|
|
@ -6,6 +6,17 @@
|
|||
#include "Core/OpenGL/CIndexBuffer.h"
|
||||
#include <Math/CAABox.h>
|
||||
|
||||
struct SCollisionMaterial
|
||||
{
|
||||
// todo: figure out what the other properties are
|
||||
u64 RawFlags;
|
||||
bool AiWalkThru;
|
||||
bool FlippedTri;
|
||||
bool ShootThru;
|
||||
bool CameraThru;
|
||||
bool Solid;
|
||||
};
|
||||
|
||||
class CCollisionMesh
|
||||
{
|
||||
friend class CCollisionLoader;
|
||||
|
@ -30,30 +41,24 @@ class CCollisionMesh
|
|||
SOctreeNode* mpRoot;
|
||||
};
|
||||
|
||||
struct SCollisionProperties
|
||||
{
|
||||
// todo: figure out what the other properties are
|
||||
bool Invert;
|
||||
};
|
||||
|
||||
class CCollisionVertex
|
||||
{
|
||||
public:
|
||||
SCollisionProperties Properties;
|
||||
u32 MaterialIdx;
|
||||
CVector3f Pos;
|
||||
};
|
||||
|
||||
class CCollisionLine
|
||||
{
|
||||
public:
|
||||
SCollisionProperties Properties;
|
||||
u32 MaterialIdx;
|
||||
u16 Vertices[2];
|
||||
};
|
||||
|
||||
class CCollisionFace
|
||||
{
|
||||
public:
|
||||
SCollisionProperties Properties;
|
||||
u32 MaterialIdx;
|
||||
u16 Lines[3];
|
||||
};
|
||||
|
||||
|
@ -66,10 +71,11 @@ class CCollisionMesh
|
|||
|
||||
CAABox mAABox;
|
||||
CCollisionOctree *mpOctree;
|
||||
std::vector<u32> mFlags;
|
||||
std::vector<SCollisionMaterial> mMaterials;
|
||||
std::vector<CCollisionVertex> mCollisionVertices;
|
||||
std::vector<CCollisionLine> mCollisionLines;
|
||||
std::vector<CCollisionFace> mCollisionFaces;
|
||||
std::vector<u32> mMaterialOffsets;
|
||||
bool mOctreeLoaded;
|
||||
|
||||
CCollisionVertex *GetVertex(u16 Index);
|
||||
|
@ -82,7 +88,11 @@ public:
|
|||
|
||||
void BufferGL();
|
||||
void Draw();
|
||||
void DrawMaterial(u32 MatIdx);
|
||||
void DrawWireframe();
|
||||
|
||||
inline u32 NumMaterials() const { return mMaterials.size(); }
|
||||
inline SCollisionMaterial& GetMaterial(u32 Index) { return mMaterials[Index]; }
|
||||
};
|
||||
|
||||
#endif // CCOLLISIONMESH_H
|
||||
|
|
|
@ -38,27 +38,27 @@ void CCollisionLoader::ParseOBBNode(IInputStream& rDCLN)
|
|||
|
||||
void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc)
|
||||
{
|
||||
CCollisionMesh::SCollisionProperties Property;
|
||||
SCollisionMaterial Material;
|
||||
|
||||
if (mVersion == ePrime)
|
||||
{
|
||||
u32 Flag = rSrc.ReadLong();
|
||||
Property.Invert = (Flag >> 25) & 0x1;
|
||||
Material.RawFlags = rSrc.ReadLong();
|
||||
Material.FlippedTri = (Material.RawFlags >> 25) & 0x1;
|
||||
}
|
||||
|
||||
else if (mVersion == eEchoes)
|
||||
{
|
||||
u64 Flag = rSrc.ReadLongLong();
|
||||
Property.Invert = (Flag >> 24) & 0x1;
|
||||
Material.RawFlags = rSrc.ReadLongLong();
|
||||
Material.FlippedTri = (Material.RawFlags >> 24) & 0x1;
|
||||
}
|
||||
|
||||
else if (mVersion == eReturns)
|
||||
{
|
||||
u64 Flag = rSrc.ReadLongLong();
|
||||
Property.Invert = (Flag >> 28) & 0x1;
|
||||
Material.RawFlags = rSrc.ReadLongLong();
|
||||
Material.FlippedTri = (Material.RawFlags >> 28) & 0x1;
|
||||
}
|
||||
|
||||
mProperties.push_back(Property);
|
||||
mpMesh->mMaterials.push_back(Material);
|
||||
}
|
||||
|
||||
void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox)
|
||||
|
@ -89,7 +89,7 @@ void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox
|
|||
CCollisionMesh::CCollisionLine *pLine = &mpMesh->mCollisionLines[iLine];
|
||||
pLine->Vertices[0] = rFile.ReadShort();
|
||||
pLine->Vertices[1] = rFile.ReadShort();
|
||||
pLine->Properties = mProperties[LineIndices[iLine]];
|
||||
pLine->MaterialIdx = LineIndices[iLine];
|
||||
}
|
||||
|
||||
// Faces
|
||||
|
@ -102,7 +102,7 @@ void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox
|
|||
pFace->Lines[0] = rFile.ReadShort();
|
||||
pFace->Lines[1] = rFile.ReadShort();
|
||||
pFace->Lines[2] = rFile.ReadShort();
|
||||
pFace->Properties = mProperties[FaceIndices[iFace]];
|
||||
pFace->MaterialIdx = FaceIndices[iFace];
|
||||
}
|
||||
|
||||
// Echoes introduces a new data chunk; don't know what it is yet, skipping for now
|
||||
|
@ -121,7 +121,7 @@ void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox
|
|||
{
|
||||
CCollisionMesh::CCollisionVertex *pVtx = &mpMesh->mCollisionVertices[iVtx];
|
||||
pVtx->Pos = CVector3f(rFile);
|
||||
pVtx->Properties = mProperties[VtxIndices[iVtx]];
|
||||
pVtx->MaterialIdx = VtxIndices[iVtx];
|
||||
if (BuildAABox) Bounds.ExpandBounds(pVtx->Pos);
|
||||
}
|
||||
if (BuildAABox) mpMesh->mAABox = Bounds;
|
||||
|
|
|
@ -10,7 +10,6 @@ class CCollisionLoader
|
|||
TResPtr<CCollisionMeshGroup> mpGroup;
|
||||
CCollisionMesh *mpMesh;
|
||||
EGame mVersion;
|
||||
std::vector<CCollisionMesh::SCollisionProperties> mProperties;
|
||||
|
||||
CCollisionLoader();
|
||||
CCollisionMesh::CCollisionOctree* ParseOctree(IInputStream& rSrc);
|
||||
|
|
|
@ -37,8 +37,21 @@ void CCollisionNode::Draw(FRenderOptions /*Options*/, int /*ComponentIndex*/, ER
|
|||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
CDrawUtil::UseCollisionShader(TintColor(rkViewInfo));
|
||||
mpCollision->Draw();
|
||||
CColor BaseTint = TintColor(rkViewInfo);
|
||||
|
||||
for (u32 iMesh = 0; iMesh < mpCollision->NumMeshes(); iMesh++)
|
||||
{
|
||||
CCollisionMesh *pMesh = mpCollision->MeshByIndex(iMesh);
|
||||
|
||||
for (u32 iMat = 0; iMat < pMesh->NumMaterials(); iMat++)
|
||||
{
|
||||
CDrawUtil::UseCollisionShader(BaseTint);
|
||||
pMesh->DrawMaterial(iMat);
|
||||
}
|
||||
}
|
||||
|
||||
//CDrawUtil::UseColorShader(CColor::skTransparentBlack);
|
||||
//mpCollision->DrawWireframe();
|
||||
}
|
||||
|
||||
SRayIntersection CCollisionNode::RayNodeIntersectTest(const CRay& /*rkRay*/, u32 /*AssetID*/, const SViewInfo& /*rkViewInfo*/)
|
||||
|
|
Loading…
Reference in New Issue