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
|
// Uniforms
|
||||||
uniform vec4 TintColor;
|
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
|
// Main
|
||||||
void 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
|
// Main
|
||||||
void 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;
|
mat4 MVP = ModelMtx * ViewMtx * ProjMtx;
|
||||||
gl_Position = vec4(RawPosition, 1) * MVP;
|
gl_Position = vec4(RawPosition, 1) * MVP;
|
||||||
|
|
||||||
// Fake lighting; render one white skylight pointing straight down with an ambient 0.5
|
// Apply some simple lighting
|
||||||
float LightDot = dot(RawNormal, vec3(0, 0, -1));
|
float LightDot = dot(RawNormal, kLightDir);
|
||||||
float Alpha = (-LightDot + 1.0) / 2;
|
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);
|
LightColor = vec4(LightAlpha, LightAlpha, LightAlpha, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "CCollisionMesh.h"
|
#include "CCollisionMesh.h"
|
||||||
#include "Core/Render/CRenderer.h"
|
#include "Core/Render/CRenderer.h"
|
||||||
#include "Core/Render/CDrawUtil.h"
|
#include "Core/Render/CDrawUtil.h"
|
||||||
|
#include <Common/Assert.h>
|
||||||
|
|
||||||
CCollisionMesh::CCollisionMesh()
|
CCollisionMesh::CCollisionMesh()
|
||||||
{
|
{
|
||||||
|
@ -31,20 +32,39 @@ void CCollisionMesh::BufferGL()
|
||||||
mBuffered = false;
|
mBuffered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all the relevant indices to the IBO
|
// Create new list of collision faces sorted by material index
|
||||||
mVBO.Reserve(mCollisionFaces.size() * 3);
|
std::vector<CCollisionFace> SortedTris = mCollisionFaces;
|
||||||
mIBO.Reserve(mCollisionFaces.size() * 3);
|
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];
|
u16 Verts[3];
|
||||||
|
|
||||||
CCollisionFace *pFace = &mCollisionFaces[iVtx];
|
CCollisionFace *pFace = &SortedTris[iTri];
|
||||||
CCollisionLine *pLineA = GetLine(pFace->Lines[0]);
|
CCollisionLine *pLineA = GetLine(pFace->Lines[0]);
|
||||||
CCollisionLine *pLineB = GetLine(pFace->Lines[1]);
|
CCollisionLine *pLineB = GetLine(pFace->Lines[1]);
|
||||||
Verts[0] = pLineA->Vertices[0];
|
Verts[0] = pLineA->Vertices[0];
|
||||||
Verts[1] = pLineA->Vertices[1];
|
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
|
// 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]) &&
|
if ((pLineB->Vertices[0] != Verts[0]) &&
|
||||||
(pLineB->Vertices[0] != Verts[1]))
|
(pLineB->Vertices[0] != Verts[1]))
|
||||||
|
@ -53,7 +73,7 @@ void CCollisionMesh::BufferGL()
|
||||||
Verts[2] = pLineB->Vertices[1];
|
Verts[2] = pLineB->Vertices[1];
|
||||||
|
|
||||||
// Some faces have a property that indicates they need to be inverted
|
// 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];
|
u16 V0 = Verts[0];
|
||||||
Verts[0] = Verts[2];
|
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
|
// Buffer, and done
|
||||||
mVBO.Buffer();
|
mVBO.Buffer();
|
||||||
mIBO.Buffer();
|
mIBO.Buffer();
|
||||||
|
@ -94,6 +122,18 @@ void CCollisionMesh::Draw()
|
||||||
mVBO.Unbind();
|
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()
|
void CCollisionMesh::DrawWireframe()
|
||||||
{
|
{
|
||||||
CDrawUtil::UseColorShader(CColor::skBlack);
|
CDrawUtil::UseColorShader(CColor::skBlack);
|
||||||
|
|
|
@ -6,6 +6,17 @@
|
||||||
#include "Core/OpenGL/CIndexBuffer.h"
|
#include "Core/OpenGL/CIndexBuffer.h"
|
||||||
#include <Math/CAABox.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
|
class CCollisionMesh
|
||||||
{
|
{
|
||||||
friend class CCollisionLoader;
|
friend class CCollisionLoader;
|
||||||
|
@ -30,30 +41,24 @@ class CCollisionMesh
|
||||||
SOctreeNode* mpRoot;
|
SOctreeNode* mpRoot;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SCollisionProperties
|
|
||||||
{
|
|
||||||
// todo: figure out what the other properties are
|
|
||||||
bool Invert;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CCollisionVertex
|
class CCollisionVertex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SCollisionProperties Properties;
|
u32 MaterialIdx;
|
||||||
CVector3f Pos;
|
CVector3f Pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CCollisionLine
|
class CCollisionLine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SCollisionProperties Properties;
|
u32 MaterialIdx;
|
||||||
u16 Vertices[2];
|
u16 Vertices[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
class CCollisionFace
|
class CCollisionFace
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SCollisionProperties Properties;
|
u32 MaterialIdx;
|
||||||
u16 Lines[3];
|
u16 Lines[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,10 +71,11 @@ class CCollisionMesh
|
||||||
|
|
||||||
CAABox mAABox;
|
CAABox mAABox;
|
||||||
CCollisionOctree *mpOctree;
|
CCollisionOctree *mpOctree;
|
||||||
std::vector<u32> mFlags;
|
std::vector<SCollisionMaterial> mMaterials;
|
||||||
std::vector<CCollisionVertex> mCollisionVertices;
|
std::vector<CCollisionVertex> mCollisionVertices;
|
||||||
std::vector<CCollisionLine> mCollisionLines;
|
std::vector<CCollisionLine> mCollisionLines;
|
||||||
std::vector<CCollisionFace> mCollisionFaces;
|
std::vector<CCollisionFace> mCollisionFaces;
|
||||||
|
std::vector<u32> mMaterialOffsets;
|
||||||
bool mOctreeLoaded;
|
bool mOctreeLoaded;
|
||||||
|
|
||||||
CCollisionVertex *GetVertex(u16 Index);
|
CCollisionVertex *GetVertex(u16 Index);
|
||||||
|
@ -82,7 +88,11 @@ public:
|
||||||
|
|
||||||
void BufferGL();
|
void BufferGL();
|
||||||
void Draw();
|
void Draw();
|
||||||
|
void DrawMaterial(u32 MatIdx);
|
||||||
void DrawWireframe();
|
void DrawWireframe();
|
||||||
|
|
||||||
|
inline u32 NumMaterials() const { return mMaterials.size(); }
|
||||||
|
inline SCollisionMaterial& GetMaterial(u32 Index) { return mMaterials[Index]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CCOLLISIONMESH_H
|
#endif // CCOLLISIONMESH_H
|
||||||
|
|
|
@ -38,27 +38,27 @@ void CCollisionLoader::ParseOBBNode(IInputStream& rDCLN)
|
||||||
|
|
||||||
void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc)
|
void CCollisionLoader::ReadPropertyFlags(IInputStream& rSrc)
|
||||||
{
|
{
|
||||||
CCollisionMesh::SCollisionProperties Property;
|
SCollisionMaterial Material;
|
||||||
|
|
||||||
if (mVersion == ePrime)
|
if (mVersion == ePrime)
|
||||||
{
|
{
|
||||||
u32 Flag = rSrc.ReadLong();
|
Material.RawFlags = rSrc.ReadLong();
|
||||||
Property.Invert = (Flag >> 25) & 0x1;
|
Material.FlippedTri = (Material.RawFlags >> 25) & 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (mVersion == eEchoes)
|
else if (mVersion == eEchoes)
|
||||||
{
|
{
|
||||||
u64 Flag = rSrc.ReadLongLong();
|
Material.RawFlags = rSrc.ReadLongLong();
|
||||||
Property.Invert = (Flag >> 24) & 0x1;
|
Material.FlippedTri = (Material.RawFlags >> 24) & 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (mVersion == eReturns)
|
else if (mVersion == eReturns)
|
||||||
{
|
{
|
||||||
u64 Flag = rSrc.ReadLongLong();
|
Material.RawFlags = rSrc.ReadLongLong();
|
||||||
Property.Invert = (Flag >> 28) & 0x1;
|
Material.FlippedTri = (Material.RawFlags >> 28) & 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mProperties.push_back(Property);
|
mpMesh->mMaterials.push_back(Material);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox)
|
void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox)
|
||||||
|
@ -89,7 +89,7 @@ void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox
|
||||||
CCollisionMesh::CCollisionLine *pLine = &mpMesh->mCollisionLines[iLine];
|
CCollisionMesh::CCollisionLine *pLine = &mpMesh->mCollisionLines[iLine];
|
||||||
pLine->Vertices[0] = rFile.ReadShort();
|
pLine->Vertices[0] = rFile.ReadShort();
|
||||||
pLine->Vertices[1] = rFile.ReadShort();
|
pLine->Vertices[1] = rFile.ReadShort();
|
||||||
pLine->Properties = mProperties[LineIndices[iLine]];
|
pLine->MaterialIdx = LineIndices[iLine];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Faces
|
// Faces
|
||||||
|
@ -102,7 +102,7 @@ void CCollisionLoader::LoadCollisionIndices(IInputStream &rFile, bool BuildAABox
|
||||||
pFace->Lines[0] = rFile.ReadShort();
|
pFace->Lines[0] = rFile.ReadShort();
|
||||||
pFace->Lines[1] = rFile.ReadShort();
|
pFace->Lines[1] = rFile.ReadShort();
|
||||||
pFace->Lines[2] = 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
|
// 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];
|
CCollisionMesh::CCollisionVertex *pVtx = &mpMesh->mCollisionVertices[iVtx];
|
||||||
pVtx->Pos = CVector3f(rFile);
|
pVtx->Pos = CVector3f(rFile);
|
||||||
pVtx->Properties = mProperties[VtxIndices[iVtx]];
|
pVtx->MaterialIdx = VtxIndices[iVtx];
|
||||||
if (BuildAABox) Bounds.ExpandBounds(pVtx->Pos);
|
if (BuildAABox) Bounds.ExpandBounds(pVtx->Pos);
|
||||||
}
|
}
|
||||||
if (BuildAABox) mpMesh->mAABox = Bounds;
|
if (BuildAABox) mpMesh->mAABox = Bounds;
|
||||||
|
|
|
@ -10,7 +10,6 @@ class CCollisionLoader
|
||||||
TResPtr<CCollisionMeshGroup> mpGroup;
|
TResPtr<CCollisionMeshGroup> mpGroup;
|
||||||
CCollisionMesh *mpMesh;
|
CCollisionMesh *mpMesh;
|
||||||
EGame mVersion;
|
EGame mVersion;
|
||||||
std::vector<CCollisionMesh::SCollisionProperties> mProperties;
|
|
||||||
|
|
||||||
CCollisionLoader();
|
CCollisionLoader();
|
||||||
CCollisionMesh::CCollisionOctree* ParseOctree(IInputStream& rSrc);
|
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);
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
|
||||||
CDrawUtil::UseCollisionShader(TintColor(rkViewInfo));
|
CColor BaseTint = TintColor(rkViewInfo);
|
||||||
mpCollision->Draw();
|
|
||||||
|
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*/)
|
SRayIntersection CCollisionNode::RayNodeIntersectTest(const CRay& /*rkRay*/, u32 /*AssetID*/, const SViewInfo& /*rkViewInfo*/)
|
||||||
|
|
Loading…
Reference in New Issue