Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabled up to 65535 pieces per model #1835

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions cont/base/springcontent/shaders/GLSL/ModelVertProgGL4.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 T;
layout (location = 3) in vec3 B;
layout (location = 4) in vec4 uv;
layout (location = 5) in uvec2 bonesInfo; //boneIDs, boneWeights
layout (location = 5) in uvec3 bonesInfo; //boneIDsLow, boneWeights, boneIDsHigh

layout (location = 6) in uvec4 instData;
// u32 matOffset
// u32 uniOffset
// u32 {teamIdx, drawFlag, unused, numPieces}
// u32 {teamIdx, drawFlag, numPiecesH, numPiecesL}, note numPiecesH then numPiecesL
// u32 bposeMatOffset

layout(std140, binding = 0) uniform UniformMatrixBuffer {
Expand Down Expand Up @@ -145,7 +145,7 @@ void GetModelSpaceVertex(out vec4 msPosition, out vec3 msNormal)
float(GetUnpackedValue(bonesInfo.y, 3)) / 255.0
);

uint b0 = GetUnpackedValue(bonesInfo.x, 0); //first boneID
uint b0 = GetUnpackedValue(bonesInfo.x, 0) + (GetUnpackedValue(bonesInfo.z, 0) << 8u); //first boneID
mat4 b0BoneMat = mat[instData.x + b0 + uint(!staticModel)];
mat3 b0NormMat = mat3(b0BoneMat);

Expand All @@ -163,14 +163,14 @@ void GetModelSpaceVertex(out vec4 msPosition, out vec3 msNormal)
msNormal *= weights[0];
wSum += weights[0];

uint numPieces = GetUnpackedValue(instData.z, 3);
uint numPieces = (GetUnpackedValue(instData.z, 2) << 8u) + GetUnpackedValue(instData.z, 3);
mat4 bposeMat = mat[instData.w + b0];

// Vertex[ModelSpace,BoneX] = PieceMat[BoneX] * InverseBindPosMat[BoneX] * BindPosMat[Bone0] * Vertex[Bone0]
for (uint bi = 1; bi < 3; ++bi) {
uint bID = GetUnpackedValue(bonesInfo.x, bi);
uint bID = GetUnpackedValue(bonesInfo.x, bi) + (GetUnpackedValue(bonesInfo.z, bi) << 8u);

if (bID == 0xFFu || weights[bi] == 0.0)
if (bID == 0xFFFFu || weights[bi] == 0.0)
continue;

mat4 bposeInvMat = mat[instData.w + numPieces + bID];
Expand Down
12 changes: 6 additions & 6 deletions cont/base/springcontent/shaders/GLSL/ShadowGenVertProgGL4.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 T;
layout (location = 3) in vec3 B;
layout (location = 4) in vec4 uv;
layout (location = 5) in uvec2 bonesInfo; //boneIDs, boneWeights
layout (location = 5) in uvec3 bonesInfo; //boneIDsLow, boneWeights, boneIDsHigh

layout (location = 6) in uvec4 instData;
// u32 matOffset
// u32 uniOffset
// u32 {teamIdx, drawFlag, unused, numPieces}
// u32 {teamIdx, drawFlag, numPiecesH, numPiecesL}, note numPiecesH then numPiecesL
// u32 bposeMatOffset

layout(std140, binding = 0) uniform UniformMatrixBuffer {
Expand Down Expand Up @@ -128,7 +128,7 @@ void GetModelSpaceVertex(out vec4 msPosition, out vec3 msNormal)
float(GetUnpackedValue(bonesInfo.y, 3)) / 255.0
);

uint b0 = GetUnpackedValue(bonesInfo.x, 0); //first boneID
uint b0 = GetUnpackedValue(bonesInfo.x, 0) + (GetUnpackedValue(bonesInfo.z, 0) << 8u); //first boneID
mat4 b0BoneMat = mat[instData.x + b0 + 1u];
mat3 b0NormMat = mat3(b0BoneMat);

Expand All @@ -146,14 +146,14 @@ void GetModelSpaceVertex(out vec4 msPosition, out vec3 msNormal)
msNormal *= weights[0];
wSum += weights[0];

uint numPieces = GetUnpackedValue(instData.z, 3);
uint numPieces = (GetUnpackedValue(instData.z, 2) << 8u) + GetUnpackedValue(instData.z, 3);
mat4 bposeMat = mat[instData.w + b0];

// Vertex[ModelSpace,BoneX] = PieceMat[BoneX] * InverseBindPosMat[BoneX] * BindPosMat[Bone0] * Vertex[Bone0]
for (uint bi = 1; bi < 3; ++bi) {
uint bID = GetUnpackedValue(bonesInfo.x, bi);
uint bID = GetUnpackedValue(bonesInfo.x, bi) + (GetUnpackedValue(bonesInfo.z, bi) << 8u);

if (bID == 0xFFu || weights[bi] == 0.0)
if (bID == 0xFFFFu || weights[bi] == 0.0)
continue;

mat4 bposeInvMat = mat[instData.w + numPieces + bID];
Expand Down
23 changes: 11 additions & 12 deletions rts/Lua/LuaVBOImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -778,17 +778,16 @@ void LuaVBOImpl::UpdateModelsVBOElementCount()
}

/*
float3 pos;
float3 normal = UpVector;
float3 sTangent;
float3 tTangent;
vec3 pos;
vec3 normal = UpVector;
vec3 sTangent;
vec3 tTangent;

// TODO:
// with pieceIndex this struct is no longer 64 bytes in size which ATI's prefer
// support an arbitrary number of channels, would be easy but overkill (for now)
float2 texCoords[NUM_MODEL_UVCHANNS];

uint32_t pieceIndex = 0;
uvec3 in uvec3 bonesInfo;
*/
size_t LuaVBOImpl::ModelsVBOImpl()
{
Expand Down Expand Up @@ -851,12 +850,12 @@ size_t LuaVBOImpl::ModelsVBOImpl()
// uint32_t pieceIndex
this->bufferAttribDefs[5] = {
GL_UNSIGNED_INT, //type
2, //size
3, //size
GL_FALSE, //normalized
"bonesInfo", //name
offsetof(SVertexData, boneIDs), //pointer
offsetof(SVertexData, boneIDsLow), //pointer
sizeof(uint32_t), //typeSizeInBytes
2 * sizeof(uint32_t) //strideSizeInBytes
3 * sizeof(uint32_t) //strideSizeInBytes
};

this->attributesCount = 6;
Expand Down Expand Up @@ -999,14 +998,14 @@ SInstanceData LuaVBOImpl::InstanceDataFromGetData(int id, int attrID, uint8_t de
drawFlags = obj->drawFlag;
}

uint8_t numPieces = 0;
uint16_t numPieces = 0;
size_t bposeIndex = 0;
if constexpr (std::is_same<TObj, S3DModel>::value) {
numPieces = static_cast<uint8_t>(obj->numPieces);
numPieces = static_cast<uint16_t>(obj->numPieces);
bposeIndex = matrixUploader.GetElemOffset(obj);
}
else {
numPieces = static_cast<uint8_t>(obj->model->numPieces);
numPieces = static_cast<uint16_t>(obj->model->numPieces);
bposeIndex = matrixUploader.GetElemOffset(obj->model);
}

Expand Down
12 changes: 7 additions & 5 deletions rts/Rendering/GL/myGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,13 @@ struct SDrawElementsIndirectCommand {

struct SInstanceData {
SInstanceData() = default;
SInstanceData(uint32_t matOffset_, uint8_t teamIndex, uint8_t drawFlags, uint8_t numPieces, uint32_t uniOffset_, uint32_t bposeMatOffset_)
: matOffset{ matOffset_ } // updated during the following draw frames
, uniOffset{ uniOffset_ } // updated during the following draw frames
, info{ teamIndex, drawFlags, 0, numPieces } // not updated during the following draw frames
, bposeMatOffset { bposeMatOffset_ } // updated during the following draw frames
SInstanceData(uint32_t matOffset_, uint8_t teamIndex, uint8_t drawFlags, uint16_t numPieces, uint32_t uniOffset_, uint32_t bposeMatOffset_)
: matOffset{ matOffset_ } // updated during the following draw frames
, uniOffset{ uniOffset_ } // updated during the following draw frames
, info{ teamIndex, drawFlags // not updated during the following draw frames
, static_cast<uint8_t>((numPieces >> 8) & 0xFF)
, static_cast<uint8_t>((numPieces ) & 0xFF) }
, bposeMatOffset { bposeMatOffset_ } // updated during the following draw frames
{}

uint32_t matOffset;
Expand Down
10 changes: 7 additions & 3 deletions rts/Rendering/Models/3DModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ CR_REG_METADATA(LocalModel, (
CR_MEMBER(needsBoundariesRecalc)
))

static_assert(sizeof(SVertexData) == (3 + 3 + 3 + 3 + 4 + 2 + 1) * 4);

void S3DModelHelpers::BindLegacyAttrVBOs()
{
Expand Down Expand Up @@ -250,9 +251,12 @@ void S3DModelPiece::PostProcessGeometry(uint32_t pieceIndex)
return;


for (auto& v : vertices)
if (v.boneIDs == SVertexData::DEFAULT_BONEIDS)
v.boneIDs = { static_cast<uint8_t>(pieceIndex), 255, 255, 255 };
for (auto& v : vertices) {
if (v.boneIDsLow == SVertexData::DEFAULT_BONEIDS_LOW && v.boneIDsHigh == SVertexData::DEFAULT_BONEIDS_HIGH) {
v.boneIDsLow [0] = static_cast<uint8_t>((pieceIndex ) & 0xFF);
v.boneIDsHigh[0] = static_cast<uint8_t>((pieceIndex >> 8) & 0xFF);
}
}
}

void S3DModelPiece::DrawElements(GLuint prim) const
Expand Down
47 changes: 30 additions & 17 deletions rts/Rendering/Models/3DModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <array>
#include <vector>
#include <string>
#include <limits>

#include "ModelsMemStorage.h"
#include "Lua/LuaObjectMaterial.h"
Expand All @@ -19,10 +20,12 @@
#include "System/SpringMath.h"
#include "System/creg/creg_cond.h"

constexpr int MAX_MODEL_OBJECTS = 3840;
constexpr int AVG_MODEL_PIECES = 16; // as it used to be
constexpr int NUM_MODEL_TEXTURES = 2;
constexpr int NUM_MODEL_UVCHANNS = 2;
static constexpr int MAX_MODEL_OBJECTS = 3840;
static constexpr int AVG_MODEL_PIECES = 16; // as it used to be
static constexpr int NUM_MODEL_TEXTURES = 2;
static constexpr int NUM_MODEL_UVCHANNS = 2;
static constexpr int MAX_PIECES_PER_MODEL = std::numeric_limits<uint16_t>::max() - 1;
static constexpr int INV_PIECE_NUM = MAX_PIECES_PER_MODEL + 1;

static constexpr float3 DEF_MIN_SIZE( 10000.0f, 10000.0f, 10000.0f);
static constexpr float3 DEF_MAX_SIZE(-10000.0f, -10000.0f, -10000.0f);
Expand All @@ -49,8 +52,10 @@ struct SVertexData {
tTangent = float3{};
texCoords[0] = float2{};
texCoords[1] = float2{};
boneIDs = DEFAULT_BONEIDS;
// boneIDs is initialized afterwards
boneIDsLow = DEFAULT_BONEIDS_LOW;
boneWeights = DEFAULT_BONEWEIGHTS;
boneIDsHigh = DEFAULT_BONEIDS_HIGH;
}
SVertexData(
const float3& p,
Expand All @@ -67,28 +72,31 @@ struct SVertexData {
texCoords[0] = uv0;
texCoords[1] = uv1;
// boneIDs is initialized afterwards
boneIDs = DEFAULT_BONEIDS;
boneIDsLow = DEFAULT_BONEIDS_LOW;
boneWeights = DEFAULT_BONEWEIGHTS;
boneIDsHigh = DEFAULT_BONEIDS_HIGH;
}

float3 pos;
float3 normal;
float3 sTangent;
float3 tTangent;
float2 texCoords[NUM_MODEL_UVCHANNS];
std::array<uint8_t, 4> boneIDs;
std::array<uint8_t, 4> boneIDsLow;
std::array<uint8_t, 4> boneWeights;
std::array<uint8_t, 4> boneIDsHigh;

static constexpr std::array<uint8_t, 4> DEFAULT_BONEIDS = { 255, 255, 255, 255 };
static constexpr std::array<uint8_t, 4> DEFAULT_BONEWEIGHTS = { 255, 0, 0, 0 };
static constexpr std::array<uint8_t, 4> DEFAULT_BONEIDS_HIGH = { 255, 255, 255, 255 };
static constexpr std::array<uint8_t, 4> DEFAULT_BONEIDS_LOW = { 255, 255, 255, 255 };
static constexpr std::array<uint8_t, 4> DEFAULT_BONEWEIGHTS = { 255, 0 , 0, 0 };

void SetBones(const std::vector<std::pair<uint8_t, float>>& bi) {
void SetBones(const std::vector<std::pair<uint16_t, float>>& bi) {
assert(bi.size() == 4);
boneIDs = {
bi[0].first,
bi[1].first,
bi[2].first,
bi[3].first
boneIDsLow = {
static_cast<uint8_t>((bi[0].first ) & 0xFF),
static_cast<uint8_t>((bi[1].first ) & 0xFF),
static_cast<uint8_t>((bi[2].first ) & 0xFF),
static_cast<uint8_t>((bi[3].first ) & 0xFF)
};

boneWeights = {
Expand All @@ -97,11 +105,16 @@ struct SVertexData {
(static_cast<uint8_t>(math::round(bi[2].second * 255.0f))),
(static_cast<uint8_t>(math::round(bi[3].second * 255.0f)))
};

boneIDsHigh = {
static_cast<uint8_t>((bi[0].first >> 8) & 0xFF),
static_cast<uint8_t>((bi[1].first >> 8) & 0xFF),
static_cast<uint8_t>((bi[2].first >> 8) & 0xFF),
static_cast<uint8_t>((bi[3].first >> 8) & 0xFF)
};
}
};



struct S3DModelPiecePart {
public:
struct RenderData {
Expand Down
14 changes: 7 additions & 7 deletions rts/Rendering/Models/3DModelVAO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void S3DModelVAO::EnableAttribs(bool inst) const
glVertexAttribPointer (2, 3, GL_FLOAT , false, sizeof(SVertexData), (const void*)offsetof(SVertexData, sTangent ));
glVertexAttribPointer (3, 3, GL_FLOAT , false, sizeof(SVertexData), (const void*)offsetof(SVertexData, tTangent ));
glVertexAttribPointer (4, 4, GL_FLOAT , false, sizeof(SVertexData), (const void*)offsetof(SVertexData, texCoords[0]));
glVertexAttribIPointer(5, 2, GL_UNSIGNED_INT, sizeof(SVertexData), (const void*)offsetof(SVertexData, boneIDs ));
glVertexAttribIPointer(5, 3, GL_UNSIGNED_INT, sizeof(SVertexData), (const void*)offsetof(SVertexData, boneIDsLow ));
}
else {
for (int i = 6; i <= 6; ++i) {
Expand Down Expand Up @@ -293,14 +293,14 @@ bool S3DModelVAO::AddToSubmissionImpl(const TObj* obj, uint32_t indexStart, uint

const auto uniIndex = modelsUniformsStorage.GetObjOffset(obj); //doesn't need to exist for defs and models. Don't check for validity

uint8_t numPieces = 0;
uint16_t numPieces = 0;
size_t bposeIndex = 0;
if constexpr (std::is_same<TObj, S3DModel>::value) {
numPieces = static_cast<uint8_t>(obj->numPieces);
numPieces = static_cast<uint16_t>(obj->numPieces);
bposeIndex = matrixUploader.GetElemOffset(obj);
}
else {
numPieces = static_cast<uint8_t>(obj->model->numPieces);
numPieces = static_cast<uint16_t>(obj->model->numPieces);
bposeIndex = matrixUploader.GetElemOffset(obj->model);
}

Expand Down Expand Up @@ -420,14 +420,14 @@ bool S3DModelVAO::SubmitImmediatelyImpl(const TObj* obj, uint32_t indexStart, ui

const auto uniIndex = modelsUniformsStorage.GetObjOffset(obj); //doesn't need to exist for defs. Don't check for validity

uint8_t numPieces = 0;
uint16_t numPieces = 0;
size_t bposeIndex = 0;
if constexpr (std::is_same<TObj, S3DModel>::value) {
numPieces = static_cast<uint8_t>(obj->numPieces);
numPieces = static_cast<uint16_t>(obj->numPieces);
bposeIndex = matrixUploader.GetElemOffset(obj);
}
else {
numPieces = static_cast<uint8_t>(obj->model->numPieces);
numPieces = static_cast<uint16_t>(obj->model->numPieces);
bposeIndex = matrixUploader.GetElemOffset(obj->model);
}

Expand Down
Loading