summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/graphics/engine/engine.cpp313
-rw-r--r--src/graphics/engine/engine.h46
-rw-r--r--src/graphics/opengl/gldevice.cpp2
3 files changed, 122 insertions, 239 deletions
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index 73cd73a..ea0c093 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -459,145 +459,82 @@ int CEngine::GetStatisticTriangle()
Object management
*******************************************************/
-EngineBaseObjTexTier& CEngine::AddLevel2(int baseObjRank, const std::string& tex1Name, const std::string& tex2Name)
+EngineBaseObjTexTier& CEngine::AddLevel2(EngineBaseObject& p1, const std::string& tex1Name, const std::string& tex2Name)
{
- bool unusedPresent = false;
- for (int i = 0; i < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); i++)
+ for (int i = 0; i < static_cast<int>( p1.next.size() ); i++)
{
- if (! m_baseObjects[baseObjRank].next[i].used)
- {
- unusedPresent = true;
- continue;
- }
-
- if (m_baseObjects[baseObjRank].next[i].tex1Name == tex1Name && m_baseObjects[baseObjRank].next[i].tex2Name == tex2Name)
- return m_baseObjects[baseObjRank].next[i];
- }
-
- if (unusedPresent)
- {
- for (int i = 0; i < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); i++)
- {
- if (! m_baseObjects[baseObjRank].next[i].used)
- {
- m_baseObjects[baseObjRank].next[i].used = true;
- m_baseObjects[baseObjRank].next[i].tex1Name = tex1Name;
- m_baseObjects[baseObjRank].next[i].tex2Name = tex2Name;
- return m_baseObjects[baseObjRank].next[i];
- }
- }
+ if (p1.next[i].tex1Name == tex1Name && p1.next[i].tex2Name == tex2Name)
+ return p1.next[i];
}
- m_baseObjects[baseObjRank].next.push_back(EngineBaseObjTexTier(true, tex1Name, tex2Name));
- return m_baseObjects[baseObjRank].next.back();
+ p1.next.push_back(EngineBaseObjTexTier(tex1Name, tex2Name));
+ return p1.next.back();
}
EngineBaseObjLODTier& CEngine::AddLevel3(EngineBaseObjTexTier& p2, float min, float max)
{
- bool unusedPresent = false;
for (int i = 0; i < static_cast<int>( p2.next.size() ); i++)
{
- if (! p2.next[i].used)
- {
- unusedPresent = true;
- continue;
- }
-
if ( (p2.next[i].min == min) && (p2.next[i].max == max) )
return p2.next[i];
}
- if (unusedPresent)
- {
- for (int i = 0; i < static_cast<int>( p2.next.size() ); i++)
- {
- if (! p2.next[i].used)
- {
- p2.next[i].used = true;
- p2.next[i].min = min;
- p2.next[i].max = max;
- return p2.next[i];
- }
- }
- }
-
- p2.next.push_back(EngineBaseObjLODTier(true, min, max));
+ p2.next.push_back(EngineBaseObjLODTier(min, max));
return p2.next.back();
}
EngineBaseObjDataTier& CEngine::AddLevel4(EngineBaseObjLODTier& p3, EngineTriangleType type,
const Material& material, int state)
{
- bool unusedPresent = false;
for (int i = 0; i < static_cast<int>( p3.next.size() ); i++)
{
- if (! p3.next[i].used)
- {
- unusedPresent = true;
- continue;
- }
-
if ( (p3.next[i].type == type) && (p3.next[i].material == material) && (p3.next[i].state == state) )
return p3.next[i];
}
- if (unusedPresent)
- {
- for (int i = 0; i < static_cast<int>( p3.next.size() ); i++)
- {
- if (! p3.next[i].used)
- {
- p3.next[i].used = true;
- p3.next[i].type = type;
- p3.next[i].material = material;
- p3.next[i].state = state;
- return p3.next[i];
- }
- }
- }
-
- p3.next.push_back(EngineBaseObjDataTier(true, type, material, state));
+ p3.next.push_back(EngineBaseObjDataTier(type, material, state));
return p3.next.back();
}
int CEngine::CreateBaseObject()
{
- int i = 0;
- for ( ; i < static_cast<int>( m_baseObjects.size() ); i++)
+ int baseObjRank = 0;
+ for ( ; baseObjRank < static_cast<int>( m_baseObjects.size() ); baseObjRank++)
{
- if (! m_baseObjects[i].used)
+ if (! m_baseObjects[baseObjRank].used)
{
- m_baseObjects[i].LoadDefault();
+ m_baseObjects[baseObjRank].LoadDefault();
break;
}
}
- if (i == static_cast<int>( m_baseObjects.size() ))
+ if (baseObjRank == static_cast<int>( m_baseObjects.size() ))
m_baseObjects.push_back(EngineBaseObject());
else
- m_baseObjects[i].LoadDefault();
+ m_baseObjects[baseObjRank].LoadDefault();
- m_baseObjects[i].used = true;
+ m_baseObjects[baseObjRank].used = true;
- return i;
+ return baseObjRank;
}
void CEngine::DeleteBaseObject(int baseObjRank)
{
- assert(baseObjRank < -1 || baseObjRank >= static_cast<int>( m_baseObjects.size() ));
+ assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
+
+ EngineBaseObject& p1 = m_baseObjects[baseObjRank];
+
+ if (! p1.used)
+ return;
- for (int l2 = 0; l2 < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); l2++)
+ for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
- EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2];
- if (! p2.used)
- continue;
+ EngineBaseObjTexTier& p2 = p1.next[l2];
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
- if (! p3.used)
- continue;
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
@@ -607,10 +544,11 @@ void CEngine::DeleteBaseObject(int baseObjRank)
p4.staticBufferId = 0;
}
}
-
- p2.used = false;
- p2.next.clear();
}
+
+ p1.next.clear();
+
+ p1.used = false;
}
void CEngine::DeleteAllBaseObjects()
@@ -638,7 +576,8 @@ void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector<VertexTex2>
m_lastObjectDetail = m_objectDetail;
m_lastClippingDistance = m_clippingDistance;
- EngineBaseObjTexTier& p2 = AddLevel2(baseObjRank, tex1Name, tex2Name);
+ EngineBaseObject& p1 = m_baseObjects[baseObjRank];
+ EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name);
EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max);
EngineBaseObjDataTier& p4 = AddLevel4(p3, triangleType, material, state);
@@ -655,22 +594,21 @@ void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector<VertexTex2>
{
for (int i = 0; i < static_cast<int>( vertices.size() ); i++)
{
- m_baseObjects[baseObjRank].bboxMin.x = Math::Min(vertices[i].coord.x, m_baseObjects[baseObjRank].bboxMin.x);
- m_baseObjects[baseObjRank].bboxMin.y = Math::Min(vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMin.y);
- m_baseObjects[baseObjRank].bboxMin.z = Math::Min(vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMin.z);
- m_baseObjects[baseObjRank].bboxMax.x = Math::Max(vertices[i].coord.x, m_baseObjects[baseObjRank].bboxMax.x);
- m_baseObjects[baseObjRank].bboxMax.y = Math::Max(vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMax.y);
- m_baseObjects[baseObjRank].bboxMax.z = Math::Max(vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMax.z);
+ p1.bboxMin.x = Math::Min(vertices[i].coord.x, p1.bboxMin.x);
+ p1.bboxMin.y = Math::Min(vertices[i].coord.y, p1.bboxMin.y);
+ p1.bboxMin.z = Math::Min(vertices[i].coord.z, p1.bboxMin.z);
+ p1.bboxMax.x = Math::Max(vertices[i].coord.x, p1.bboxMax.x);
+ p1.bboxMax.y = Math::Max(vertices[i].coord.y, p1.bboxMax.y);
+ p1.bboxMax.z = Math::Max(vertices[i].coord.z, p1.bboxMax.z);
}
- m_baseObjects[baseObjRank].radius = Math::Max(m_baseObjects[baseObjRank].bboxMin.Length(),
- m_baseObjects[baseObjRank].bboxMax.Length());
+ p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
}
if (triangleType == ENG_TRIANGLE_TYPE_TRIANGLES)
- m_baseObjects[baseObjRank].totalTriangles += vertices.size() / 3;
+ p1.totalTriangles += vertices.size() / 3;
else
- m_baseObjects[baseObjRank].totalTriangles += vertices.size() - 2;
+ p1.totalTriangles += vertices.size() - 2;
}
void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer,
@@ -679,17 +617,15 @@ void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buff
{
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
- EngineBaseObjTexTier& p2 = AddLevel2(baseObjRank, tex1Name, tex2Name);
+ EngineBaseObject& p1 = m_baseObjects[baseObjRank];
+ EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name);
EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max);
p3.next.push_back(buffer);
EngineBaseObjDataTier& p4 = p3.next.back();
- p4.used = true;
-
- p4.updateStaticBuffer = true;
- m_updateStaticBuffers = true;
+ UpdateStaticBuffer(p4);
if (globalUpdate)
{
@@ -699,52 +635,51 @@ void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buff
{
for (int i = 0; i < static_cast<int>( p4.vertices.size() ); i++)
{
- m_baseObjects[baseObjRank].bboxMin.x = Math::Min(p4.vertices[i].coord.x, m_baseObjects[baseObjRank].bboxMin.x);
- m_baseObjects[baseObjRank].bboxMin.y = Math::Min(p4.vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMin.y);
- m_baseObjects[baseObjRank].bboxMin.z = Math::Min(p4.vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMin.z);
- m_baseObjects[baseObjRank].bboxMax.x = Math::Max(p4.vertices[i].coord.x, m_baseObjects[baseObjRank].bboxMax.x);
- m_baseObjects[baseObjRank].bboxMax.y = Math::Max(p4.vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMax.y);
- m_baseObjects[baseObjRank].bboxMax.z = Math::Max(p4.vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMax.z);
+ p1.bboxMin.x = Math::Min(p4.vertices[i].coord.x, p1.bboxMin.x);
+ p1.bboxMin.y = Math::Min(p4.vertices[i].coord.y, p1.bboxMin.y);
+ p1.bboxMin.z = Math::Min(p4.vertices[i].coord.z, p1.bboxMin.z);
+ p1.bboxMax.x = Math::Max(p4.vertices[i].coord.x, p1.bboxMax.x);
+ p1.bboxMax.y = Math::Max(p4.vertices[i].coord.y, p1.bboxMax.y);
+ p1.bboxMax.z = Math::Max(p4.vertices[i].coord.z, p1.bboxMax.z);
}
- m_baseObjects[baseObjRank].radius = Math::Max(m_baseObjects[baseObjRank].bboxMin.Length(),
- m_baseObjects[baseObjRank].bboxMax.Length());
+ p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
}
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
- m_baseObjects[baseObjRank].totalTriangles += p4.vertices.size() / 3;
+ p1.totalTriangles += p4.vertices.size() / 3;
else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE)
- m_baseObjects[baseObjRank].totalTriangles += p4.vertices.size() - 2;
+ p1.totalTriangles += p4.vertices.size() - 2;
}
int CEngine::CreateObject()
{
- int i = 0;
- for ( ; i < static_cast<int>( m_objects.size() ); i++)
+ int objRank = 0;
+ for ( ; objRank < static_cast<int>( m_objects.size() ); objRank++)
{
- if (! m_objects[i].used)
+ if (! m_objects[objRank].used)
{
- m_objects[i].LoadDefault();
+ m_objects[objRank].LoadDefault();
break;
}
}
- if (i == static_cast<int>( m_objects.size() ))
+ if (objRank == static_cast<int>( m_objects.size() ))
m_objects.push_back(EngineObject());
- m_objects[i].used = true;
+ m_objects[objRank].used = true;
Math::Matrix mat;
mat.LoadIdentity();
- SetObjectTransform(i, mat);
+ SetObjectTransform(objRank, mat);
- m_objects[i].drawWorld = true;
- m_objects[i].distance = 0.0f;
- m_objects[i].shadowRank = -1;
+ m_objects[objRank].drawWorld = true;
+ m_objects[objRank].distance = 0.0f;
+ m_objects[objRank].shadowRank = -1;
- return i;
+ return objRank;
}
void CEngine::DeleteAllObjects()
@@ -861,11 +796,11 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
- for (int l2 = 0; l2 < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); l2++)
+ EngineBaseObject& p1 = m_baseObjects[baseObjRank];
+
+ for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
- EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2];
- if (! p2.used)
- continue;
+ EngineBaseObjTexTier& p2 = p1.next[l2];
if (p2.tex1Name != tex1Name)
continue;
@@ -873,8 +808,6 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
- if (! p3.used)
- continue;
if (p3.min != min || p3.max != max)
continue;
@@ -882,8 +815,6 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
- if (! p4.used)
- continue;
if ( (p4.state & (~(ENG_RSTATE_DUAL_BLACK|ENG_RSTATE_DUAL_WHITE))) != state ||
p4.material != material )
@@ -905,23 +836,21 @@ int CEngine::GetPartialTriangles(int objRank, float min, float max, float percen
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
- int total = m_baseObjects[baseObjRank].totalTriangles;
+ EngineBaseObject& p1 = m_baseObjects[baseObjRank];
+
+ int total = p1.totalTriangles;
int expectedCount = static_cast<int>(percent * total);
triangles.reserve(Math::Min(maxCount, expectedCount));
int actualCount = 0;
- for (int l2 = 0; l2 < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); l2++)
+ for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
- EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2];
- if (! p2.used)
- continue;
+ EngineBaseObjTexTier& p2 = p1.next[l2];
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
- if (! p3.used)
- continue;
if (p3.min != min || p3.max != max)
continue;
@@ -929,8 +858,6 @@ int CEngine::GetPartialTriangles(int objRank, float min, float max, float percen
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
- if (! p4.used)
- continue;
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
{
@@ -1006,20 +933,18 @@ void CEngine::ChangeLOD()
for (int baseObjRank = 0; baseObjRank < static_cast<int>( m_baseObjects.size() ); baseObjRank++)
{
- if (! m_baseObjects[baseObjRank].used)
+ EngineBaseObject& p1 = m_baseObjects[baseObjRank];
+
+ if (! p1.used)
continue;
- for (int l2 = 0; l2 < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); l2++)
+ for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
- EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2];
- if (! p2.used)
- continue;
+ EngineBaseObjTexTier& p2 = p1.next[l2];
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
- if (! p3.used)
- continue;
if ( Math::IsEqual(p3.min, 0.0f ) &&
Math::IsEqual(p3.max, oldLimit[0]) )
@@ -1057,21 +982,18 @@ void CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name)
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
-
+
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
- if (! p2.used)
- continue;
if (p2.tex2Name == tex2Name)
continue; // already new
- EngineBaseObjTexTier& newP2 = AddLevel2(baseObjRank, p2.tex1Name, tex2Name);
+ EngineBaseObjTexTier& newP2 = AddLevel2(p1, p2.tex1Name, tex2Name);
newP2.next.swap(p2.next);
- p2.used = false;
}
}
@@ -1143,7 +1065,7 @@ void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state,
float pos, float factor, float tl, float ts, float tt)
{
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
-
+
EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, min, max);
if (p4 == nullptr)
return;
@@ -1424,16 +1346,18 @@ bool CEngine::GetBBox2D(int objRank, Math::Point &min, Math::Point &max)
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
+ EngineBaseObject& p1 = m_baseObjects[baseObjRank];
+
for (int i = 0; i < 8; i++)
{
Math::Vector p;
- if ( i & (1<<0) ) p.x = m_baseObjects[baseObjRank].bboxMin.x;
- else p.x = m_baseObjects[baseObjRank].bboxMax.x;
- if ( i & (1<<1) ) p.y = m_baseObjects[baseObjRank].bboxMin.y;
- else p.y = m_baseObjects[baseObjRank].bboxMax.y;
- if ( i & (1<<2) ) p.z = m_baseObjects[baseObjRank].bboxMin.z;
- else p.z = m_baseObjects[baseObjRank].bboxMax.z;
+ if ( i & (1<<0) ) p.x = p1.bboxMin.x;
+ else p.x = p1.bboxMax.x;
+ if ( i & (1<<1) ) p.y = p1.bboxMin.y;
+ else p.y = p1.bboxMax.y;
+ if ( i & (1<<2) ) p.z = p1.bboxMin.z;
+ else p.z = p1.bboxMax.z;
Math::Vector pp;
if (TransformPoint(pp, objRank, p))
@@ -1598,20 +1522,14 @@ void CEngine::UpdateGeometry()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
- if (! p2.used)
- continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
- if (! p3.used)
- continue;
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
- if (! p4.used)
- continue;
for (int i = 0; i < static_cast<int>( p4.vertices.size() ); i++)
{
@@ -1664,20 +1582,14 @@ void CEngine::UpdateStaticBuffers()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
- if (! p2.used)
- continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
- if (! p3.used)
- continue;
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
- if (! p4.used)
- continue;
if (! p4.updateStaticBuffer)
continue;
@@ -1703,6 +1615,8 @@ bool CEngine::DetectBBox(int objRank, Math::Point mouse)
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>(m_baseObjects.size()));
+ EngineBaseObject& p1 = m_baseObjects[baseObjRank];
+
Math::Point min, max;
min.x = 1000000.0f;
min.y = 1000000.0f;
@@ -1713,12 +1627,12 @@ bool CEngine::DetectBBox(int objRank, Math::Point mouse)
{
Math::Vector p;
- if ( i & (1<<0) ) p.x = m_baseObjects[baseObjRank].bboxMin.x;
- else p.x = m_baseObjects[baseObjRank].bboxMax.x;
- if ( i & (1<<1) ) p.y = m_baseObjects[baseObjRank].bboxMin.y;
- else p.y = m_baseObjects[baseObjRank].bboxMax.y;
- if ( i & (1<<2) ) p.z = m_baseObjects[baseObjRank].bboxMin.z;
- else p.z = m_baseObjects[baseObjRank].bboxMax.z;
+ if ( i & (1<<0) ) p.x = p1.bboxMin.x;
+ else p.x = p1.bboxMax.x;
+ if ( i & (1<<1) ) p.y = p1.bboxMin.y;
+ else p.y = p1.bboxMax.y;
+ if ( i & (1<<2) ) p.z = p1.bboxMin.z;
+ else p.z = p1.bboxMax.z;
Math::Vector pp;
if ( TransformPoint(pp, objRank, p) )
@@ -1762,14 +1676,10 @@ int CEngine::DetectObject(Math::Point mouse)
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
- if (! p2.used)
- continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
- if (! p3.used)
- continue;
if (p3.min != 0.0f)
continue; // LOD B or C?
@@ -1777,8 +1687,6 @@ int CEngine::DetectObject(Math::Point mouse)
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
- if (! p4.used)
- continue;
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
{
@@ -2273,8 +2181,6 @@ bool CEngine::LoadAllTextures()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
- if (! p2.used)
- continue;
if (! p2.tex1Name.empty())
{
@@ -3083,7 +2989,7 @@ void CEngine::Draw3DScene()
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
-
+
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
if (! p1.used)
continue;
@@ -3091,18 +2997,13 @@ void CEngine::Draw3DScene()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
- if (! p2.used)
- continue;
- // Should be loaded by now
SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
- if (! p3.used)
- continue;
if ( m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max )
@@ -3111,8 +3012,6 @@ void CEngine::Draw3DScene()
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
- if (! p4.used)
- continue;
SetMaterial(p4.material);
SetState(p4.state);
@@ -3163,18 +3062,13 @@ void CEngine::Draw3DScene()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
- if (! p2.used)
- continue;
- // Should be loaded by now
SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
- if (! p3.used)
- continue;
if ( m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max )
@@ -3183,8 +3077,6 @@ void CEngine::Draw3DScene()
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
- if (! p4.used)
- continue;
if (m_objects[objRank].transparency != 0.0f) // transparent ?
{
@@ -3236,18 +3128,13 @@ void CEngine::Draw3DScene()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
- if (! p2.used)
- continue;
- // Should be loaded by now
SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
- if (! p3.used)
- continue;
if (m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max)
@@ -3256,8 +3143,6 @@ void CEngine::Draw3DScene()
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
- if (! p4.used)
- continue;
if (m_objects[objRank].transparency == 0.0f)
continue;
@@ -3393,8 +3278,6 @@ void CEngine::DrawInterface()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
- if (! p2.used)
- continue;
SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1);
@@ -3402,8 +3285,6 @@ void CEngine::DrawInterface()
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
- if (! p3.used)
- continue;
if (m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max)
@@ -3412,8 +3293,6 @@ void CEngine::DrawInterface()
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
- if (! p4.used)
- continue;
SetMaterial(p4.material);
SetState(p4.state);
diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h
index ad934a6..899abc0 100644
--- a/src/graphics/engine/engine.h
+++ b/src/graphics/engine/engine.h
@@ -185,7 +185,6 @@ enum EngineObjectType
*/
struct EngineBaseObjDataTier
{
- bool used;
EngineTriangleType type;
Material material;
int state;
@@ -193,11 +192,10 @@ struct EngineBaseObjDataTier
unsigned int staticBufferId;
bool updateStaticBuffer;
- inline EngineBaseObjDataTier(bool used = false,
- EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES,
+ inline EngineBaseObjDataTier(EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES,
const Material& material = Material(),
int state = ENG_RSTATE_NORMAL)
- : used(used), type(type), material(material), state(state), staticBufferId(0), updateStaticBuffer(false) {}
+ : type(type), material(material), state(state), staticBufferId(0), updateStaticBuffer(false) {}
};
/**
@@ -206,13 +204,12 @@ struct EngineBaseObjDataTier
*/
struct EngineBaseObjLODTier
{
- bool used;
float min;
float max;
std::vector<EngineBaseObjDataTier> next;
- inline EngineBaseObjLODTier(bool used = false, float min = 0.0f, float max = 0.0f)
- : used(used), min(min), max(max) {}
+ inline EngineBaseObjLODTier(float min = 0.0f, float max = 0.0f)
+ : min(min), max(max) {}
};
/**
@@ -221,16 +218,14 @@ struct EngineBaseObjLODTier
*/
struct EngineBaseObjTexTier
{
- bool used;
std::string tex1Name;
Texture tex1;
std::string tex2Name;
Texture tex2;
std::vector<EngineBaseObjLODTier> next;
- inline EngineBaseObjTexTier(bool used = false, const std::string& tex1Name = "",
- const std::string& tex2Name = "")
- : used(used), tex1Name(tex1Name), tex2Name(tex2Name) {}
+ inline EngineBaseObjTexTier(const std::string& tex1Name = "", const std::string& tex2Name = "")
+ : tex1Name(tex1Name), tex2Name(tex2Name) {}
};
/**
@@ -624,27 +619,36 @@ struct EngineMouse
*
* Objects are uniquely identified by object rank obtained at object creation. Creating an
* object equals to allocating space for EngineObject structure which holds object parameters.
- * Object's geometric data is stored in a separate structure - a 4-tier tree which splits
- * the information of each geometric triangle.
+ *
+ * Object's geometric data is stored as a separate object -- base engine object. Each object
+ * must reference a valid base engine object. This many-to-one association allows to share
+ * same geometric data (e.g. from same model) across objects. Base engine objects are identified
+ * by unique rank obtained upon their creation.
+ *
+ * Base engine object data is stored in a 4-tier tree which splits the data describing triangles.
*
* The 4 tiers contain the following information:
- * - level 1 (EngineObjLevel1) - two textures (names and structs) applied to triangles,
- * - level 2 (EngineObjLevel2) - object rank
- * - level 3 (EngineObjLevel3) - minumum and maximum LOD (=level of detail)
- * - level 4 (EngineObjLevel4) - type of object*, material, render state and the actual triangle data
+ * - level 1 (EngineBaseObject) - geometric statistics
+ * - level 2 (EngineBaseObjTexTier) - two textures (names and structs) applied to triangles,
+ * - level 3 (EngineBaseObjLODTier) - minumum and maximum LOD (=level of detail)
+ * - level 4 (EngineBaseObjDataTier) - type of object*, material, render state and the actual vertex data
*
- * NOTE: type of object in this context means only the internal type in 3D engine. It is not related
+ * *NOTE: type of object in this context means only the internal type in 3D engine. It is not related
* to CObject types.
*
+ * Last tier containing vertex data contains also an ID of static buffer holding the data.
+ * The static buffer is created and updated with new data as needed.
+ *
* Such tiered structure complicates loops over all object data, but saves a lot of memory and
- * optimizes the rendering process (for instance, switching of textures is an expensive operation).
+ * optimizes the rendering process.
*
* \section Shadows Shadows
*
* Each engine object can be associated with a shadow (EngineShadow). Like objects, shadows are
* identified by their rank obtained upon creation.
*
- * ...
+ * Shadows are drawn as circular spots on the ground, except for shadows for worms, which have
+ * special mode for them.
*
* \section RenderStates Render States
*
@@ -1213,7 +1217,7 @@ protected:
void DrawStats();
//! Creates a new tier 2 object (texture)
- EngineBaseObjTexTier& AddLevel2(int baseObjRank, const std::string& tex1Name, const std::string& tex2Name);
+ EngineBaseObjTexTier& AddLevel2(EngineBaseObject& p1, const std::string& tex1Name, const std::string& tex2Name);
//! Creates a new tier 3 object (LOD)
EngineBaseObjLODTier& AddLevel3(EngineBaseObjTexTier &p2, float min, float max);
//! Creates a new tier 4 object (data)
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index c1e18d3..024a523 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -1151,7 +1151,7 @@ void CGLDevice::DrawStaticBuffer(unsigned int bufferId)
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast<char*>(nullptr) + offsetof(Vertex, normal));
- glActiveTexture(GL_TEXTURE0);
+ glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast<char*>(nullptr) + offsetof(Vertex, texCoord));
}