diff options
Diffstat (limited to 'src/graphics')
-rw-r--r-- | src/graphics/engine/engine.cpp | 313 | ||||
-rw-r--r-- | src/graphics/engine/engine.h | 46 | ||||
-rw-r--r-- | src/graphics/opengl/gldevice.cpp | 2 |
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)); } |