Skip to content

Commit

Permalink
refactor Lua unit material management to sane(r) code
Browse files Browse the repository at this point in the history
  • Loading branch information
rtri committed Nov 22, 2015
1 parent c51dbda commit a23029f
Show file tree
Hide file tree
Showing 9 changed files with 350 additions and 324 deletions.
16 changes: 16 additions & 0 deletions rts/Game/Camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ class CCamera

static float3 GetRotFromDir(float3 dir);

float ProjectedDistance(const float3 objPos) const {
const float3 diff = objPos - GetPos();
const float dist = diff.dot(GetDir());
return dist;
}

/*
float ProjectedDistanceShadow(const float3 objPos, const float3 sunDir) const {
// FIXME: fix it, cap it for shallow shadows?
const float3 diff = (GetPos() - objPos);
const float dot = diff.dot(sunDir);
const float3 gap = diff - (sunDir * dot);
return (gap.Length());
}
*/

private:
void ComputeViewRange();

Expand Down
40 changes: 29 additions & 11 deletions rts/Lua/LuaMaterial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ LuaMatHandler& luaMatHandler = LuaMatHandler::handler;
// LuaUnitUniforms
//

void LuaUnitUniforms::Execute(CUnit* unit) const
void LuaUnitUniforms::Execute(const CUnit* unit) const
{
// FIXME use vertex attributes
if (!haveUniforms) {
Expand All @@ -56,7 +56,7 @@ void LuaUnitUniforms::Execute(CUnit* unit) const
}
if (customLoc >= 0) {
if (customCount > 0) {
glUniform1fv(customLoc, customCount, customData);
glUniform1fv(customLoc, customCount, &customData[0]);
}
}
}
Expand All @@ -65,12 +65,12 @@ void LuaUnitUniforms::Execute(CUnit* unit) const
void LuaUnitUniforms::SetCustomCount(int count)
{
customCount = count;
delete[] customData;

if (count > 0) {
customData = new float[count];
memset(customData, 0, customCount * sizeof(GLfloat));
customData.resize(count);
memset(&customData[0], 0, customCount * sizeof(GLfloat));
} else {
customData = NULL;
customData.clear();
}
}

Expand All @@ -79,8 +79,7 @@ LuaUnitUniforms& LuaUnitUniforms::operator=(const LuaUnitUniforms& u)
{
// do not assign to self
if (this != &u) {
delete[] customData;
customData = NULL;
customData.clear();

haveUniforms = u.haveUniforms;
speedLoc = u.speedLoc;
Expand All @@ -91,8 +90,8 @@ LuaUnitUniforms& LuaUnitUniforms::operator=(const LuaUnitUniforms& u)
customCount = u.customCount;

if (customCount > 0) {
customData = new GLfloat[customCount];
memcpy(customData, u.customData, customCount * sizeof(GLfloat));
customData.resize(customCount);
memcpy(&customData[0], &u.customData[0], customCount * sizeof(GLfloat));
}
}

Expand All @@ -102,7 +101,6 @@ LuaUnitUniforms& LuaUnitUniforms::operator=(const LuaUnitUniforms& u)

LuaUnitUniforms::LuaUnitUniforms(const LuaUnitUniforms& u)
{
customData = NULL;
*this = u;
}

Expand Down Expand Up @@ -619,3 +617,23 @@ void LuaMatHandler::PrintAllBins(const string& indent) const

/******************************************************************************/
/******************************************************************************/

float LuaUnitMaterialData::UNIT_GLOBAL_LOD_FACTOR = 1.0f;

unsigned int LuaUnitMaterialData::CalcCurrentLOD(float lodDist, unsigned int lastLOD) const
{
if (lastLOD == 0)
return 0;

// positive values only!
const float lpp = std::max(0.0f, lodDist * UNIT_GLOBAL_LOD_FACTOR);

for (/* no-op */; lastLOD != 0; lastLOD--) {
if (lpp > lodLengths[lastLOD]) {
break;
}
}

return lastLOD;
}

147 changes: 56 additions & 91 deletions rts/Lua/LuaOpenGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1327,127 +1327,92 @@ static inline CUnit* ParseUnit(lua_State* L, const char* caller, int index)

/******************************************************************************/

int LuaOpenGL::Unit(lua_State* L)
{
CheckDrawingEnabled(L, __FUNCTION__);

CUnit* unit = ParseUnit(L, __FUNCTION__, 1);
if (unit == NULL) {
return 0;
}
static bool UnitDrawPreCommon(lua_State* L, CUnit* unit)
{
LuaUnitMaterialData* lmd = unit->GetLuaMaterialData();

const bool rawDraw = luaL_optboolean(L, 2, false);
if (!lmd->Enabled())
return false;

bool useLOD = true;
if (unit->lodCount <= 0) {
useLOD = false;
}
else {
unsigned int lod = 0;
if (!lua_isnumber(L, 3)) {
const LuaMatType matType =
(water->DrawReflectionPass()) ? LUAMAT_OPAQUE_REFLECT : LUAMAT_OPAQUE;
lod = unitDrawer->CalcUnitLOD(unit, unit->luaMats[matType].GetLastLOD());
} else {
int tmpLod = lua_toint(L, 3);
if (tmpLod < 0) {
useLOD = false;
} else {
lod = std::min(unit->lodCount - 1, (unsigned int)tmpLod);
}
if (!lua_isnumber(L, 3)) {
// calculate new LOD level
lmd->UpdateCurrentLOD(camera->ProjectedDistance(unit->pos), (water->DrawReflectionPass())? LUAMAT_OPAQUE_REFLECT: LUAMAT_OPAQUE);
return true;
} else {
// set new LOD level manually
if (lua_toint(L, 3) >= 0) {
lmd->SetCurrentLOD(std::min(lmd->GetLODCount() - 1, static_cast<unsigned int>(lua_toint(L, 3))));
return true;
}
unit->currentLOD = lod;
}

return false;
}

static void UnitDrawPostCommon(CUnit* unit, bool applyTransform, bool doRawDraw, bool useLuaMat) {
glPushAttrib(GL_ENABLE_BIT);

if (rawDraw) {
if (useLOD) {
LuaUnitMaterialData* lmd = unit->GetLuaMaterialData();

if (!useLuaMat) {
// "scoped" draw; this prevents any Lua-assigned
// material(s) from being used by the calls below
lmd->PushLODCount(0);
}

if (applyTransform) {
if (doRawDraw) {
unitDrawer->DrawUnitRaw(unit);
} else {
const unsigned int origLodCount = unit->lodCount;
unit->lodCount = 0;
unitDrawer->DrawUnitRaw(unit);
unit->lodCount = origLodCount;
}
}
else {
if (useLOD) {
unitDrawer->DrawIndividual(unit);
}
} else {
if (doRawDraw) {
unitDrawer->DrawUnitRawModel(unit);
} else {
const unsigned int origLodCount = unit->lodCount;
unit->lodCount = 0;
unitDrawer->DrawIndividual(unit);
unit->lodCount = origLodCount;
// FIXME? no no-transform version of this
// unitDrawer->DrawIndividual(unit);
}
}

glPopAttrib();
if (!useLuaMat) {
lmd->PopLODCount();
}

return 0;
glPopAttrib();
}


int LuaOpenGL::UnitRaw(lua_State* L)
int LuaOpenGL::Unit(lua_State* L)
{
CheckDrawingEnabled(L, __FUNCTION__);

CUnit* unit = ParseUnit(L, __FUNCTION__, 1);
if (unit == NULL) {

if (unit == NULL)
return 0;
}

const bool rawDraw = luaL_optboolean(L, 2, false);
const bool doRawDraw = luaL_optboolean(L, 2, false);
const bool useLuaMat = UnitDrawPreCommon(L, unit);

bool useLOD = true;
if (unit->lodCount <= 0) {
useLOD = false;
}
else {
unsigned int lod = 0;
if (!lua_isnumber(L, 3)) {
const LuaMatType matType =
(water->DrawReflectionPass()) ? LUAMAT_OPAQUE_REFLECT : LUAMAT_OPAQUE;
lod = unitDrawer->CalcUnitLOD(unit, unit->luaMats[matType].GetLastLOD());
} else {
int tmpLod = lua_toint(L, 3);
if (tmpLod < 0) {
useLOD = false;
} else {
lod = std::min(unit->lodCount - 1, (unsigned int)tmpLod);
}
}
unit->currentLOD = lod;
}
UnitDrawPostCommon(unit, true, doRawDraw, useLuaMat);
return 0;
}

glPushAttrib(GL_ENABLE_BIT);
int LuaOpenGL::UnitRaw(lua_State* L)
{
CheckDrawingEnabled(L, __FUNCTION__);

if (rawDraw) {
if (useLOD) {
unitDrawer->DrawUnitRawModel(unit);
} else {
const unsigned int origLodCount = unit->lodCount;
unit->lodCount = 0;
// transformation is not applied
unitDrawer->DrawUnitRawModel(unit);
unit->lodCount = origLodCount;
}
}
else {
/*
if (useLOD) {
unitDrawer->DrawIndividual(unit);
} else {
const unsigned int origLodCount = unit->lodCount;
unit->lodCount = 0;
unitDrawer->DrawIndividual(unit);
unit->lodCount = origLodCount;
}
*/
}
CUnit* unit = ParseUnit(L, __FUNCTION__, 1);

glPopAttrib();
if (unit == NULL)
return 0;

const bool doRawDraw = luaL_optboolean(L, 2, false);
const bool useLuaMat = UnitDrawPreCommon(L, unit);

UnitDrawPostCommon(unit, false, doRawDraw, useLuaMat);
return 0;
}

Expand Down

1 comment on commit a23029f

@ashdnazg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the adding of luaMaterialData to CUnit broke the CREG test

Please sign in to comment.