Added UV transform and rewritten animated texture mapping code to use it
parent
3bd4fee844
commit
7d9badb542
|
@ -174,6 +174,9 @@ public:
|
|||
//! Sets transparency mode
|
||||
virtual void SetTransparency(TransparencyMode mode) = 0;
|
||||
|
||||
//! Sets UV transform
|
||||
virtual void SetUVTransform(const glm::vec2& offset, const glm::vec2& scale) = 0;
|
||||
|
||||
virtual void SetPrimaryTextureEnabled(bool enabled) = 0;
|
||||
//! Sets triplanar mode
|
||||
virtual void SetTriplanarMode(bool enabled) = 0;
|
||||
|
|
|
@ -640,7 +640,7 @@ EngineBaseObjDataTier& CEngine::AddLevel3(EngineBaseObjTexTier& p3, EngineTriang
|
|||
return p3.next[i];
|
||||
}
|
||||
|
||||
p3.next.push_back(EngineBaseObjDataTier(type, state));
|
||||
p3.next.push_back(EngineBaseObjDataTier{ type, state });
|
||||
return p3.next.back();
|
||||
}
|
||||
|
||||
|
@ -1162,168 +1162,35 @@ void CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name)
|
|||
}
|
||||
}
|
||||
|
||||
void CEngine::ChangeTextureMapping(int objRank, int state,
|
||||
const std::string& tex1Name, const std::string& tex2Name,
|
||||
EngineTextureMapping mode,
|
||||
float au, float bu, float av, float bv)
|
||||
void CEngine::SetUVTransform(int objRank, int state, const glm::vec2& offset, const glm::vec2& scale)
|
||||
{
|
||||
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
||||
assert(objRank >= 0 && objRank < static_cast<int>(m_objects.size()));
|
||||
|
||||
EngineBaseObjDataTier* p4 = FindTriangles(objRank, state, tex1Name, tex2Name);
|
||||
if (p4 == nullptr)
|
||||
int baseObjRank = m_objects[objRank].baseObjRank;
|
||||
if (baseObjRank == -1)
|
||||
return;
|
||||
|
||||
int nb = p4->vertices.size();
|
||||
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>(m_baseObjects.size()));
|
||||
|
||||
if (mode == EngineTextureMapping::X)
|
||||
{
|
||||
for (int i = 0; i < nb; i++)
|
||||
{
|
||||
p4->vertices[i].uv.x = p4->vertices[i].position.z * au + bu;
|
||||
p4->vertices[i].uv.y = p4->vertices[i].position.y * av + bv;
|
||||
}
|
||||
}
|
||||
else if (mode == EngineTextureMapping::Y)
|
||||
{
|
||||
for (int i = 0; i < nb; i++)
|
||||
{
|
||||
p4->vertices[i].uv.x = p4->vertices[i].position.x * au + bu;
|
||||
p4->vertices[i].uv.y = p4->vertices[i].position.z * av + bv;
|
||||
}
|
||||
}
|
||||
else if (mode == EngineTextureMapping::Z)
|
||||
{
|
||||
for (int i = 0; i < nb; i++)
|
||||
{
|
||||
p4->vertices[i].uv.x = p4->vertices[i].position.x * au + bu;
|
||||
p4->vertices[i].uv.y = p4->vertices[i].position.y * av + bv;
|
||||
}
|
||||
}
|
||||
else if (mode == EngineTextureMapping::ONE_X)
|
||||
{
|
||||
for (int i = 0; i < nb; i++)
|
||||
{
|
||||
p4->vertices[i].uv.x = p4->vertices[i].position.x * au + bu;
|
||||
}
|
||||
}
|
||||
else if (mode == EngineTextureMapping::ONE_Y)
|
||||
{
|
||||
for (int i = 0; i < nb; i++)
|
||||
{
|
||||
p4->vertices[i].uv.y = p4->vertices[i].position.y * au + bu;
|
||||
}
|
||||
}
|
||||
else if (mode == EngineTextureMapping::ONE_Z)
|
||||
{
|
||||
for (int i = 0; i < nb; i++)
|
||||
{
|
||||
p4->vertices[i].uv.x = p4->vertices[i].position.z * au + bu;
|
||||
}
|
||||
}
|
||||
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
||||
|
||||
UpdateStaticBuffer(*p4);
|
||||
for (size_t l2 = 0; l2 < p1.next.size(); l2++)
|
||||
{
|
||||
EngineBaseObjTexTier& p2 = p1.next[l2];
|
||||
|
||||
for (size_t l3 = 0; l3 < p2.next.size(); l3++)
|
||||
{
|
||||
EngineBaseObjDataTier& p3 = p2.next[l3];
|
||||
|
||||
if (p3.state & state)
|
||||
{
|
||||
p3.uvOffset = offset;
|
||||
p3.uvScale = scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CEngine::TrackTextureMapping(int objRank, int state,
|
||||
const std::string& tex1Name, const std::string& tex2Name,
|
||||
EngineTextureMapping mode,
|
||||
float pos, float factor, float tl, float ts, float tt)
|
||||
{
|
||||
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
||||
|
||||
EngineBaseObjDataTier* p4 = FindTriangles(objRank, state, tex1Name, tex2Name);
|
||||
if (p4 == nullptr)
|
||||
return;
|
||||
|
||||
int tNum = p4->vertices.size();
|
||||
if (tNum < 12 || tNum % 6 != 0)
|
||||
return;
|
||||
|
||||
std::vector<Gfx::Vertex3D>& vs = p4->vertices;
|
||||
|
||||
while (pos < 0.0f)
|
||||
pos += 1.0f; // never negative!
|
||||
|
||||
glm::vec3 current{ 0, 0, 0 };
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
for (int j = 0; j < 6; j++)
|
||||
{
|
||||
if (Math::IsEqual(vs[i].position.x, vs[j+6].position.x) &&
|
||||
Math::IsEqual(vs[i].position.y, vs[j+6].position.y))
|
||||
{
|
||||
current.x = vs[i].position.x; // position end link
|
||||
current.y = vs[i].position.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float ps = 0.0f; // start position on the periphery
|
||||
float pe = 0.0f;
|
||||
int is[6] = { 0 }, ie[6] = { 0 };
|
||||
|
||||
int tBase = 0;
|
||||
for (int ti = 0; ti < tNum / 6; ti++)
|
||||
{
|
||||
int s = 0;
|
||||
int e = 0;
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (Math::IsEqual(vs[tBase + i].position.x, current.x, 0.0001f) &&
|
||||
Math::IsEqual(vs[tBase + i].position.y, current.y, 0.0001f))
|
||||
{
|
||||
ie[e++] = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
is[s++] = i;
|
||||
}
|
||||
}
|
||||
if (s == 3 && e == 3)
|
||||
{
|
||||
glm::vec2 endPosition{};
|
||||
endPosition.x = vs[tBase + is[0]].position.x - vs[tBase + ie[0]].position.x;
|
||||
endPosition.y = vs[tBase + is[0]].position.y - vs[tBase + ie[0]].position.y;
|
||||
|
||||
pe = ps + glm::length(endPosition) / factor; // end position on the periphery
|
||||
|
||||
float pps = ps + pos;
|
||||
float ppe = pe + pos;
|
||||
int offset = static_cast<int>(pps);
|
||||
ppe -= offset;
|
||||
pps -= offset;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
vs[tBase + is[i]].uv.x = ((pps * tl) + ts) / tt;
|
||||
vs[tBase + ie[i]].uv.x = ((ppe * tl) + ts) / tt;
|
||||
}
|
||||
}
|
||||
|
||||
if (ti >= (tNum / 6) - 1)
|
||||
break;
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (!Math::IsEqual(vs[tBase + i+6].position.x, current.x, 0.0001f) ||
|
||||
!Math::IsEqual(vs[tBase + i+6].position.y, current.y, 0.0001f))
|
||||
{
|
||||
current.x = vs[tBase + i+6].position.x; // end next link
|
||||
current.y = vs[tBase + i+6].position.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ps = pe; // following start position on the periphery
|
||||
tBase += 6;
|
||||
}
|
||||
|
||||
UpdateStaticBuffer(*p4);
|
||||
}
|
||||
|
||||
|
||||
void CEngine::CreateShadowSpot(int objRank)
|
||||
{
|
||||
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
||||
|
@ -3570,6 +3437,7 @@ void CEngine::Draw3DScene()
|
|||
objectRenderer->SetDirty(dirty);
|
||||
objectRenderer->SetColor({ 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
objectRenderer->SetCullMode((p3.state& ENG_RSTATE_2FACE) == 0);
|
||||
objectRenderer->SetUVTransform(p3.uvOffset, p3.uvScale);
|
||||
objectRenderer->DrawObject(p3.buffer);
|
||||
}
|
||||
}
|
||||
|
@ -3635,6 +3503,7 @@ void CEngine::Draw3DScene()
|
|||
float dirty = (p3.state & ENG_RSTATE_DUAL_BLACK) && m_dirty ? 1.0 : 0.0;
|
||||
objectRenderer->SetDirty(dirty);
|
||||
objectRenderer->SetColor(tColor);
|
||||
objectRenderer->SetUVTransform(p3.uvOffset, p3.uvScale);
|
||||
objectRenderer->DrawObject(p3.buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -189,19 +189,13 @@ enum EngineObjectType
|
|||
*/
|
||||
struct EngineBaseObjDataTier
|
||||
{
|
||||
EngineTriangleType type;
|
||||
int state;
|
||||
EngineTriangleType type = EngineTriangleType::TRIANGLES;
|
||||
int state = ENG_RSTATE_NORMAL;
|
||||
std::vector<Vertex3D> vertices;
|
||||
CVertexBuffer* buffer;
|
||||
bool updateStaticBuffer;
|
||||
|
||||
inline EngineBaseObjDataTier(EngineTriangleType type = EngineTriangleType::TRIANGLES,
|
||||
int state = ENG_RSTATE_NORMAL)
|
||||
: type(type)
|
||||
, state(state)
|
||||
, buffer(nullptr)
|
||||
, updateStaticBuffer(false)
|
||||
{}
|
||||
CVertexBuffer* buffer = nullptr;
|
||||
bool updateStaticBuffer = false;
|
||||
glm::vec2 uvOffset = { 0.0f, 0.0f };
|
||||
glm::vec2 uvScale = { 1.0f, 1.0f };
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -785,17 +779,7 @@ public:
|
|||
//! Changes the 2nd texure for given object
|
||||
void ChangeSecondTexture(int objRank, const std::string& tex2Name);
|
||||
|
||||
//! Changes (recalculates) texture mapping for given object
|
||||
void ChangeTextureMapping(int objRank, int state,
|
||||
const std::string& tex1Name, const std::string& tex2Name,
|
||||
EngineTextureMapping mode,
|
||||
float au, float bu, float av, float bv);
|
||||
|
||||
//! Changes texture mapping for robot tracks
|
||||
void TrackTextureMapping(int objRank, int state,
|
||||
const std::string& tex1Name, const std::string& tex2Name,
|
||||
EngineTextureMapping mode,
|
||||
float pos, float factor, float tl, float ts, float tt);
|
||||
void SetUVTransform(int objRank, int state, const glm::vec2& offset, const glm::vec2& scale);
|
||||
|
||||
//! Detects the target object that is selected with the mouse
|
||||
/** Returns the rank of the object or -1. */
|
||||
|
|
|
@ -86,6 +86,8 @@ CGL33ObjectRenderer::CGL33ObjectRenderer(CGL33Device* device)
|
|||
m_triplanarScale = glGetUniformLocation(m_program, "uni_TriplanarScale");
|
||||
m_dirty = glGetUniformLocation(m_program, "uni_Dirty");
|
||||
m_alphaScissor = glGetUniformLocation(m_program, "uni_AlphaScissor");
|
||||
m_uvOffset = glGetUniformLocation(m_program, "uni_UVOffset");
|
||||
m_uvScale = glGetUniformLocation(m_program, "uni_UVScale");
|
||||
|
||||
m_shadowRegions = glGetUniformLocation(m_program, "uni_ShadowRegions");
|
||||
|
||||
|
@ -174,6 +176,8 @@ void CGL33ObjectRenderer::CGL33ObjectRenderer::Begin()
|
|||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
SetUVTransform({ 0.0f, 0.0f }, { 1.0f, 1.0f });
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::CGL33ObjectRenderer::End()
|
||||
|
@ -349,6 +353,12 @@ void CGL33ObjectRenderer::SetTransparency(TransparencyMode mode)
|
|||
}
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetUVTransform(const glm::vec2& offset, const glm::vec2& scale)
|
||||
{
|
||||
glUniform2fv(m_uvOffset, 1, glm::value_ptr(offset));
|
||||
glUniform2fv(m_uvScale, 1, glm::value_ptr(scale));
|
||||
}
|
||||
|
||||
void CGL33ObjectRenderer::SetPrimaryTextureEnabled(bool enabled)
|
||||
{
|
||||
glUniform1f(m_primaryEnabled, enabled ? 1.0f : 0.0f);
|
||||
|
|
|
@ -83,6 +83,10 @@ public:
|
|||
virtual void SetCullMode(bool enabled) override;
|
||||
//! Sets transparency mode
|
||||
virtual void SetTransparency(TransparencyMode mode) override;
|
||||
|
||||
//! Sets UV transform
|
||||
virtual void SetUVTransform(const glm::vec2& offset, const glm::vec2& scale) override;
|
||||
|
||||
virtual void SetPrimaryTextureEnabled(bool enabled) override;
|
||||
|
||||
//! Sets triplanar mode
|
||||
|
@ -119,6 +123,8 @@ private:
|
|||
GLint m_triplanarScale = -1;
|
||||
GLint m_dirty = -1;
|
||||
GLint m_alphaScissor = -1;
|
||||
GLint m_uvOffset = -1;
|
||||
GLint m_uvScale = -1;
|
||||
|
||||
struct ShadowUniforms
|
||||
{
|
||||
|
|
|
@ -24,6 +24,9 @@ uniform mat4 uni_ViewMatrix;
|
|||
uniform mat4 uni_ModelMatrix;
|
||||
uniform mat3 uni_NormalMatrix;
|
||||
|
||||
uniform vec2 uni_UVOffset;
|
||||
uniform vec2 uni_UVScale;
|
||||
|
||||
layout(location = 0) in vec4 in_VertexCoord;
|
||||
layout(location = 1) in vec3 in_Normal;
|
||||
layout(location = 2) in vec4 in_Color;
|
||||
|
@ -49,7 +52,7 @@ void main()
|
|||
gl_Position = uni_ProjectionMatrix * eyeSpace;
|
||||
|
||||
data.Color = in_Color;
|
||||
data.TexCoord0 = in_TexCoord0;
|
||||
data.TexCoord0 = in_TexCoord0 * uni_UVScale + uni_UVOffset;
|
||||
data.TexCoord1 = in_TexCoord1;
|
||||
data.Normal = mat3(uni_NormalMatrix) * in_Normal;
|
||||
data.VertexCoord = in_VertexCoord.xyz;
|
||||
|
|
|
@ -395,14 +395,14 @@ void CAutoPortico::UpdateTrackMapping(float left, float right)
|
|||
{
|
||||
int rank = m_object->GetObjectRank(0);
|
||||
|
||||
std::string teamStr = StrUtils::ToString<int>(m_object->GetTeam());
|
||||
if(m_object->GetTeam() == 0) teamStr = "";
|
||||
constexpr float scale = 0.25f / 8.0f;
|
||||
|
||||
m_engine->TrackTextureMapping(rank, Gfx::ENG_RSTATE_PART1, "objects/lemt.png"+teamStr, "",
|
||||
Gfx::EngineTextureMapping::X,
|
||||
right, 8.0f, 8.0f, 192.0f, 256.0f);
|
||||
left = left - std::floor(left);
|
||||
right = right - std::floor(right);
|
||||
|
||||
m_engine->TrackTextureMapping(rank, Gfx::ENG_RSTATE_PART2, "objects/lemt.png"+teamStr, "",
|
||||
Gfx::EngineTextureMapping::X,
|
||||
left, 8.0f, 8.0f, 192.0f, 256.0f);
|
||||
m_engine->SetUVTransform(rank, Gfx::ENG_RSTATE_PART1,
|
||||
{ (1.0f - right) * scale, 0.0f }, { 1.0f, 1.0f });
|
||||
|
||||
m_engine->SetUVTransform(rank, Gfx::ENG_RSTATE_PART2,
|
||||
{ (1.0f - left) * scale, 0.0f }, { 1.0f, 1.0f });
|
||||
}
|
||||
|
|
|
@ -1984,25 +1984,25 @@ void CMotionVehicle::UpdateTrackMapping(float left, float right, ObjectType type
|
|||
std::string teamStr = StrUtils::ToString<int>(m_object->GetTeam());
|
||||
if(m_object->GetTeam() == 0) teamStr = "";
|
||||
|
||||
constexpr float scale = 0.25f / 8.0f;
|
||||
|
||||
left = left - std::floor(left);
|
||||
right = right - std::floor(right);
|
||||
|
||||
if (type == OBJECT_MOBILEdr)
|
||||
{
|
||||
m_engine->TrackTextureMapping(rRank, Gfx::ENG_RSTATE_PART1, "objects/drawer.png"+teamStr, "",
|
||||
Gfx::EngineTextureMapping::X,
|
||||
right, 1.0f, 8.0f, 192.0f, 256.0f);
|
||||
m_engine->SetUVTransform(rRank, Gfx::ENG_RSTATE_PART1,
|
||||
{ (1.0f - right) * scale, 0.0f }, { 1.0f, 1.0f });
|
||||
|
||||
m_engine->TrackTextureMapping(lRank, Gfx::ENG_RSTATE_PART2, "objects/drawer.png"+teamStr, "",
|
||||
Gfx::EngineTextureMapping::X,
|
||||
left, 1.0f, 8.0f, 192.0f, 256.0f);
|
||||
m_engine->SetUVTransform(lRank, Gfx::ENG_RSTATE_PART2,
|
||||
{ (1.0f - left) * scale, 0.0f }, { 1.0f, 1.0f });
|
||||
}
|
||||
else
|
||||
{
|
||||
m_engine->TrackTextureMapping(rRank, Gfx::ENG_RSTATE_PART1, "objects/lemt.png"+teamStr, "",
|
||||
Gfx::EngineTextureMapping::X,
|
||||
right, 1.0f, 8.0f, 192.0f, 256.0f);
|
||||
m_engine->SetUVTransform(rRank, Gfx::ENG_RSTATE_PART1,
|
||||
{ (1.0f - right) * scale, 0.0f }, { 1.0f, 1.0f });
|
||||
|
||||
m_engine->TrackTextureMapping(lRank, Gfx::ENG_RSTATE_PART2, "objects/lemt.png"+teamStr, "",
|
||||
Gfx::EngineTextureMapping::X,
|
||||
left, 1.0f, 8.0f, 192.0f, 256.0f);
|
||||
m_engine->SetUVTransform(lRank, Gfx::ENG_RSTATE_PART2,
|
||||
{ (1.0f - left) * scale, 0.0f }, { 1.0f, 1.0f });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2120,7 +2120,7 @@ void COldObject::FlatParent()
|
|||
|
||||
void COldObject::UpdateEnergyMapping()
|
||||
{
|
||||
if (Math::IsEqual(GetEnergyLevel(), m_lastEnergy, 0.01f))
|
||||
if (m_lastEnergy == GetEnergyLevel())
|
||||
return;
|
||||
|
||||
m_lastEnergy = GetEnergyLevel();
|
||||
|
@ -2152,10 +2152,9 @@ void COldObject::UpdateEnergyMapping()
|
|||
|
||||
std::string teamStr = StrUtils::ToString<int>(GetTeam());
|
||||
if(GetTeam() == 0) teamStr = "";
|
||||
m_engine->ChangeTextureMapping(m_objectPart[0].object,
|
||||
Gfx::ENG_RSTATE_PART3, "objects/lemt.png"+teamStr, "",
|
||||
Gfx::EngineTextureMapping::ONE_Y,
|
||||
au, bu, 1.0f, 0.0f);
|
||||
|
||||
m_engine->SetUVTransform(m_objectPart[0].object, Gfx::ENG_RSTATE_PART3,
|
||||
{ 0.0f, 0.25f * (GetEnergyLevel() - 1.0f) }, { 1.0f, 1.0f });
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue