From a90cd304ba4310833f239cd0d1528c3700ecbe99 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 19 Oct 2012 22:37:11 +0200 Subject: Track texture mapping --- src/graphics/engine/engine.cpp | 101 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 9 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 3365b24..90c00f5 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -812,9 +812,9 @@ EngineObjLevel4& CEngine::AddLevel4(EngineObjLevel3& p3, EngineTriangleType type } bool CEngine::AddTriangles(int objRank, const std::vector& vertices, - const Material& material, int state, - std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate) + const Material& material, int state, + std::string tex1Name, std::string tex2Name, + float min, float max, bool globalUpdate) { if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) { @@ -1247,12 +1247,95 @@ bool CEngine::ChangeTextureMapping(int objRank, const Material& mat, int state, } bool CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, - const std::string& tex1Name, const std::string& tex2Name, - float min, float max, EngineTextureMapping mode, - float pos, float factor, float tl, float ts, float tt) + const std::string& tex1Name, const std::string& tex2Name, + float min, float max, EngineTextureMapping mode, + float pos, float factor, float tl, float ts, float tt) { - // TODO track texture mapping: pretty complex code, so leaving it for now - GetLogger()->Trace("CEngine::TrackTextureMapping(): stub!\n"); + EngineObjLevel4* triangles = FindTriangles(objRank, mat, state, tex1Name, tex2Name, min, max); + if (triangles == nullptr) return false; + + int tNum = triangles->vertices.size(); + if (tNum < 12 || tNum % 6 != 0) return false; + + std::vector& vs = triangles->vertices; + + while (pos < 0.0f) + pos += 1000000.0f; // never negative! + + // TODO: might still be buggy as track animation seems to be choppy + // but the code should work exactly as in original + + Math::Vector current; + + for (int i = 0; i < 6; i++) + { + for (int j = 0; j < 6; j++) + { + if (Math::IsEqual(vs[i].coord.x, vs[j+6].coord.x) && + Math::IsEqual(vs[i].coord.y, vs[j+6].coord.y)) + { + current.x = vs[i].coord.x; // position end link + current.y = vs[i].coord.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].coord.x, current.x, 0.0001f) && + Math::IsEqual(vs[tBase + i].coord.y, current.y, 0.0001f)) + { + ie[e++] = i; + } + else + { + is[s++] = i; + } + } + if (s == 3 && e == 3) + { + pe = ps + Math::Point(vs[tBase + is[0]].coord.x - vs[tBase + ie[0]].coord.x, + vs[tBase + is[0]].coord.y - vs[tBase + ie[0]].coord.y).Length() / factor; // end position on the periphery + + float pps = ps + pos; + float ppe = pe + pos; + float offset = static_cast( static_cast(pps) ); + ppe -= offset; + + for (int i = 0; i < 3; i++) + { + vs[tBase + is[i]].texCoord.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].coord.x, current.x, 0.0001f) || + !Math::IsEqual(vs[tBase + i+6].coord.y, current.y, 0.0001f)) + { + current.x = vs[tBase + i+6].coord.x; // end next link + current.y = vs[tBase + i+6].coord.y; + break; + } + } + ps = pe; // following start position on the periphery + tBase += 6; + } + return true; } @@ -3586,7 +3669,7 @@ void CEngine::DrawBackgroundImage() p2.x = 1.0f; p2.y = 1.0f; -Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal + Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal float u1, u2, v1, v2; if (m_backgroundFull) -- cgit v1.2.3-1-g7c22 From be4654c63b80862352961160446155238eee3ef5 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 19 Oct 2012 22:43:18 +0200 Subject: Fix track mapping and sphere particle position --- src/graphics/engine/engine.cpp | 11 +++++------ src/graphics/engine/particle.cpp | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 90c00f5..6d07b62 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -1260,10 +1260,7 @@ bool CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, std::vector& vs = triangles->vertices; while (pos < 0.0f) - pos += 1000000.0f; // never negative! - - // TODO: might still be buggy as track animation seems to be choppy - // but the code should work exactly as in original + pos += 1.0f; // never negative! Math::Vector current; @@ -1310,12 +1307,14 @@ bool CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, float pps = ps + pos; float ppe = pe + pos; - float offset = static_cast( static_cast(pps) ); + int offset = static_cast(pps); ppe -= offset; + pps -= offset; for (int i = 0; i < 3; i++) { - vs[tBase + is[i]].texCoord.x = ((ppe * tl) + ts) / tt; + vs[tBase + is[i]].texCoord.x = ((pps * tl) + ts) / tt; + vs[tBase + ie[i]].texCoord.x = ((ppe * tl) + ts) / tt; } } diff --git a/src/graphics/engine/particle.cpp b/src/graphics/engine/particle.cpp index acc40df..388c189 100644 --- a/src/graphics/engine/particle.cpp +++ b/src/graphics/engine/particle.cpp @@ -3214,7 +3214,7 @@ void CParticle::DrawParticleSphere(int i) angle.z = m_particle[i].angle*0.7f; Math::Matrix rot; Math::LoadRotationZXYMatrix(rot, angle); - mat = Math::MultiplyMatrices(rot, mat); + mat = Math::MultiplyMatrices(mat, rot); } m_device->SetTransform(TRANSFORM_WORLD, mat); -- cgit v1.2.3-1-g7c22 From 6d06c9f722885805f7e150173706804634b3e5d4 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 19 Oct 2012 23:05:41 +0200 Subject: Flare textures should work now --- src/graphics/engine/engine.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 6d07b62..daf0386 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -3271,8 +3271,7 @@ void CEngine::Draw3DScene() m_particle->DrawParticle(SH_WORLD); // draws the particles of the 3D world m_lightning->Draw(); // draws lightning - // TODO: fix white screen error; commenting out temporarily - // if (m_lensMode) DrawForegroundImage(); // draws the foreground + if (m_lensMode) DrawForegroundImage(); // draws the foreground if (! m_overFront) DrawOverColor(); // draws the foreground color } -- cgit v1.2.3-1-g7c22 From 40e065aea947b45700930d431754282c23d1de45 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sat, 20 Oct 2012 16:34:22 +0200 Subject: Ground spot texture drawing --- src/graphics/engine/engine.cpp | 268 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 257 insertions(+), 11 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index daf0386..019e959 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -1638,6 +1638,7 @@ void CEngine::CreateGroundMark(Math::Vector pos, float radius, { m_groundMark.LoadDefault(); + m_groundMark.draw = true; m_groundMark.phase = ENG_GR_MARK_PHASE_INC; m_groundMark.delay[0] = delay1; m_groundMark.delay[1] = delay2; @@ -3409,8 +3410,262 @@ void CEngine::DrawInterface() void CEngine::UpdateGroundSpotTextures() { - // TODO the original code modifying the textures is very complex, so stub for now - GetLogger()->Trace("CEngine::UpdateGroundSpotTextures(): stub!\n"); + if (!m_firstGroundSpot && + m_groundMark.drawPos.x == m_groundMark.pos.x && + m_groundMark.drawPos.z == m_groundMark.pos.z && + m_groundMark.drawRadius == m_groundMark.radius && + m_groundMark.drawIntensity == m_groundMark.intensity) return; + + for (int s = 0; s < 16; s++) + { + Math::Point min, max; + min.x = (s%4) * 254.0f - 1.0f; // 1 pixel cover + min.y = (s/4) * 254.0f - 1.0f; + max.x = min.x + 254.0f + 2.0f; + max.y = min.y + 254.0f + 2.0f; + + bool clear = false; + bool set = false; + + // Calculate the area to be erased. + int dot = static_cast(m_groundMark.drawRadius/2.0f); + + float tu, tv; + float cx, cy; + + tu = (m_groundMark.drawPos.x+1600.0f)/3200.0f; + tv = (m_groundMark.drawPos.z+1600.0f)/3200.0f; // 0..1 + + cx = (tu*254.0f*4.0f)-0.5f; + cy = (tv*254.0f*4.0f)-0.5f; + + if (dot == 0) + { + cx += 0.5f; + cy += 0.5f; + } + + float px = cx-Math::Mod(cx, 1.0f); + float py = cy-Math::Mod(cy, 1.0f); // multiple of 1 + + if (m_firstGroundSpot || + (m_groundMark.drawRadius != 0.0f && + px+dot >= min.x && py+dot >= min.y && + px-dot <= max.x && py-dot <= max.y)) + { + clear = true; + } + + // Calculate the area to draw. + dot = static_cast(m_groundMark.radius/2.0f); + + tu = (m_groundMark.pos.x+1600.0f)/3200.0f; + tv = (m_groundMark.pos.z+1600.0f)/3200.0f; // 0..1 + + cx = (tu*254.0f*4.0f)-0.5f; + cy = (tv*254.0f*4.0f)-0.5f; + + if ( dot == 0 ) + { + cx += 0.5f; + cy += 0.5f; + } + + px = cx - Math::Mod(cx, 1.0f); + py = cy - Math::Mod(cy, 1.0f); // multiple of 1 + + if (m_groundMark.draw && + px+dot >= min.x && py+dot >= min.y && + px-dot <= max.x && py-dot <= max.y) + { + set = true; + } + + if (clear || set) + { + CImage shadowImg(Math::IntPoint(256, 256)); + shadowImg.Fill(Gfx::IntColor(255, 255, 255, 255)); + + // Draw the new shadows. + for (int i = 0; i < static_cast( m_groundSpots.size() ); i++) + { + if ( m_groundSpots[i].used == false || + m_groundSpots[i].radius == 0.0f ) continue; + + if ( m_groundSpots[i].min == 0.0f && + m_groundSpots[i].max == 0.0f ) + { + dot = static_cast(m_groundSpots[i].radius/2.0f); + + tu = (m_groundSpots[i].pos.x+1600.0f)/3200.0f; + tv = (m_groundSpots[i].pos.z+1600.0f)/3200.0f; // 0..1 + + cx = (tu*254.0f*4.0f) - 0.5f; + cy = (tv*254.0f*4.0f) - 0.5f; + + if (dot == 0) + { + cx += 0.5f; + cy += 0.5f; + } + + px = cx-Math::Mod(cx, 1.0f); + py = cy-Math::Mod(cy, 1.0f); // multiple of 1 + + if ( px+dot < min.x || py+dot < min.y || + px-dot > max.x || py-dot > max.y ) continue; + + for (int iy = -dot; iy <= dot; iy++) + { + for (int ix =- dot; ix <= dot; ix++) + { + float ppx = px+ix; + float ppy = py+iy; + + if ( ppx < min.x || ppy < min.y || + ppx >= max.x || ppy >= max.y ) continue; + + float intensity; + if (dot == 0) + intensity = 0.0f; + else + intensity = Math::Point(ppx-cx, ppy-cy).Length()/dot; + + Gfx::Color color; + color.r = Math::Norm(m_groundSpots[i].color.r+intensity); + color.g = Math::Norm(m_groundSpots[i].color.g+intensity); + color.b = Math::Norm(m_groundSpots[i].color.b+intensity); + + ppx -= min.x; // on the texture + ppy -= min.y; + + shadowImg.SetPixel(Math::IntPoint(ppx, ppy), color); + } + } + } + else + { + for (int iy = 0; iy < 256; iy++) + { + for (int ix = 0; ix < 256; ix++) + { + Math::Vector pos; + pos.x = (256.0f * (s%4) + ix) * 3200.0f/1024.0f - 1600.0f; + pos.z = (256.0f * (s/4) + iy) * 3200.0f/1024.0f - 1600.0f; + pos.y = 0.0f; + + float level = m_terrain->GetFloorLevel(pos, true); + if ( level < m_groundSpots[i].min || + level > m_groundSpots[i].max ) continue; + + float intensity; + if (level > (m_groundSpots[i].max+m_groundSpots[i].min)/2.0f) + intensity = 1.0f - (m_groundSpots[i].max-level) / m_groundSpots[i].smooth; + else + intensity = 1.0f - (level-m_groundSpots[i].min) / m_groundSpots[i].smooth; + + if (intensity < 0.0f) intensity = 0.0f; + + Gfx::Color color; + color.r = Math::Norm(m_groundSpots[i].color.r+intensity); + color.g = Math::Norm(m_groundSpots[i].color.g+intensity); + color.b = Math::Norm(m_groundSpots[i].color.b+intensity); + + shadowImg.SetPixel(Math::IntPoint(ix, iy), color); + } + } + } + } + + if (set) + { + dot = static_cast(m_groundMark.radius/2.0f); + + tu = (m_groundMark.pos.x + 1600.0f) / 3200.0f; + tv = (m_groundMark.pos.z + 1600.0f) / 3200.0f; // 0..1 + + cx = (tu*254.0f*4.0f)-0.5f; + cy = (tv*254.0f*4.0f)-0.5f; + + if (dot == 0) + { + cx += 0.5f; + cy += 0.5f; + } + + px = cx-Math::Mod(cx, 1.0f); + py = cy-Math::Mod(cy, 1.0f); // multiple of 1 + + for (int iy = -dot; iy <= dot; iy++) + { + for (int ix = -dot; ix <= dot; ix++) + { + float ppx = px+ix; + float ppy = py+iy; + + if (ppx < min.x || ppy < min.y || + ppx >= max.x || ppy >= max.y) continue; + + ppx -= min.x; // on the texture + ppy -= min.y; + + float intensity = 1.0f - Math::Point(ix, iy).Length() / dot; + if (intensity <= 0.0f) continue; + intensity *= m_groundMark.intensity; + + int j = (ix+dot) + (iy+dot) * m_groundMark.dx; + if (m_groundMark.table[j] == 1) // green ? + { + Gfx::Color color; + color.r = Math::Norm(1.0f-intensity); + color.g = 1.0f; + color.b = Math::Norm(1.0f-intensity); + shadowImg.SetPixel(Math::IntPoint(ppx, ppy), color); + } + if (m_groundMark.table[j] == 2) // red ? + { + Gfx::Color color; + color.r = 1.0f; + color.g = Math::Norm(1.0f-intensity); + color.b = Math::Norm(1.0f-intensity); + shadowImg.SetPixel(Math::IntPoint(ppx, ppy), color); + } + } + } + } + + std::stringstream str; + str << "shadow" << std::setfill('0') << std::setw(2) << s << ".png"; + std::string texName = str.str(); + + DeleteTexture(texName); + + Gfx::Texture tex = m_device->CreateTexture(&shadowImg, m_defaultTexParams); + + m_texNameMap[texName] = tex; + m_revTexNameMap[tex] = texName; + } + } + + for (int i = 0; i < static_cast( m_groundSpots.size() ); i++) + { + if (m_groundSpots[i].used == false || + m_groundSpots[i].radius == 0.0f) + { + m_groundSpots[i].drawRadius = 0.0f; + } + else + { + m_groundSpots[i].drawPos = m_groundSpots[i].pos; + m_groundSpots[i].drawRadius = m_groundSpots[i].radius; + } + } + + m_groundMark.drawPos = m_groundMark.pos; + m_groundMark.drawRadius = m_groundMark.radius; + m_groundMark.drawIntensity = m_groundMark.intensity; + + m_firstGroundSpot = false; } void CEngine::DrawShadow() @@ -3607,7 +3862,6 @@ void CEngine::DrawShadow() m_device->SetRenderState(RENDER_STATE_LIGHTING, true); } -// STATUS: TESTED, VERIFIED void CEngine::DrawBackground() { if (m_skyMode && m_cloud->GetLevel() != 0.0f) // clouds ? @@ -3627,7 +3881,6 @@ void CEngine::DrawBackground() } } -// STATUS: TESTED void CEngine::DrawBackgroundGradient(const Color& up, const Color& down) { Math::Point p1(0.0f, 0.5f); @@ -3658,7 +3911,6 @@ void CEngine::DrawBackgroundGradient(const Color& up, const Color& down) AddStatisticTriangle(2); } -// Status: TESTED, VERIFIED void CEngine::DrawBackgroundImage() { Math::Point p1, p2; @@ -3729,7 +3981,6 @@ void CEngine::DrawPlanet() m_planet->Draw(); // draws the planets } -// Status: PART_TESTED void CEngine::DrawForegroundImage() { if (m_foregroundName.empty()) return; @@ -3765,10 +4016,8 @@ void CEngine::DrawForegroundImage() AddStatisticTriangle(2); } -// Status: PART_TESTED void CEngine::DrawOverColor() { - // TODO: fuzzy compare? if ( (m_overColor == Color(0.0f, 0.0f, 0.0f, 0.0f) && m_overMode == ENG_RSTATE_TCOLOR_BLACK) || (m_overColor == Color(1.0f, 1.0f, 1.0f, 1.0f) && m_overMode == ENG_RSTATE_TCOLOR_WHITE) ) return; @@ -3805,7 +4054,6 @@ void CEngine::DrawOverColor() AddStatisticTriangle(2); } -// Status: TESTED, VERIFIED void CEngine::DrawHighlight() { Math::Point min, max; @@ -3897,7 +4145,6 @@ void CEngine::DrawHighlight() m_device->DrawPrimitive(PRIMITIVE_LINE_STRIP, line, 3); } -// Status: TESTED, VERIFIED void CEngine::DrawMouse() { MouseMode mode = m_app->GetMouseMode(); @@ -3931,7 +4178,6 @@ void CEngine::DrawMouse() DrawMouseSprite(pos, m_mouseSize, m_mice[index].icon2); } -// Status: TESTED, VERIFIED void CEngine::DrawMouseSprite(Math::Point pos, Math::Point size, int icon) { if (icon == -1) -- cgit v1.2.3-1-g7c22 From 728e7e405dd56afb4da03fd63df378d5f984ed73 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sat, 20 Oct 2012 18:40:24 +0200 Subject: Transparent plant textures --- src/graphics/engine/modelfile.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/modelfile.cpp b/src/graphics/engine/modelfile.cpp index c0d04a0..3b0343a 100644 --- a/src/graphics/engine/modelfile.cpp +++ b/src/graphics/engine/modelfile.cpp @@ -608,9 +608,6 @@ bool CModelFile::ReadModel(std::istream& stream) triangle.state = t.state; triangle.variableTex2 = t.texNum2 == 1; - if (triangle.tex1Name == "plant.png") - triangle.state |= ENG_RSTATE_ALPHA; - if (!triangle.variableTex2 && t.texNum2 != 0) { if (t.texNum2 >= 1 && t.texNum2 <= 10) @@ -637,6 +634,10 @@ bool CModelFile::ReadModel(std::istream& stream) m_triangles[i].tex2Name = StrUtils::Replace(m_triangles[i].tex2Name, "bmp", "png"); m_triangles[i].tex2Name = StrUtils::Replace(m_triangles[i].tex2Name, "tga", "png"); + // TODO: fix this in model files + if (m_triangles[i].tex1Name == "plant.png") + m_triangles[i].state |= ENG_RSTATE_ALPHA; + GetLogger()->Trace("ModelTriangle %d\n", i+1); std::string s1 = m_triangles[i].p1.ToString(); GetLogger()->Trace(" p1: %s\n", s1.c_str()); -- cgit v1.2.3-1-g7c22 From 688315ab76145a32d0aebf826fbbb7fc9ce24443 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sat, 20 Oct 2012 23:06:56 +0200 Subject: ComputeSphereVisibility and fixes in CEngine TODOs - view frustum culling with ComputeSphereVisibility - game should run faster now - resolved/removed most TODOs from CEngine - fixed OpenGL tests --- src/graphics/core/device.h | 29 +++++------ src/graphics/engine/engine.cpp | 60 ++++++++++++----------- src/graphics/engine/engine.h | 6 --- src/graphics/engine/water.cpp | 6 ++- src/graphics/opengl/gldevice.cpp | 80 +++++++++++++++++-------------- src/graphics/opengl/test/light_test.cpp | 27 ++++++++++- src/graphics/opengl/test/texture_test.cpp | 1 - 7 files changed, 122 insertions(+), 87 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h index b6dd138..8e7d446 100644 --- a/src/graphics/core/device.h +++ b/src/graphics/core/device.h @@ -204,22 +204,22 @@ enum PrimitiveType }; /** - * \enum IntersectPlane - * \brief Intersection plane of projection volume + * \enum FrustumPlane + * \brief Planes of frustum space * - * These flags can be OR'd together. + * Bitset of flags - can be OR'd together. */ -enum IntersectPlane +enum FrustumPlane { - INTERSECT_PLANE_LEFT = 0x01, - INTERSECT_PLANE_RIGHT = 0x02, - INTERSECT_PLANE_TOP = 0x04, - INTERSECT_PLANE_BOTTOM = 0x08, - INTERSECT_PLANE_FRONT = 0x10, - INTERSECT_PLANE_BACK = 0x20, - INTERSECT_PLANE_ALL = INTERSECT_PLANE_LEFT | INTERSECT_PLANE_RIGHT | - INTERSECT_PLANE_TOP | INTERSECT_PLANE_BOTTOM | - INTERSECT_PLANE_FRONT | INTERSECT_PLANE_BACK + FRUSTUM_PLANE_LEFT = 0x01, + FRUSTUM_PLANE_RIGHT = 0x02, + FRUSTUM_PLANE_TOP = 0x04, + FRUSTUM_PLANE_BOTTOM = 0x08, + FRUSTUM_PLANE_FRONT = 0x10, + FRUSTUM_PLANE_BACK = 0x20, + FRUSTUM_PLANE_ALL = FRUSTUM_PLANE_LEFT | FRUSTUM_PLANE_RIGHT | + FRUSTUM_PLANE_TOP | FRUSTUM_PLANE_BOTTOM | + FRUSTUM_PLANE_FRONT | FRUSTUM_PLANE_BACK }; /** @@ -316,7 +316,8 @@ public: //! Renders primitive composed of vertices with color information virtual void DrawPrimitive(PrimitiveType type, const VertexCol *vertices , int vertexCount) = 0; - //! Tests whether a sphere intersects the 6 clipping planes of projection volume + //! Tests whether a sphere is (partially) within the frustum volume + //! Returns a mask of frustum planes for which the test is positive virtual int ComputeSphereVisibility(const Math::Vector ¢er, float radius) = 0; //! Enables/disables the given render state diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 019e959..ca10304 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -422,18 +422,6 @@ bool CEngine::WriteScreenShot(const std::string& fileName, int width, int height return true; } -bool CEngine::ReadSettings() -{ - // TODO: when INI reading is completed - return true; -} - -bool CEngine::WriteSettings() -{ - // TODO: when INI writing is completed - return true; -} - void CEngine::SetPause(bool pause) { m_pause = pause; @@ -966,7 +954,6 @@ EngineObjLevel4* CEngine::FindTriangles(int objRank, const Material& material, if (! p1.used) continue; if (p1.tex1Name != tex1Name) continue; - // TODO: tex2Name compare? for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) { @@ -1557,7 +1544,22 @@ void CEngine::FlushGroundSpot() m_groundSpots.clear(); m_firstGroundSpot = true; - // TODO: blank all shadow textures + for (int s = 0; s < 16; s++) + { + CImage shadowImg(Math::IntPoint(256, 256)); + shadowImg.Fill(Gfx::IntColor(255, 255, 255, 255)); + + std::stringstream str; + str << "shadow" << std::setfill('0') << std::setw(2) << s << ".png"; + std::string texName = str.str(); + + DeleteTexture(texName); + + Gfx::Texture tex = m_device->CreateTexture(&shadowImg, m_defaultTexParams); + + m_texNameMap[texName] = tex; + m_revTexNameMap[tex] = texName; + } } int CEngine::CreateGroundSpot() @@ -1658,8 +1660,6 @@ void CEngine::DeleteGroundMark(int rank) void CEngine::ComputeDistance() { - // TODO: s_resol??? - for (int i = 0; i < static_cast( m_objects.size() ); i++) { if (! m_objects[i].used) @@ -1877,9 +1877,18 @@ bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRan return true; } +//! Use only after world transform already set bool CEngine::IsVisible(int objRank) { - // TODO: use ComputeSphereVisiblity() after tested OK + float radius = m_objects[objRank].radius; + Math::Vector center(0.0f, 0.0f, 0.0f); + if (m_device->ComputeSphereVisibility(center, radius) == Gfx::FRUSTUM_PLANE_ALL) + { + m_objects[objRank].visible = true; + return true; + } + + m_objects[objRank].visible = false; return true; } @@ -1938,7 +1947,7 @@ void CEngine::SetState(int state, const Color& color) params.colorOperation = TEX_MIX_OPER_MODULATE; params.colorArg1 = TEX_MIX_ARG_TEXTURE; params.colorArg2 = TEX_MIX_ARG_FACTOR; - params.alphaOperation = TEX_MIX_OPER_DEFAULT; // TODO: replace with src color ? + params.alphaOperation = TEX_MIX_OPER_DEFAULT; params.factor = color; m_device->SetTextureEnabled(0, true); @@ -1957,7 +1966,7 @@ void CEngine::SetState(int state, const Color& color) params.colorOperation = TEX_MIX_OPER_ADD; params.colorArg1 = TEX_MIX_ARG_TEXTURE; params.colorArg2 = TEX_MIX_ARG_FACTOR; - params.alphaOperation = TEX_MIX_OPER_DEFAULT; // TODO: replace with src color ? + params.alphaOperation = TEX_MIX_OPER_DEFAULT; params.factor = color.Inverse(); m_device->SetTextureEnabled(0, true); @@ -1997,7 +2006,7 @@ void CEngine::SetState(int state, const Color& color) TextureStageParams params; params.colorOperation = TEX_MIX_OPER_REPLACE; params.colorArg1 = TEX_MIX_ARG_TEXTURE; - params.alphaOperation = TEX_MIX_OPER_DEFAULT; // TODO: replace with src color ? + params.alphaOperation = TEX_MIX_OPER_DEFAULT; m_device->SetTextureEnabled(0, true); m_device->SetTextureStageParams(0, params); @@ -2065,7 +2074,7 @@ void CEngine::SetState(int state, const Color& color) TextureStageParams params; params.colorOperation = TEX_MIX_OPER_DEFAULT; // default modulate - params.alphaOperation = TEX_MIX_OPER_DEFAULT; // TODO: replace with src color ? + params.alphaOperation = TEX_MIX_OPER_DEFAULT; m_device->SetTextureEnabled(0, true); m_device->SetTextureStageParams(0, params); @@ -2086,7 +2095,7 @@ void CEngine::SetState(int state, const Color& color) params.colorOperation = TEX_MIX_OPER_MODULATE; params.colorArg1 = TEX_MIX_ARG_TEXTURE; params.colorArg2 = TEX_MIX_ARG_COMPUTED_COLOR; - params.alphaOperation = TEX_MIX_OPER_DEFAULT; // TODO: ??? + params.alphaOperation = TEX_MIX_OPER_DEFAULT; m_device->SetTextureEnabled(1, true); m_device->SetTextureStageParams(1, params); } @@ -2096,7 +2105,7 @@ void CEngine::SetState(int state, const Color& color) params.colorOperation = TEX_MIX_OPER_ADD; params.colorArg1 = TEX_MIX_ARG_TEXTURE; params.colorArg2 = TEX_MIX_ARG_COMPUTED_COLOR; - params.alphaOperation = TEX_MIX_OPER_DEFAULT; // TODO: ??? + params.alphaOperation = TEX_MIX_OPER_DEFAULT; m_device->SetTextureEnabled(1, true); m_device->SetTextureStageParams(1, params); } @@ -4033,11 +4042,6 @@ void CEngine::DrawOverColor() SetState(m_overMode); - // TODO: set also with m_overMode ? - m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false); - m_device->SetRenderState(RENDER_STATE_LIGHTING, false); - m_device->SetRenderState(RENDER_STATE_FOG, false); - m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface); m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface); m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface); diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 27f0173..d127e74 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -692,12 +692,6 @@ public: //! Writes a screenshot containing the current frame bool WriteScreenShot(const std::string& fileName, int width, int height); - - //! Reads settings from INI - bool ReadSettings(); - //! Writes settings to INI - bool WriteSettings(); - //@{ //! Management of game pause mode void SetPause(bool pause); diff --git a/src/graphics/engine/water.cpp b/src/graphics/engine/water.cpp index 18811eb..6c822b3 100644 --- a/src/graphics/engine/water.cpp +++ b/src/graphics/engine/water.cpp @@ -386,9 +386,11 @@ void CWater::DrawSurf() Math::Vector p = pos; p.x += size*(m_lines[i].len-1); float radius = sqrtf(powf(size, 2.0f)+powf(size*m_lines[i].len, 2.0f)); - if ( Math::Distance(p, eye) > deep+radius ) continue; + if (Math::Distance(p, eye) > deep + radius) + continue; - // TODO: ComputeSphereVisibility + if (device->ComputeSphereVisibility(p, radius) != Gfx::FRUSTUM_PLANE_ALL) + continue; int vertexIndex = 0; diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index 94b0dbc..a6ba1eb 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -929,27 +929,25 @@ void CGLDevice::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int bool InPlane(Math::Vector normal, float originPlane, Math::Vector center, float radius) { - float distance = (originPlane + Math::DotProduct(normal, center)) / normal.Length(); + float distance = originPlane + Math::DotProduct(normal, center); if (distance < -radius) - return true; + return false; - return false; + return true; } -/* - The implementation of ComputeSphereVisibility is taken from libwine's device.c - Copyright of the WINE team, licensed under GNU LGPL v 2.1 - */ +/* Based on libwine's implementation */ -// TODO: testing int CGLDevice::ComputeSphereVisibility(const Math::Vector ¢er, float radius) { Math::Matrix m; - m.LoadIdentity(); - m = Math::MultiplyMatrices(m, m_worldMat); - m = Math::MultiplyMatrices(m, m_viewMat); - m = Math::MultiplyMatrices(m, m_projectionMat); + m = Math::MultiplyMatrices(m_worldMat, m); + m = Math::MultiplyMatrices(m_viewMat, m); + Math::Matrix sc; + Math::LoadScaleMatrix(sc, Math::Vector(1.0f, 1.0f, -1.0f)); + m = Math::MultiplyMatrices(sc, m); + m = Math::MultiplyMatrices(m_projectionMat, m); Math::Vector vec[6]; float originPlane[6]; @@ -958,52 +956,64 @@ int CGLDevice::ComputeSphereVisibility(const Math::Vector ¢er, float radius) vec[0].x = m.Get(4, 1) + m.Get(1, 1); vec[0].y = m.Get(4, 2) + m.Get(1, 2); vec[0].z = m.Get(4, 3) + m.Get(1, 3); - originPlane[0] = m.Get(4, 4) + m.Get(1, 4); + float l1 = vec[0].Length(); + vec[0].Normalize(); + originPlane[0] = (m.Get(4, 4) + m.Get(1, 4)) / l1; // Right plane vec[1].x = m.Get(4, 1) - m.Get(1, 1); vec[1].y = m.Get(4, 2) - m.Get(1, 2); vec[1].z = m.Get(4, 3) - m.Get(1, 3); - originPlane[1] = m.Get(4, 4) - m.Get(1, 4); - - // Top plane - vec[2].x = m.Get(4, 1) - m.Get(2, 1); - vec[2].y = m.Get(4, 2) - m.Get(2, 2); - vec[2].z = m.Get(4, 3) - m.Get(2, 3); - originPlane[2] = m.Get(4, 4) - m.Get(2, 4); + float l2 = vec[1].Length(); + vec[1].Normalize(); + originPlane[1] = (m.Get(4, 4) - m.Get(1, 4)) / l2; // Bottom plane - vec[3].x = m.Get(4, 1) + m.Get(2, 1); - vec[3].y = m.Get(4, 2) + m.Get(2, 2); - vec[3].z = m.Get(4, 3) + m.Get(2, 3); - originPlane[3] = m.Get(4, 4) + m.Get(2, 4); + vec[2].x = m.Get(4, 1) + m.Get(2, 1); + vec[2].y = m.Get(4, 2) + m.Get(2, 2); + vec[2].z = m.Get(4, 3) + m.Get(2, 3); + float l3 = vec[2].Length(); + vec[2].Normalize(); + originPlane[2] = (m.Get(4, 4) + m.Get(2, 4)) / l3; + + // Top plane + vec[3].x = m.Get(4, 1) - m.Get(2, 1); + vec[3].y = m.Get(4, 2) - m.Get(2, 2); + vec[3].z = m.Get(4, 3) - m.Get(2, 3); + float l4 = vec[3].Length(); + vec[3].Normalize(); + originPlane[3] = (m.Get(4, 4) - m.Get(2, 4)) / l4; // Front plane - vec[4].x = m.Get(3, 1); - vec[4].y = m.Get(3, 2); - vec[4].z = m.Get(3, 3); - originPlane[4] = m.Get(3, 4); + vec[4].x = m.Get(4, 1) + m.Get(3, 1); + vec[4].y = m.Get(4, 2) + m.Get(3, 2); + vec[4].z = m.Get(4, 3) + m.Get(3, 3); + float l5 = vec[4].Length(); + vec[4].Normalize(); + originPlane[4] = (m.Get(4, 4) + m.Get(3, 4)) / l5; // Back plane vec[5].x = m.Get(4, 1) - m.Get(3, 1); vec[5].y = m.Get(4, 2) - m.Get(3, 2); vec[5].z = m.Get(4, 3) - m.Get(3, 3); - originPlane[5] = m.Get(4, 4) - m.Get(3, 4); + float l6 = vec[5].Length(); + vec[5].Normalize(); + originPlane[5] = (m.Get(4, 4) - m.Get(3, 4)) / l6; int result = 0; if (InPlane(vec[0], originPlane[0], center, radius)) - result |= INTERSECT_PLANE_LEFT; + result |= FRUSTUM_PLANE_LEFT; if (InPlane(vec[1], originPlane[1], center, radius)) - result |= INTERSECT_PLANE_RIGHT; + result |= FRUSTUM_PLANE_RIGHT; if (InPlane(vec[2], originPlane[2], center, radius)) - result |= INTERSECT_PLANE_TOP; + result |= FRUSTUM_PLANE_BOTTOM; if (InPlane(vec[3], originPlane[3], center, radius)) - result |= INTERSECT_PLANE_BOTTOM; + result |= FRUSTUM_PLANE_TOP; if (InPlane(vec[4], originPlane[4], center, radius)) - result |= INTERSECT_PLANE_FRONT; + result |= FRUSTUM_PLANE_FRONT; if (InPlane(vec[5], originPlane[5], center, radius)) - result |= INTERSECT_PLANE_BACK; + result |= FRUSTUM_PLANE_BACK; return result; } diff --git a/src/graphics/opengl/test/light_test.cpp b/src/graphics/opengl/test/light_test.cpp index 6ff3b1c..b19ba4b 100644 --- a/src/graphics/opengl/test/light_test.cpp +++ b/src/graphics/opengl/test/light_test.cpp @@ -51,7 +51,7 @@ void Render(Gfx::CGLDevice *device) device->SetRenderState(Gfx::RENDER_STATE_CULLING, false); // Double-sided drawing Math::Matrix persp; - Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.0f), 0.1f, 100.0f); + Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.0f), 0.1f, 50.0f); device->SetTransform(Gfx::TRANSFORM_PROJECTION, persp); @@ -121,6 +121,31 @@ void Render(Gfx::CGLDevice *device) Math::LoadTranslationMatrix(worldMat, Math::Vector(-40.0f, 2.0f, -40.0f)); device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat); + int planes = device->ComputeSphereVisibility(Math::Vector(0.0f, 0.0f, 0.0f), 1.0f); + printf("Planes:"); + if (planes == 0) + printf(" (none)"); + + if (planes & Gfx::FRUSTUM_PLANE_LEFT) + printf(" LEFT"); + + if (planes & Gfx::FRUSTUM_PLANE_RIGHT) + printf(" RIGHT"); + + if (planes & Gfx::FRUSTUM_PLANE_BOTTOM) + printf(" BOTTOM"); + + if (planes & Gfx::FRUSTUM_PLANE_TOP) + printf(" TOP"); + + if (planes & Gfx::FRUSTUM_PLANE_FRONT) + printf(" FRONT"); + + if (planes & Gfx::FRUSTUM_PLANE_BACK) + printf(" BACK"); + + printf("\n"); + device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4); for (int i = 0; i < 6; ++i) diff --git a/src/graphics/opengl/test/texture_test.cpp b/src/graphics/opengl/test/texture_test.cpp index 534a5c0..d771927 100644 --- a/src/graphics/opengl/test/texture_test.cpp +++ b/src/graphics/opengl/test/texture_test.cpp @@ -13,7 +13,6 @@ void Init(Gfx::CGLDevice *device) device->SetShadeModel(Gfx::SHADE_SMOOTH); device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false); - device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); device->SetTextureEnabled(0, true); device->SetTextureEnabled(1, true); -- cgit v1.2.3-1-g7c22 From 3ce488307f5394e51ff006458a8245bdbd5e6bfa Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Thu, 25 Oct 2012 23:29:49 +0200 Subject: Performance counters --- src/graphics/engine/engine.cpp | 144 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 130 insertions(+), 14 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index ca10304..856c2d4 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -378,7 +378,11 @@ void CEngine::FrameUpdate() float rTime = m_app->GetRelTime(); m_lightMan->UpdateProgression(rTime); + + m_app->StartPerformanceCounter(PCNT_UPDATE_PARTICLE); m_particle->FrameParticle(rTime); + m_app->StopPerformanceCounter(PCNT_UPDATE_PARTICLE); + ComputeDistance(); UpdateGeometry(); @@ -409,7 +413,7 @@ void CEngine::FrameUpdate() { m_groundMark.intensity = 0.0f; m_groundMark.phase = ENG_GR_MARK_PHASE_NULL; - m_groundMark.draw = false; + m_groundMark.draw = false; } } } @@ -3020,7 +3024,9 @@ void CEngine::Render() if (m_drawWorld) Draw3DScene(); + m_app->StartPerformanceCounter(PCNT_RENDER_INTERFACE); DrawInterface(); + m_app->StopPerformanceCounter(PCNT_RENDER_INTERFACE); // End the scene m_device->EndScene(); @@ -3051,12 +3057,13 @@ void CEngine::Draw3DScene() if (m_waterMode) m_water->DrawBack(); // draws water background + m_app->StartPerformanceCounter(PCNT_RENDER_TERRAIN); + + // Draw terrain with shadows, if shadows enabled if (m_shadowVisible) { m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN); - // Draw the terrain - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) { EngineObjLevel1& p1 = m_objectTree[l1]; @@ -3122,7 +3129,11 @@ void CEngine::Draw3DScene() DrawShadow(); } - // Draw objects (non-terrain) + m_app->StopPerformanceCounter(PCNT_RENDER_TERRAIN); + + // Draw other objects (and if shadows disabled, also terrain) + + m_app->StartPerformanceCounter(PCNT_RENDER_OBJECTS); bool transparent = false; @@ -3274,11 +3285,21 @@ void CEngine::Draw3DScene() } } + m_app->StopPerformanceCounter(PCNT_RENDER_OBJECTS); + m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN); - if (m_waterMode) m_water->DrawSurf(); // draws water surface + if (m_waterMode) + { + m_app->StartPerformanceCounter(PCNT_RENDER_WATER); + m_water->DrawSurf(); // draws water surface + m_app->StopPerformanceCounter(PCNT_RENDER_WATER); + } + m_app->StartPerformanceCounter(PCNT_RENDER_PARTICLE); m_particle->DrawParticle(SH_WORLD); // draws the particles of the 3D world + m_app->StopPerformanceCounter(PCNT_RENDER_PARTICLE); + m_lightning->Draw(); // draws lightning if (m_lensMode) DrawForegroundImage(); // draws the foreground @@ -4220,15 +4241,10 @@ void CEngine::DrawStats() if (!m_showStats) return; - std::stringstream str; - str << "Triangles: "; - str << m_statisticTriangle; - std::string triangleText = str.str(); - float height = m_text->GetAscent(FONT_COLOBOT, 12.0f); float width = 0.2f; - Math::Point pos(0.04f, 0.04f + height); + Math::Point pos(0.04f, 0.04f + 17 * height); SetState(ENG_RSTATE_OPAQUE_COLOR); @@ -4236,9 +4252,9 @@ void CEngine::DrawStats() VertexCol vertex[4] = { - VertexCol(Math::Vector(pos.x , pos.y - height, 0.0f), black), + VertexCol(Math::Vector(pos.x , pos.y - 17 * height, 0.0f), black), VertexCol(Math::Vector(pos.x , pos.y + height, 0.0f), black), - VertexCol(Math::Vector(pos.x + width, pos.y - height, 0.0f), black), + VertexCol(Math::Vector(pos.x + width, pos.y - 17 * height, 0.0f), black), VertexCol(Math::Vector(pos.x + width, pos.y + height, 0.0f), black) }; @@ -4246,7 +4262,107 @@ void CEngine::DrawStats() SetState(ENG_RSTATE_TEXT); - m_text->DrawText(triangleText, FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + std::stringstream str; + + str.str(""); + str << "Event processing: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_EVENT_PROCESSING); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + pos.y -= height; + + + str.str(""); + str << "Frame update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_ALL); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Engine update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_ENGINE); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Particle update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_PARTICLE); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Game update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_GAME); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + float otherUpdate = Math::Max(0.0f, m_app->GetPerformanceCounterData(PCNT_UPDATE_ALL) - + m_app->GetPerformanceCounterData(PCNT_UPDATE_ENGINE) - + m_app->GetPerformanceCounterData(PCNT_UPDATE_PARTICLE) - + m_app->GetPerformanceCounterData(PCNT_UPDATE_GAME)); + + str.str(""); + str << "Other update: " << std::fixed << std::setprecision(2) << otherUpdate; + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + pos.y -= height; + + + str.str(""); + str << "Frame render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_ALL); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Particle render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_PARTICLE); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Water render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_WATER); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Terrain render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_TERRAIN); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "Objects render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_OBJECTS); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + str.str(""); + str << "UI render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_INTERFACE); + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + + float otherRender = m_app->GetPerformanceCounterData(PCNT_RENDER_ALL) - + m_app->GetPerformanceCounterData(PCNT_RENDER_PARTICLE) - + m_app->GetPerformanceCounterData(PCNT_RENDER_WATER) - + m_app->GetPerformanceCounterData(PCNT_RENDER_TERRAIN) - + m_app->GetPerformanceCounterData(PCNT_RENDER_OBJECTS) - + m_app->GetPerformanceCounterData(PCNT_RENDER_INTERFACE); + + str.str(""); + str << "Other render: " << std::fixed << std::setprecision(2) << otherRender; + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); + + pos.y -= height; + pos.y -= height; + + + str.str(""); + str << "Triangles: " << m_statisticTriangle; + m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f)); pos.y -= height; -- cgit v1.2.3-1-g7c22 From 4811defca2eeea69e40346be6b1647f276db8c76 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 14 Dec 2012 21:30:35 +0100 Subject: Static objects using OpenGL VBOs and display lists --- src/graphics/core/device.h | 17 ++- src/graphics/core/vertex.h | 20 +-- src/graphics/engine/engine.cpp | 247 ++++++++++++++++++++++++++------------ src/graphics/engine/engine.h | 18 ++- src/graphics/engine/modelfile.cpp | 10 +- src/graphics/engine/pyro.cpp | 3 + src/graphics/engine/terrain.cpp | 6 + src/graphics/opengl/gldevice.cpp | 222 ++++++++++++++++++++++++++++++++++ src/graphics/opengl/gldevice.h | 36 +++++- 9 files changed, 480 insertions(+), 99 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h index 8e7d446..a0e44e4 100644 --- a/src/graphics/core/device.h +++ b/src/graphics/core/device.h @@ -313,9 +313,24 @@ public: //! Renders primitive composed of vertices with multitexturing (2 textures) virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) = 0; - //! Renders primitive composed of vertices with color information + //! Renders primitive composed of vertices with solid color virtual void DrawPrimitive(PrimitiveType type, const VertexCol *vertices , int vertexCount) = 0; + //! Creates a static buffer composed of given primitives with single texture vertices + virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) = 0; + + //! Creates a static buffer composed of given primitives with multitexturing (2 textures) + virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) = 0; + + //! Creates a static buffer composed of given primitives with solid color + virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) = 0; + + //! Draws a static buffer + virtual void DrawStaticObject(unsigned int objectId) = 0; + + //! Deletes a static buffer + virtual void DestroyStaticObject(unsigned int objectId) = 0; + //! Tests whether a sphere is (partially) within the frustum volume //! Returns a mask of frustum planes for which the test is positive virtual int ComputeSphereVisibility(const Math::Vector ¢er, float radius) = 0; diff --git a/src/graphics/core/vertex.h b/src/graphics/core/vertex.h index 2ee6be4..66e1503 100644 --- a/src/graphics/core/vertex.h +++ b/src/graphics/core/vertex.h @@ -44,23 +44,18 @@ namespace Gfx { * - vertex coordinates (x,y,z) as Math::Vector, * - normal coordinates (nx,ny,nz) as Math::Vector * - texture coordinates (u,v) as Math::Point. - * - * Additional padding is provided to align to even multiplies of 4 floats for faster access. */ struct Vertex { Math::Vector coord; - float pad1; Math::Vector normal; - float pad2; Math::Point texCoord; - float pad3, pad4; explicit Vertex(Math::Vector aCoord = Math::Vector(), Math::Vector aNormal = Math::Vector(), Math::Point aTexCoord = Math::Point()) - : coord(aCoord), pad1(0.0f), normal(aNormal), - pad2(0.0f),texCoord(aTexCoord), pad3(0.0f), pad4(0.0f) {} + : coord(aCoord), normal(aNormal), + texCoord(aTexCoord) {} //! Returns a string "(c: [...], n: [...], tc: [...])" @@ -81,18 +76,15 @@ struct Vertex * It contains: * - vertex coordinates (x,y,z) as Math::Vector, * - RGBA color as Color - * - * Additional padding is provided to align to even multiplies of 4 floats for faster access. */ struct VertexCol { Math::Vector coord; - float pad; Color color; explicit VertexCol(Math::Vector aCoord = Math::Vector(), Color aColor = Color()) - : coord(aCoord), pad(0.0f), color(aColor) {} + : coord(aCoord), color(aColor) {} //! Returns a string "(c: [...], col: [...])" inline std::string ToString() const @@ -111,15 +103,11 @@ struct VertexCol * * In addition to fields from Vector, it contains * secondary texture coordinates (u2, v2) as Math::Point - * - * Additional padding is provided to align to even multiplies of 4 floats for faster access. */ struct VertexTex2 { Math::Vector coord; - float pad1; Math::Vector normal; - float pad2; Math::Point texCoord; Math::Point texCoord2; @@ -127,7 +115,7 @@ struct VertexTex2 Math::Vector aNormal = Math::Vector(), Math::Point aTexCoord = Math::Point(), Math::Point aTexCoord2 = Math::Point()) - : coord(aCoord), pad1(0.0f), normal(aNormal), pad2(0.0f), + : coord(aCoord), normal(aNormal), texCoord(aTexCoord), texCoord2(aTexCoord2) {} //! Sets the fields from Vertex with texCoord2 = (0,0) diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 856c2d4..de5f2d4 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -92,6 +92,7 @@ EngineObjLevel4::EngineObjLevel4(bool used, EngineTriangleType type, const Mater this->type = type; this->material = material; this->state = state; + this->staticBufferId = 0; vertices.reserve(LEVEL4_VERTEX_PREALLOCATE_COUNT); } @@ -182,6 +183,7 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_alphaMode = 1; m_updateGeometry = false; + m_updateStaticObjects = false; m_interfaceMode = false; @@ -385,6 +387,7 @@ void CEngine::FrameUpdate() ComputeDistance(); UpdateGeometry(); + UpdateStaticObjects(); m_highlightTime = m_app->GetAbsTime(); @@ -570,11 +573,27 @@ bool CEngine::DeleteObject(int objRank) EngineObjLevel2& p2 = p1.next[l2]; if (! p2.used) continue; - if (p2.objRank == objRank) + if (p2.objRank != objRank) continue; + + if (m_objects[objRank].staticBuffer) { - p2.used = false; - p2.next.clear(); + for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) + { + EngineObjLevel3& p3 = p2.next[l3]; + if (! p3.used) continue; + + for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) + { + EngineObjLevel4& p4 = p3.next[l4]; + + m_device->DestroyStaticObject(p4.staticBufferId); + } + } } + + + p2.used = false; + p2.next.clear(); } } @@ -623,6 +642,22 @@ bool CEngine::GetObjectTransform(int objRank, Math::Matrix& transform) return true; } +void CEngine::SetObjectStatic(int objRank, bool staticBuffer) +{ + if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) + return; + + m_objects[objRank].staticBuffer = staticBuffer; +} + +bool CEngine::GetObjectStatic(int objRank) +{ + if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) + return false; + + return m_objects[objRank].staticBuffer; +} + bool CEngine::SetObjectDrawWorld(int objRank, bool draw) { if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) @@ -825,6 +860,17 @@ bool CEngine::AddTriangles(int objRank, const std::vector& vertices, p4.vertices.insert(p4.vertices.end(), vertices.begin(), vertices.end()); + if (m_objects[objRank].staticBuffer) + { + if (p4.staticBufferId != 0) + { + m_device->DestroyStaticObject(p4.staticBufferId); + p4.staticBufferId = 0; + } + + m_updateStaticObjects = true; + } + if (globalUpdate) { m_updateGeometry = true; @@ -872,6 +918,17 @@ bool CEngine::AddSurface(int objRank, const std::vector& vertices, p4.vertices.insert(p4.vertices.end(), vertices.begin(), vertices.end()); + if (m_objects[objRank].staticBuffer) + { + if (p4.staticBufferId != 0) + { + m_device->DestroyStaticObject(p4.staticBufferId); + p4.staticBufferId = 0; + } + + m_updateStaticObjects = true; + } + if (globalUpdate) { m_updateGeometry = true; @@ -898,8 +955,8 @@ bool CEngine::AddSurface(int objRank, const std::vector& vertices, } bool CEngine::AddQuick(int objRank, const EngineObjLevel4& buffer, - std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate) + std::string tex1Name, std::string tex2Name, + float min, float max, bool globalUpdate) { if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) { @@ -912,7 +969,26 @@ bool CEngine::AddQuick(int objRank, const EngineObjLevel4& buffer, EngineObjLevel3& p3 = AddLevel3(p2, min, max); p3.next.push_back(buffer); - p3.next.back().used = true; // ensure that it is used + + EngineObjLevel4& p4 = p3.next.back(); + p4.used = true; // ensure that it is used + + if (m_objects[objRank].staticBuffer) + { + if (p4.staticBufferId != 0) + { + m_device->DestroyStaticObject(p4.staticBufferId); + p4.staticBufferId = 0; + } + + PrimitiveType type; + if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) + type = PRIMITIVE_TRIANGLES; + else + type = PRIMITIVE_TRIANGLE_STRIP; + + p4.staticBufferId = m_device->CreateStaticObject(type, &p4.vertices[0], p4.vertices.size()); + } if (globalUpdate) { @@ -920,24 +996,24 @@ bool CEngine::AddQuick(int objRank, const EngineObjLevel4& buffer, } else { - for (int i = 0; i < static_cast( buffer.vertices.size() ); i++) + for (int i = 0; i < static_cast( p4.vertices.size() ); i++) { - m_objects[objRank].bboxMin.x = Math::Min(buffer.vertices[i].coord.x, m_objects[objRank].bboxMin.x); - m_objects[objRank].bboxMin.y = Math::Min(buffer.vertices[i].coord.y, m_objects[objRank].bboxMin.y); - m_objects[objRank].bboxMin.z = Math::Min(buffer.vertices[i].coord.z, m_objects[objRank].bboxMin.z); - m_objects[objRank].bboxMax.x = Math::Max(buffer.vertices[i].coord.x, m_objects[objRank].bboxMax.x); - m_objects[objRank].bboxMax.y = Math::Max(buffer.vertices[i].coord.y, m_objects[objRank].bboxMax.y); - m_objects[objRank].bboxMax.z = Math::Max(buffer.vertices[i].coord.z, m_objects[objRank].bboxMax.z); + m_objects[objRank].bboxMin.x = Math::Min(p4.vertices[i].coord.x, m_objects[objRank].bboxMin.x); + m_objects[objRank].bboxMin.y = Math::Min(p4.vertices[i].coord.y, m_objects[objRank].bboxMin.y); + m_objects[objRank].bboxMin.z = Math::Min(p4.vertices[i].coord.z, m_objects[objRank].bboxMin.z); + m_objects[objRank].bboxMax.x = Math::Max(p4.vertices[i].coord.x, m_objects[objRank].bboxMax.x); + m_objects[objRank].bboxMax.y = Math::Max(p4.vertices[i].coord.y, m_objects[objRank].bboxMax.y); + m_objects[objRank].bboxMax.z = Math::Max(p4.vertices[i].coord.z, m_objects[objRank].bboxMax.z); } m_objects[objRank].radius = Math::Max(m_objects[objRank].bboxMin.Length(), m_objects[objRank].bboxMax.Length()); } - if (buffer.type == ENG_TRIANGLE_TYPE_TRIANGLES) - m_objects[objRank].totalTriangles += buffer.vertices.size() / 3; - else if (buffer.type == ENG_TRIANGLE_TYPE_SURFACE) - m_objects[objRank].totalTriangles += buffer.vertices.size() - 2; + if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) + m_objects[objRank].totalTriangles += p4.vertices.size() / 3; + else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE) + m_objects[objRank].totalTriangles += p4.vertices.size() - 2; return true; } @@ -1735,10 +1811,57 @@ void CEngine::UpdateGeometry() m_updateGeometry = false; } +void CEngine::UpdateStaticObjects() +{ + if (!m_updateStaticObjects) + return; + + for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) + { + EngineObjLevel1& p1 = m_objectTree[l1]; + if (! p1.used) continue; + + for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) + { + EngineObjLevel2& p2 = p1.next[l2]; + if (! p2.used) continue; + + int objRank = p2.objRank; + + if (!m_objects[objRank].staticBuffer) + continue; + + for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) + { + EngineObjLevel3& p3 = p2.next[l3]; + if (! p3.used) continue; + + for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) + { + EngineObjLevel4& p4 = p3.next[l4]; + if (! p4.used) continue; + + if (p4.staticBufferId != 0) + continue; + + PrimitiveType type; + if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) + type = PRIMITIVE_TRIANGLES; + else + type = PRIMITIVE_TRIANGLE_STRIP; + + p4.staticBufferId = m_device->CreateStaticObject(type, &p4.vertices[0], p4.vertices.size()); + } + } + } + } +} + void CEngine::Update() { ComputeDistance(); UpdateGeometry(); + UpdateStaticObjects(); } bool CEngine::DetectBBox(int objRank, Math::Point mouse) @@ -3106,20 +3229,7 @@ void CEngine::Draw3DScene() SetMaterial(p4.material); SetState(p4.state); - if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) - { - m_device->DrawPrimitive( PRIMITIVE_TRIANGLES, - &p4.vertices[0], - p4.vertices.size() ); - m_statisticTriangle += p4.vertices.size() / 3; - } - if (p4.type == ENG_TRIANGLE_TYPE_SURFACE) - { - m_device->DrawPrimitive( PRIMITIVE_TRIANGLE_STRIP, - &p4.vertices[0], - p4.vertices.size() ); - m_statisticTriangle += p4.vertices.size() - 2; - } + DrawObject(p4, m_objects[objRank].staticBuffer); } } } @@ -3188,22 +3298,7 @@ void CEngine::Draw3DScene() SetMaterial(p4.material); SetState(p4.state); - if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) - { - m_device->DrawPrimitive( PRIMITIVE_TRIANGLES, - &p4.vertices[0], - p4.vertices.size() ); - - m_statisticTriangle += p4.vertices.size() / 3; - } - else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE) - { - m_device->DrawPrimitive( PRIMITIVE_TRIANGLE_STRIP, - &p4.vertices[0], - p4.vertices.size() ); - - m_statisticTriangle += p4.vertices.size() - 2; - } + DrawObject(p4, m_objects[objRank].staticBuffer); } } } @@ -3264,21 +3359,7 @@ void CEngine::Draw3DScene() SetMaterial(p4.material); SetState(tState, tColor); - if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) - { - m_device->DrawPrimitive( PRIMITIVE_TRIANGLES, - &p4.vertices[0], - p4.vertices.size() ); - - m_statisticTriangle += p4.vertices.size() / 3; - } - else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE) - { - m_device->DrawPrimitive( PRIMITIVE_TRIANGLE_STRIP, - &p4.vertices[0], - p4.vertices.size() ); - m_statisticTriangle += p4.vertices.size() - 2; - } + DrawObject(p4, m_objects[objRank].staticBuffer); } } } @@ -3307,6 +3388,32 @@ void CEngine::Draw3DScene() if (! m_overFront) DrawOverColor(); // draws the foreground color } +void CEngine::DrawObject(const EngineObjLevel4& obj, bool staticBuffer) +{ + if (staticBuffer) + { + m_device->DrawStaticObject(obj.staticBufferId); + + if (obj.type == ENG_TRIANGLE_TYPE_TRIANGLES) + m_statisticTriangle += obj.vertices.size() / 3; + else + m_statisticTriangle += obj.vertices.size() - 2; + } + else + { + if (obj.type == ENG_TRIANGLE_TYPE_TRIANGLES) + { + m_device->DrawPrimitive(PRIMITIVE_TRIANGLES, &obj.vertices[0], obj.vertices.size()); + m_statisticTriangle += obj.vertices.size() / 3; + } + else + { + m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, &obj.vertices[0], obj.vertices.size() ); + m_statisticTriangle += obj.vertices.size() - 2; + } + } +} + void CEngine::DrawInterface() { m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, false); @@ -3397,21 +3504,7 @@ void CEngine::DrawInterface() SetMaterial(p4.material); SetState(p4.state); - if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) - { - m_device->DrawPrimitive( PRIMITIVE_TRIANGLES, - &p4.vertices[0], - p4.vertices.size() ); - - m_statisticTriangle += p4.vertices.size() / 3; - } - else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE) - { - m_device->DrawPrimitive( PRIMITIVE_TRIANGLE_STRIP, - &p4.vertices[0], - p4.vertices.size() ); - m_statisticTriangle += p4.vertices.size() - 2; - } + DrawObject(p4, m_objects[objRank].staticBuffer); } } } diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index d127e74..de57e4d 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -195,7 +195,9 @@ struct EngineObject //! Number of triangles int totalTriangles; //! Type of object - EngineObjectType type; + EngineObjectType type; + //! Whether the object is stored and rendered as static buffer + bool staticBuffer; //! Transformation matrix Math::Matrix transform; //! Distance to object from eye point @@ -225,6 +227,7 @@ struct EngineObject drawWorld = false; drawFront = false; totalTriangles = 0; + staticBuffer = false; type = ENG_OBJTYPE_NULL; transform.LoadIdentity(); bboxMax.LoadZero(); @@ -252,6 +255,7 @@ struct EngineObjLevel4 Material material; int state; std::vector vertices; + unsigned int staticBufferId; EngineObjLevel4(bool used = false, EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES, @@ -760,6 +764,12 @@ public: bool GetObjectTransform(int objRank, Math::Matrix& transform); //@} + //@{ + //! Management of object static drawing flag + void SetObjectStatic(int objRank, bool staticBuffer); + bool GetObjectStatic(int objRank); + //@} + //! Sets drawWorld for given object bool SetObjectDrawWorld(int objRank, bool draw); //! Sets drawFront for given object @@ -1151,6 +1161,8 @@ public: protected: //! Prepares the interface for 3D scene void Draw3DScene(); + //! Draw 3D object + void DrawObject(const EngineObjLevel4& obj, bool staticBuffer); //! Draws the user interface over the scene void DrawInterface(); @@ -1215,6 +1227,9 @@ protected: //! Updates geometric parameters of objects (bounding box and radius) void UpdateGeometry(); + //! Updates static buffers of changed objects + void UpdateStaticObjects(); + protected: CInstanceManager* m_iMan; CApplication* m_app; @@ -1293,6 +1308,7 @@ protected: Color m_waterAddColor; int m_statisticTriangle; bool m_updateGeometry; + bool m_updateStaticObjects; int m_alphaMode; bool m_groundSpotVisible; bool m_shadowVisible; diff --git a/src/graphics/engine/modelfile.cpp b/src/graphics/engine/modelfile.cpp index 3b0343a..a9972fe 100644 --- a/src/graphics/engine/modelfile.cpp +++ b/src/graphics/engine/modelfile.cpp @@ -1157,18 +1157,24 @@ bool CModelFile::WriteBinaryModel(std::ostream& stream) #ifndef MODELFILE_NO_ENGINE + +/** + * TODO: move the function to CEngine or new class (CModelManager?) + * and make models shared static objects. + */ + bool CModelFile::CreateEngineObject(int objRank) { std::vector vs(3, VertexTex2()); + m_engine->SetObjectStatic(objRank, true); // TODO: make optional in the future + float limit[2]; limit[0] = m_engine->GetLimitLOD(0); // frontier AB as config limit[1] = m_engine->GetLimitLOD(1); // frontier BC as config for (int i = 0; i < static_cast( m_triangles.size() ); i++) { - // TODO move this to CEngine - float min = m_triangles[i].min; float max = m_triangles[i].max; diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index 978471b..73c5cec 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -363,6 +363,7 @@ bool CPyro::Create(PyroType type, CObject* obj, float force) m_type == PT_EXPLOW ) { CreateTriangle(obj, oType, 0); + m_engine->SetObjectStatic(m_object->GetObjectRank(0), false); m_engine->DeleteShadow(m_object->GetObjectRank(0)); ExploStart(); } @@ -1397,6 +1398,8 @@ void CPyro::CreateTriangle(CObject* obj, ObjectType oType, int part) int objRank = obj->GetObjectRank(part); if (objRank == -1) return; + m_engine->SetObjectStatic(objRank, false); + float min = 0.0f; float max = m_engine->GetLimitLOD(0); int total = m_engine->GetObjectTotalTriangles(objRank); diff --git a/src/graphics/engine/terrain.cpp b/src/graphics/engine/terrain.cpp index 4c22a32..0e77ea2 100644 --- a/src/graphics/engine/terrain.cpp +++ b/src/graphics/engine/terrain.cpp @@ -478,6 +478,8 @@ VertexTex2 CTerrain::GetVertex(int x, int y, int step) v.texCoord.x = (o.x-oo.x)*m_textureScale*m_textureSubdivCount; v.texCoord.y = 1.0f - (o.z-oo.z)*m_textureScale*m_textureSubdivCount; + v.texCoord2 = v.texCoord; + return v; } @@ -1166,6 +1168,10 @@ bool CTerrain::CreateSquare(int x, int y) int objRank = m_engine->CreateObject(); m_engine->SetObjectType(objRank, ENG_OBJTYPE_TERRAIN); + // TODO: create a static object, but not split into squares, but a single object for all terrain + // Squares should be sub-objects accessing parts of triangle list + // m_engine->SetObjectStatic(objRank, true); + m_objRanks[x+y*m_mosaicCount] = objRank; float min = 0.0f; diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index a6ba1eb..2d284d0 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -73,6 +73,8 @@ CGLDevice::CGLDevice(const GLDeviceConfig &config) { m_config = config; m_lighting = false; + m_lastVboId = 0; + m_useVbo = false; } @@ -109,6 +111,16 @@ bool CGLDevice::Create() GetLogger()->Error("GLEW reports required extensions not supported\n"); return false; } + + if (GLEW_ARB_vertex_buffer_object) + { + GetLogger()->Info("Detected ARB_vertex_buffer_object extension - using VBOs\n"); + m_useVbo = true; + } + else + { + GetLogger()->Info("No ARB_vertex_buffer_object extension present - using display lists\n"); + } } #endif @@ -174,6 +186,16 @@ void CGLDevice::ConfigChanged(const GLDeviceConfig& newConfig) Create(); } +void CGLDevice::SetUseVbo(bool useVbo) +{ + m_useVbo = useVbo; +} + +bool CGLDevice::GetUseVbo() +{ + return m_useVbo; +} + void CGLDevice::BeginScene() { Clear(); @@ -927,6 +949,206 @@ void CGLDevice::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int glDisableClientState(GL_COLOR_ARRAY); } +unsigned int CGLDevice::CreateStaticObject(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +{ + unsigned int id = 0; + if (m_useVbo) + { + id = ++m_lastVboId; + + VboObjectInfo info; + info.primitiveType = primitiveType; + info.vertexType = VERTEX_TYPE_NORMAL; + info.vertexCount = vertexCount; + info.bufferId = 0; + + glGenBuffers(1, &info.bufferId); + glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); + glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + m_vboObjects[id] = info; + } + else + { + id = glGenLists(1); + + glNewList(id, GL_COMPILE); + + DrawPrimitive(primitiveType, vertices, vertexCount); + + glEndList(); + } + + return id; +} + +unsigned int CGLDevice::CreateStaticObject(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) +{ + unsigned int id = 0; + if (m_useVbo) + { + id = ++m_lastVboId; + + VboObjectInfo info; + info.primitiveType = primitiveType; + info.vertexType = VERTEX_TYPE_TEX2; + info.vertexCount = vertexCount; + info.bufferId = 0; + + glGenBuffers(1, &info.bufferId); + glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); + glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + m_vboObjects[id] = info; + } + else + { + id = glGenLists(1); + + glNewList(id, GL_COMPILE); + + DrawPrimitive(primitiveType, vertices, vertexCount); + + glEndList(); + } + + return id; +} + +unsigned int CGLDevice::CreateStaticObject(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) +{ + unsigned int id = 0; + if (m_useVbo) + { + id = ++m_lastVboId; + + VboObjectInfo info; + info.primitiveType = primitiveType; + info.vertexType = VERTEX_TYPE_COL; + info.vertexCount = vertexCount; + info.bufferId = 0; + + glGenBuffers(1, &info.bufferId); + glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); + glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + m_vboObjects[id] = info; + } + else + { + id = glGenLists(1); + + glNewList(id, GL_COMPILE); + + DrawPrimitive(primitiveType, vertices, vertexCount); + + glEndList(); + } + + return id; +} + +void CGLDevice::DrawStaticObject(unsigned int objectId) +{ + if (m_useVbo) + { + auto it = m_vboObjects.find(objectId); + if (it == m_vboObjects.end()) + return; + + glEnable(GL_VERTEX_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER, (*it).second.bufferId); + + if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) + { + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, normal)); + + glActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, texCoord)); + } + else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) + { + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, coord)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, normal)); + + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord)); + + glClientActiveTexture(GL_TEXTURE1); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord2)); + } + else if ((*it).second.vertexType == VERTEX_TYPE_COL) + { + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, coord)); + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_FLOAT, sizeof(VertexCol), static_cast(nullptr) + offsetof(VertexCol, color)); + } + + GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType); + glDrawArrays(GL_TRIANGLES, 0, (*it).second.vertexCount); + + if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) + { + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0 + } + else if ((*it).second.vertexType == VERTEX_TYPE_TEX2) + { + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + else if ((*it).second.vertexType == VERTEX_TYPE_COL) + { + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glDisable(GL_VERTEX_ARRAY); + } + else + { + glCallList(objectId); + } +} + +void CGLDevice::DestroyStaticObject(unsigned int objectId) +{ + if (m_useVbo) + { + auto it = m_vboObjects.find(objectId); + if (it == m_vboObjects.end()) + return; + + glDeleteBuffers(1, &(*it).second.bufferId); + + m_vboObjects.erase(it); + } + else + { + glDeleteLists(objectId, 1); + } +} + bool InPlane(Math::Vector normal, float originPlane, Math::Vector center, float radius) { float distance = originPlane + Math::DotProduct(normal, center); diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h index 87c1247..adae41b 100644 --- a/src/graphics/opengl/gldevice.h +++ b/src/graphics/opengl/gldevice.h @@ -27,6 +27,7 @@ #include #include #include +#include // Graphics module namespace @@ -84,6 +85,9 @@ public: void ConfigChanged(const GLDeviceConfig &newConfig); + void SetUseVbo(bool useVbo); + bool GetUseVbo(); + virtual void BeginScene(); virtual void EndScene(); @@ -119,14 +123,18 @@ public: virtual void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT); - //! Renders primitive composed of vertices with single texture virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)); - //! Renders primitive composed of vertices with multitexturing (2 textures) virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)); virtual void DrawPrimitive(PrimitiveType type, const VertexCol *vertices , int vertexCount); + virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount); + virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount); + virtual void DrawStaticObject(unsigned int objectId); + virtual void DestroyStaticObject(unsigned int objectId); + virtual int ComputeSphereVisibility(const Math::Vector ¢er, float radius); virtual void SetRenderState(RenderState state, bool enabled); @@ -200,6 +208,30 @@ private: //! Set of all created textures std::set m_allTextures; + + //! Type of vertex structure + enum VertexType + { + VERTEX_TYPE_NORMAL, + VERTEX_TYPE_TEX2, + VERTEX_TYPE_COL, + }; + + //! Info about static VBO buffers + struct VboObjectInfo + { + PrimitiveType primitiveType; + unsigned int bufferId; + VertexType vertexType; + int vertexCount; + }; + + //! Whether to use VBOs or display lists + bool m_useVbo; + //! Map of saved VBO objects + std::map m_vboObjects; + //! Last ID of VBO object + unsigned int m_lastVboId; }; -- cgit v1.2.3-1-g7c22 From 5574eccebd16ae38a2a21ed202d1f9d1ba8f67a4 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Wed, 26 Dec 2012 20:58:02 +0100 Subject: Engine optimization - rewritten model management - new class CModelManager - rewritten engine object structure in CEngine - created shared model data instead of separate objects per each model instance - minor refactoring --- src/graphics/core/device.h | 21 +- src/graphics/engine/engine.cpp | 1758 +++++++++++++-------------- src/graphics/engine/engine.h | 341 +++--- src/graphics/engine/modelfile.cpp | 136 +-- src/graphics/engine/modelfile.h | 27 +- src/graphics/engine/modelmanager.cpp | 213 ++++ src/graphics/engine/modelmanager.h | 97 ++ src/graphics/engine/pyro.cpp | 3 - src/graphics/engine/terrain.cpp | 29 +- src/graphics/engine/terrain.h | 2 +- src/graphics/engine/test/CMakeLists.txt | 1 - src/graphics/engine/test/modelfile_test.cpp | 12 +- src/graphics/opengl/gldevice.cpp | 99 +- src/graphics/opengl/gldevice.h | 13 +- 14 files changed, 1475 insertions(+), 1277 deletions(-) create mode 100644 src/graphics/engine/modelmanager.cpp create mode 100644 src/graphics/engine/modelmanager.h (limited to 'src/graphics') diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h index a0e44e4..618d21a 100644 --- a/src/graphics/core/device.h +++ b/src/graphics/core/device.h @@ -317,19 +317,28 @@ public: virtual void DrawPrimitive(PrimitiveType type, const VertexCol *vertices , int vertexCount) = 0; //! Creates a static buffer composed of given primitives with single texture vertices - virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) = 0; + virtual unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) = 0; - //! Creates a static buffer composed of given primitives with multitexturing (2 textures) - virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) = 0; + //! Creates a static buffer composed of given primitives with multitexturing + virtual unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) = 0; //! Creates a static buffer composed of given primitives with solid color - virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) = 0; + virtual unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) = 0; + + //! Updates the static buffer composed of given primitives with single texture vertices + virtual void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) = 0; + + //! Updates the static buffer composed of given primitives with multitexturing + virtual void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) = 0; + + //! Updates the static buffer composed of given primitives with solid color + virtual void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) = 0; //! Draws a static buffer - virtual void DrawStaticObject(unsigned int objectId) = 0; + virtual void DrawStaticBuffer(unsigned int bufferId) = 0; //! Deletes a static buffer - virtual void DestroyStaticObject(unsigned int objectId) = 0; + virtual void DestroyStaticBuffer(unsigned int bufferId) = 0; //! Tests whether a sphere is (partially) within the frustum volume //! Returns a mask of frustum planes for which the test is positive diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index de5f2d4..73cd73a 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -47,56 +47,6 @@ // Graphics module namespace namespace Gfx { - -// Initial size of various vectors -const int OBJECT_PREALLOCATE_COUNT = 1200; -const int SHADOW_PREALLOCATE_COUNT = 500; -const int GROUNDSPOT_PREALLOCATE_COUNT = 100; - -const int LEVEL1_PREALLOCATE_COUNT = 50; -const int LEVEL2_PREALLOCATE_COUNT = 100; -const int LEVEL3_PREALLOCATE_COUNT = 5; -const int LEVEL4_PREALLOCATE_COUNT = 100; -const int LEVEL4_VERTEX_PREALLOCATE_COUNT = 200; - - -EngineObjLevel1::EngineObjLevel1(bool used, const std::string& tex1Name, const std::string& tex2Name) -{ - this->used = used; - this->tex1Name = tex1Name; - this->tex2Name = tex2Name; - - next.reserve(LEVEL2_PREALLOCATE_COUNT); -} - -EngineObjLevel2::EngineObjLevel2(bool used, int objRank) -{ - this->used = used; - this->objRank = objRank; - - next.reserve(LEVEL3_PREALLOCATE_COUNT); -} - -EngineObjLevel3::EngineObjLevel3(bool used, float min, float max) -{ - this->used = used; - this->min = min; - this->max = max; - - next.reserve(LEVEL4_PREALLOCATE_COUNT); -} - -EngineObjLevel4::EngineObjLevel4(bool used, EngineTriangleType type, const Material& material, int state) -{ - this->used = used; - this->type = type; - this->material = material; - this->state = state; - this->staticBufferId = 0; - - vertices.reserve(LEVEL4_VERTEX_PREALLOCATE_COUNT); -} - CEngine::CEngine(CInstanceManager *iMan, CApplication *app) { m_iMan = iMan; @@ -183,7 +133,7 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_alphaMode = 1; m_updateGeometry = false; - m_updateStaticObjects = false; + m_updateStaticBuffers = false; m_interfaceMode = false; @@ -220,11 +170,6 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_terrainTexParams.mipmap = false; m_terrainTexParams.minFilter = TEX_MIN_FILTER_LINEAR; m_terrainTexParams.magFilter = TEX_MAG_FILTER_LINEAR; - - m_objectTree.reserve(LEVEL1_PREALLOCATE_COUNT); - m_objects.reserve(OBJECT_PREALLOCATE_COUNT); - m_shadows.reserve(SHADOW_PREALLOCATE_COUNT); - m_groundSpots.reserve(GROUNDSPOT_PREALLOCATE_COUNT); } CEngine::~CEngine() @@ -387,7 +332,7 @@ void CEngine::FrameUpdate() ComputeDistance(); UpdateGeometry(); - UpdateStaticObjects(); + UpdateStaticBuffers(); m_highlightTime = m_app->GetAbsTime(); @@ -495,7 +440,7 @@ Math::Point CEngine::WindowToInterfaceSize(Math::IntPoint size) Math::IntPoint CEngine::InterfaceToWindowSize(Math::Point size) { return Math::IntPoint(static_cast(size.x * m_size.x), - static_cast(size.y * m_size.y)); + static_cast(size.y * m_size.y)); } void CEngine::AddStatisticTriangle(int count) @@ -514,263 +459,40 @@ int CEngine::GetStatisticTriangle() Object management *******************************************************/ - - -int CEngine::CreateObject() -{ - int i = 0; - for ( ; i < static_cast( m_objects.size() ); i++) - { - if (! m_objects[i].used) - { - m_objects[i].LoadDefault(); - break; - } - } - - if (i == static_cast( m_objects.size() )) - m_objects.push_back(EngineObject()); - - - m_objects[i].used = true; - - Math::Matrix mat; - mat.LoadIdentity(); - SetObjectTransform(i, mat); - - m_objects[i].drawWorld = true; - m_objects[i].distance = 0.0f; - m_objects[i].bboxMin = Math::Vector(0.0f, 0.0f, 0.0f); - m_objects[i].bboxMax = Math::Vector(0.0f, 0.0f, 0.0f); - m_objects[i].shadowRank = -1; - - return i; -} - -void CEngine::FlushObject() -{ - m_objectTree.clear(); - m_objects.clear(); - - m_shadows.clear(); - - FlushGroundSpot(); -} - -bool CEngine::DeleteObject(int objRank) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; - - // Delete object's triangles - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) - { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; - - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) - { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; - - if (p2.objRank != objRank) continue; - - if (m_objects[objRank].staticBuffer) - { - for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) - { - EngineObjLevel3& p3 = p2.next[l3]; - if (! p3.used) continue; - - for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) - { - EngineObjLevel4& p4 = p3.next[l4]; - - m_device->DestroyStaticObject(p4.staticBufferId); - } - } - } - - - p2.used = false; - p2.next.clear(); - } - } - - // Mark object as deleted - m_objects[objRank].used = false; - - // Delete associated shadows - DeleteShadow(objRank); - - return true; -} - -bool CEngine::SetObjectType(int objRank, EngineObjectType type) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; - - m_objects[objRank].type = type; - return true; -} - -EngineObjectType CEngine::GetObjectType(int objRank) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return ENG_OBJTYPE_NULL; - - return m_objects[objRank].type; -} - - -bool CEngine::SetObjectTransform(int objRank, const Math::Matrix& transform) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; - - m_objects[objRank].transform = transform; - return true; -} - -bool CEngine::GetObjectTransform(int objRank, Math::Matrix& transform) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; - - transform = m_objects[objRank].transform; - return true; -} - -void CEngine::SetObjectStatic(int objRank, bool staticBuffer) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return; - - m_objects[objRank].staticBuffer = staticBuffer; -} - -bool CEngine::GetObjectStatic(int objRank) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; - - return m_objects[objRank].staticBuffer; -} - -bool CEngine::SetObjectDrawWorld(int objRank, bool draw) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; - - m_objects[objRank].drawWorld = draw; - return true; -} - -bool CEngine::SetObjectDrawFront(int objRank, bool draw) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; - - m_objects[objRank].drawFront = draw; - return true; -} - -bool CEngine::SetObjectTransparency(int objRank, float value) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; - - m_objects[objRank].transparency = value; - return true; -} - -bool CEngine::GetObjectBBox(int objRank, Math::Vector& min, Math::Vector& max) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return 0; - - min = m_objects[objRank].bboxMin; - max = m_objects[objRank].bboxMax; - return true; -} - - -int CEngine::GetObjectTotalTriangles(int objRank) -{ - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return 0; - - return m_objects[objRank].totalTriangles; -} - - -EngineObjLevel1& CEngine::AddLevel1(const std::string& tex1Name, const std::string& tex2Name) -{ - bool unusedPresent = false; - for (int i = 0; i < static_cast( m_objectTree.size() ); i++) - { - if (! m_objectTree[i].used) - { - unusedPresent = true; - continue; - } - - if (m_objectTree[i].tex1Name == tex1Name && m_objectTree[i].tex2Name == tex2Name) - return m_objectTree[i]; - } - - if (unusedPresent) - { - for (int i = 0; i < static_cast( m_objectTree.size() ); i++) - { - if (! m_objectTree[i].used) - { - m_objectTree[i].used = true; - m_objectTree[i].tex1Name = tex1Name; - m_objectTree[i].tex2Name = tex2Name; - return m_objectTree[i]; - } - } - } - - m_objectTree.push_back(EngineObjLevel1(true, tex1Name, tex2Name)); - return m_objectTree.back(); -} - -EngineObjLevel2& CEngine::AddLevel2(EngineObjLevel1& p1, int objRank) +EngineBaseObjTexTier& CEngine::AddLevel2(int baseObjRank, const std::string& tex1Name, const std::string& tex2Name) { bool unusedPresent = false; - for (int i = 0; i < static_cast( p1.next.size() ); i++) + for (int i = 0; i < static_cast( m_baseObjects[baseObjRank].next.size() ); i++) { - if (! p1.next[i].used) + if (! m_baseObjects[baseObjRank].next[i].used) { unusedPresent = true; continue; } - if (p1.next[i].objRank == objRank) - return p1.next[i]; + 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( p1.next.size() ); i++) + for (int i = 0; i < static_cast( m_baseObjects[baseObjRank].next.size() ); i++) { - if (! p1.next[i].used) + if (! m_baseObjects[baseObjRank].next[i].used) { - p1.next[i].used = true; - p1.next[i].objRank = objRank; - return p1.next[i]; + 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]; } } } - p1.next.push_back(EngineObjLevel2(true, objRank)); - return p1.next.back(); + m_baseObjects[baseObjRank].next.push_back(EngineBaseObjTexTier(true, tex1Name, tex2Name)); + return m_baseObjects[baseObjRank].next.back(); } -EngineObjLevel3& CEngine::AddLevel3(EngineObjLevel2& p2, float min, float max) +EngineBaseObjLODTier& CEngine::AddLevel3(EngineBaseObjTexTier& p2, float min, float max) { bool unusedPresent = false; for (int i = 0; i < static_cast( p2.next.size() ); i++) @@ -799,12 +521,12 @@ EngineObjLevel3& CEngine::AddLevel3(EngineObjLevel2& p2, float min, float max) } } - p2.next.push_back(EngineObjLevel3(true, min, max)); + p2.next.push_back(EngineBaseObjLODTier(true, min, max)); return p2.next.back(); } -EngineObjLevel4& CEngine::AddLevel4(EngineObjLevel3& p3, EngineTriangleType type, - const Material& material, int state) +EngineBaseObjDataTier& CEngine::AddLevel4(EngineBaseObjLODTier& p3, EngineTriangleType type, + const Material& material, int state) { bool unusedPresent = false; for (int i = 0; i < static_cast( p3.next.size() ); i++) @@ -834,100 +556,96 @@ EngineObjLevel4& CEngine::AddLevel4(EngineObjLevel3& p3, EngineTriangleType type } } - p3.next.push_back(EngineObjLevel4(true, type, material, state)); + p3.next.push_back(EngineBaseObjDataTier(true, type, material, state)); return p3.next.back(); } -bool CEngine::AddTriangles(int objRank, const std::vector& vertices, - const Material& material, int state, - std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate) +int CEngine::CreateBaseObject() { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) + int i = 0; + for ( ; i < static_cast( m_baseObjects.size() ); i++) { - GetLogger()->Error("AddTriangle(): invalid object rank %d\n", objRank); - return false; + if (! m_baseObjects[i].used) + { + m_baseObjects[i].LoadDefault(); + break; + } } - m_lastSize = m_size; - m_lastObjectDetail = m_objectDetail; - m_lastClippingDistance = m_clippingDistance; + if (i == static_cast( m_baseObjects.size() )) + m_baseObjects.push_back(EngineBaseObject()); + else + m_baseObjects[i].LoadDefault(); - EngineObjLevel1& p1 = AddLevel1(tex1Name, tex2Name); - EngineObjLevel2& p2 = AddLevel2(p1, objRank); - EngineObjLevel3& p3 = AddLevel3(p2, min, max); - EngineObjLevel4& p4 = AddLevel4(p3, ENG_TRIANGLE_TYPE_TRIANGLES, material, state); - p4.vertices.insert(p4.vertices.end(), vertices.begin(), vertices.end()); + m_baseObjects[i].used = true; - if (m_objects[objRank].staticBuffer) - { - if (p4.staticBufferId != 0) - { - m_device->DestroyStaticObject(p4.staticBufferId); - p4.staticBufferId = 0; - } + return i; +} - m_updateStaticObjects = true; - } +void CEngine::DeleteBaseObject(int baseObjRank) +{ + assert(baseObjRank < -1 || baseObjRank >= static_cast( m_baseObjects.size() )); - if (globalUpdate) - { - m_updateGeometry = true; - } - else + for (int l2 = 0; l2 < static_cast( m_baseObjects[baseObjRank].next.size() ); l2++) { - for (int i = 0; i < static_cast( vertices.size() ); i++) + EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2]; + if (! p2.used) + continue; + + for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { - m_objects[objRank].bboxMin.x = Math::Min(vertices[i].coord.x, m_objects[objRank].bboxMin.x); - m_objects[objRank].bboxMin.y = Math::Min(vertices[i].coord.y, m_objects[objRank].bboxMin.y); - m_objects[objRank].bboxMin.z = Math::Min(vertices[i].coord.z, m_objects[objRank].bboxMin.z); - m_objects[objRank].bboxMax.x = Math::Max(vertices[i].coord.x, m_objects[objRank].bboxMax.x); - m_objects[objRank].bboxMax.y = Math::Max(vertices[i].coord.y, m_objects[objRank].bboxMax.y); - m_objects[objRank].bboxMax.z = Math::Max(vertices[i].coord.z, m_objects[objRank].bboxMax.z); + EngineBaseObjLODTier& p3 = p2.next[l3]; + if (! p3.used) + continue; + + for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) + { + EngineBaseObjDataTier& p4 = p3.next[l4]; + + m_device->DestroyStaticBuffer(p4.staticBufferId); + p4.staticBufferId = 0; + } } - m_objects[objRank].radius = Math::Max(m_objects[objRank].bboxMin.Length(), - m_objects[objRank].bboxMax.Length()); + p2.used = false; + p2.next.clear(); } +} + +void CEngine::DeleteAllBaseObjects() +{ + m_baseObjects.clear(); +} - m_objects[objRank].totalTriangles += vertices.size() / 3; +void CEngine::CopyBaseObject(int sourceBaseObjRank, int destBaseObjRank) +{ + assert(sourceBaseObjRank >= 0 && sourceBaseObjRank < static_cast( m_baseObjects.size() )); + assert(destBaseObjRank >= 0 && destBaseObjRank < static_cast( m_baseObjects.size() )); - return true; + m_baseObjects[destBaseObjRank] = m_baseObjects[sourceBaseObjRank]; } -bool CEngine::AddSurface(int objRank, const std::vector& vertices, - const Material& material, int state, - std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate) +void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector& vertices, + EngineTriangleType triangleType, + const Material& material, int state, + std::string tex1Name, std::string tex2Name, + float min, float max, bool globalUpdate) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - { - GetLogger()->Error("AddSurface(): invalid object rank %d\n", objRank); - return false; - } + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); m_lastSize = m_size; m_lastObjectDetail = m_objectDetail; m_lastClippingDistance = m_clippingDistance; - EngineObjLevel1& p1 = AddLevel1(tex1Name, tex2Name); - EngineObjLevel2& p2 = AddLevel2(p1, objRank); - EngineObjLevel3& p3 = AddLevel3(p2, min, max); - EngineObjLevel4& p4 = AddLevel4(p3, ENG_TRIANGLE_TYPE_SURFACE, material, state); + EngineBaseObjTexTier& p2 = AddLevel2(baseObjRank, tex1Name, tex2Name); + EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max); + EngineBaseObjDataTier& p4 = AddLevel4(p3, triangleType, material, state); p4.vertices.insert(p4.vertices.end(), vertices.begin(), vertices.end()); - if (m_objects[objRank].staticBuffer) - { - if (p4.staticBufferId != 0) - { - m_device->DestroyStaticObject(p4.staticBufferId); - p4.staticBufferId = 0; - } - - m_updateStaticObjects = true; - } + p4.updateStaticBuffer = true; + m_updateStaticBuffers = true; if (globalUpdate) { @@ -937,58 +655,41 @@ bool CEngine::AddSurface(int objRank, const std::vector& vertices, { for (int i = 0; i < static_cast( vertices.size() ); i++) { - m_objects[objRank].bboxMin.x = Math::Min(vertices[i].coord.x, m_objects[objRank].bboxMin.x); - m_objects[objRank].bboxMin.y = Math::Min(vertices[i].coord.y, m_objects[objRank].bboxMin.y); - m_objects[objRank].bboxMin.z = Math::Min(vertices[i].coord.z, m_objects[objRank].bboxMin.z); - m_objects[objRank].bboxMax.x = Math::Max(vertices[i].coord.x, m_objects[objRank].bboxMax.x); - m_objects[objRank].bboxMax.y = Math::Max(vertices[i].coord.y, m_objects[objRank].bboxMax.y); - m_objects[objRank].bboxMax.z = Math::Max(vertices[i].coord.z, m_objects[objRank].bboxMax.z); + 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); } - m_objects[objRank].radius = Math::Max(m_objects[objRank].bboxMin.Length(), - m_objects[objRank].bboxMax.Length()); + m_baseObjects[baseObjRank].radius = Math::Max(m_baseObjects[baseObjRank].bboxMin.Length(), + m_baseObjects[baseObjRank].bboxMax.Length()); } - m_objects[objRank].totalTriangles += vertices.size() - 2; - - return true; + if (triangleType == ENG_TRIANGLE_TYPE_TRIANGLES) + m_baseObjects[baseObjRank].totalTriangles += vertices.size() / 3; + else + m_baseObjects[baseObjRank].totalTriangles += vertices.size() - 2; } -bool CEngine::AddQuick(int objRank, const EngineObjLevel4& buffer, - std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate) +void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer, + std::string tex1Name, std::string tex2Name, + float min, float max, bool globalUpdate) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - { - GetLogger()->Error("AddQuick(): invalid object rank %d\n", objRank); - return false; - } + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); - EngineObjLevel1& p1 = AddLevel1(tex1Name, tex2Name); - EngineObjLevel2& p2 = AddLevel2(p1, objRank); - EngineObjLevel3& p3 = AddLevel3(p2, min, max); + EngineBaseObjTexTier& p2 = AddLevel2(baseObjRank, tex1Name, tex2Name); + EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max); p3.next.push_back(buffer); - EngineObjLevel4& p4 = p3.next.back(); - p4.used = true; // ensure that it is used - - if (m_objects[objRank].staticBuffer) - { - if (p4.staticBufferId != 0) - { - m_device->DestroyStaticObject(p4.staticBufferId); - p4.staticBufferId = 0; - } + EngineBaseObjDataTier& p4 = p3.next.back(); - PrimitiveType type; - if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) - type = PRIMITIVE_TRIANGLES; - else - type = PRIMITIVE_TRIANGLE_STRIP; + p4.used = true; - p4.staticBufferId = m_device->CreateStaticObject(type, &p4.vertices[0], p4.vertices.size()); - } + p4.updateStaticBuffer = true; + m_updateStaticBuffers = true; if (globalUpdate) { @@ -998,68 +699,197 @@ bool CEngine::AddQuick(int objRank, const EngineObjLevel4& buffer, { for (int i = 0; i < static_cast( p4.vertices.size() ); i++) { - m_objects[objRank].bboxMin.x = Math::Min(p4.vertices[i].coord.x, m_objects[objRank].bboxMin.x); - m_objects[objRank].bboxMin.y = Math::Min(p4.vertices[i].coord.y, m_objects[objRank].bboxMin.y); - m_objects[objRank].bboxMin.z = Math::Min(p4.vertices[i].coord.z, m_objects[objRank].bboxMin.z); - m_objects[objRank].bboxMax.x = Math::Max(p4.vertices[i].coord.x, m_objects[objRank].bboxMax.x); - m_objects[objRank].bboxMax.y = Math::Max(p4.vertices[i].coord.y, m_objects[objRank].bboxMax.y); - m_objects[objRank].bboxMax.z = Math::Max(p4.vertices[i].coord.z, m_objects[objRank].bboxMax.z); + 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); } - m_objects[objRank].radius = Math::Max(m_objects[objRank].bboxMin.Length(), - m_objects[objRank].bboxMax.Length()); + m_baseObjects[baseObjRank].radius = Math::Max(m_baseObjects[baseObjRank].bboxMin.Length(), + m_baseObjects[baseObjRank].bboxMax.Length()); } if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) - m_objects[objRank].totalTriangles += p4.vertices.size() / 3; + m_baseObjects[baseObjRank].totalTriangles += p4.vertices.size() / 3; else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE) - m_objects[objRank].totalTriangles += p4.vertices.size() - 2; - - return true; + m_baseObjects[baseObjRank].totalTriangles += p4.vertices.size() - 2; } -EngineObjLevel4* CEngine::FindTriangles(int objRank, const Material& material, - int state, std::string tex1Name, - std::string tex2Name, float min, float max) + +int CEngine::CreateObject() { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) + int i = 0; + for ( ; i < static_cast( m_objects.size() ); i++) { - GetLogger()->Error("FindTriangles(): invalid object rank %d\n", objRank); - return nullptr; + if (! m_objects[i].used) + { + m_objects[i].LoadDefault(); + break; + } } - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) + if (i == static_cast( m_objects.size() )) + m_objects.push_back(EngineObject()); + + + m_objects[i].used = true; + + Math::Matrix mat; + mat.LoadIdentity(); + SetObjectTransform(i, mat); + + m_objects[i].drawWorld = true; + m_objects[i].distance = 0.0f; + m_objects[i].shadowRank = -1; + + return i; +} + +void CEngine::DeleteAllObjects() +{ + m_objects.clear(); + m_shadows.clear(); + + DeleteAllGroundSpots(); +} + +void CEngine::DeleteObject(int objRank) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + // Mark object as deleted + m_objects[objRank].used = false; + + // Delete associated shadows + DeleteShadow(objRank); +} + +void CEngine::SetObjectBaseRank(int objRank, int baseObjRank) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + m_objects[objRank].baseObjRank = baseObjRank; +} + +int CEngine::GetObjectBaseRank(int objRank) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + return m_objects[objRank].baseObjRank; +} + +void CEngine::SetObjectType(int objRank, EngineObjectType type) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + m_objects[objRank].type = type; +} + +EngineObjectType CEngine::GetObjectType(int objRank) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + return m_objects[objRank].type; +} + + +void CEngine::SetObjectTransform(int objRank, const Math::Matrix& transform) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + m_objects[objRank].transform = transform; +} + +void CEngine::GetObjectTransform(int objRank, Math::Matrix& transform) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + transform = m_objects[objRank].transform; +} + +void CEngine::SetObjectDrawWorld(int objRank, bool draw) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + m_objects[objRank].drawWorld = draw; +} + +void CEngine::SetObjectDrawFront(int objRank, bool draw) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + m_objects[objRank].drawFront = draw; +} + +void CEngine::SetObjectTransparency(int objRank, float value) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + m_objects[objRank].transparency = value; +} + +void CEngine::GetObjectBBox(int objRank, Math::Vector& min, Math::Vector& max) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast(m_baseObjects.size())); + + min = m_baseObjects[baseObjRank].bboxMin; + max = m_baseObjects[baseObjRank].bboxMax; +} + + +int CEngine::GetObjectTotalTriangles(int objRank) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); + + return m_baseObjects[baseObjRank].totalTriangles; +} + +EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& material, + int state, std::string tex1Name, + std::string tex2Name, float min, float max) +{ + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); + + for (int l2 = 0; l2 < static_cast( m_baseObjects[baseObjRank].next.size() ); l2++) { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; + EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2]; + if (! p2.used) + continue; - if (p1.tex1Name != tex1Name) continue; + if (p2.tex1Name != tex1Name) + continue; - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) + for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; + EngineBaseObjLODTier& p3 = p2.next[l3]; + if (! p3.used) + continue; - if (p2.objRank != objRank) continue; + if (p3.min != min || p3.max != max) + continue; - for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) + for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { - EngineObjLevel3& p3 = p2.next[l3]; - if (! p3.used) continue; - - if (p3.min != min || p3.max != max) continue; - - for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) - { - EngineObjLevel4& p4 = p3.next[l4]; - if (! p4.used) continue; + EngineBaseObjDataTier& p4 = p3.next[l4]; + if (! p4.used) + continue; - if ( (p4.state & (~(ENG_RSTATE_DUAL_BLACK|ENG_RSTATE_DUAL_WHITE))) != state || - p4.material != material ) - continue; + if ( (p4.state & (~(ENG_RSTATE_DUAL_BLACK|ENG_RSTATE_DUAL_WHITE))) != state || + p4.material != material ) + continue; - return &p4; - } + return &p4; } } } @@ -1068,91 +898,86 @@ EngineObjLevel4* CEngine::FindTriangles(int objRank, const Material& material, } int CEngine::GetPartialTriangles(int objRank, float min, float max, float percent, int maxCount, - std::vector& triangles) + std::vector& triangles) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - { - GetLogger()->Error("GetPartialTriangles(): invalid object rank %d\n", objRank); - return 0; - } + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - int total = m_objects[objRank].totalTriangles; + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); + + int total = m_baseObjects[baseObjRank].totalTriangles; int expectedCount = static_cast(percent * total); triangles.reserve(Math::Min(maxCount, expectedCount)); int actualCount = 0; - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) + for (int l2 = 0; l2 < static_cast( m_baseObjects[baseObjRank].next.size() ); l2++) { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; + EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2]; + if (! p2.used) + continue; - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) + for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; + EngineBaseObjLODTier& p3 = p2.next[l3]; + if (! p3.used) + continue; - if (p2.objRank != objRank) continue; + if (p3.min != min || p3.max != max) + continue; - for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) + for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { - EngineObjLevel3& p3 = p2.next[l3]; - if (! p3.used) continue; - - if (p3.min != min || p3.max != max) continue; + EngineBaseObjDataTier& p4 = p3.next[l4]; + if (! p4.used) + continue; - for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) + if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) { - EngineObjLevel4& p4 = p3.next[l4]; - if (! p4.used) continue; - - if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) + for (int i = 0; i < static_cast( p4.vertices.size() ); i += 3) { - for (int i = 0; i < static_cast( p4.vertices.size() ); i += 3) - { - if (static_cast(actualCount) / total >= percent) - break; + if (static_cast(actualCount) / total >= percent) + break; - if (actualCount >= maxCount) - break; + if (actualCount >= maxCount) + break; - EngineTriangle t; - t.triangle[0] = p4.vertices[i]; - t.triangle[1] = p4.vertices[i+1]; - t.triangle[2] = p4.vertices[i+2]; - t.material = p4.material; - t.state = p4.state; - t.tex1Name = p1.tex1Name; - t.tex2Name = p1.tex2Name; + EngineTriangle t; + t.triangle[0] = p4.vertices[i]; + t.triangle[1] = p4.vertices[i+1]; + t.triangle[2] = p4.vertices[i+2]; + t.material = p4.material; + t.state = p4.state; + t.tex1Name = p2.tex1Name; + t.tex2Name = p2.tex2Name; - triangles.push_back(t); + triangles.push_back(t); - ++actualCount; - } + ++actualCount; } - else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE) + } + else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE) + { + for (int i = 0; i < static_cast( p4.vertices.size() ); i += 1) { - for (int i = 0; i < static_cast( p4.vertices.size() ); i += 1) - { - if (static_cast(actualCount) / total >= percent) - break; + if (static_cast(actualCount) / total >= percent) + break; - if (actualCount >= maxCount) - break; + if (actualCount >= maxCount) + break; - EngineTriangle t; - t.triangle[0] = p4.vertices[i]; - t.triangle[1] = p4.vertices[i+1]; - t.triangle[2] = p4.vertices[i+2]; - t.material = p4.material; - t.state = p4.state; - t.tex1Name = p1.tex1Name; - t.tex2Name = p1.tex2Name; + EngineTriangle t; + t.triangle[0] = p4.vertices[i]; + t.triangle[1] = p4.vertices[i+1]; + t.triangle[2] = p4.vertices[i+2]; + t.material = p4.material; + t.state = p4.state; + t.tex1Name = p2.tex1Name; + t.tex2Name = p2.tex2Name; - triangles.push_back(t); + triangles.push_back(t); - ++actualCount; - } + ++actualCount; } } } @@ -1179,20 +1004,22 @@ void CEngine::ChangeLOD() float oldTerrain = m_terrainVision * m_lastClippingDistance; float newTerrain = m_terrainVision * m_clippingDistance; - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) + for (int baseObjRank = 0; baseObjRank < static_cast( m_baseObjects.size() ); baseObjRank++) { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; + if (! m_baseObjects[baseObjRank].used) + continue; - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) + for (int l2 = 0; l2 < static_cast( m_baseObjects[baseObjRank].next.size() ); l2++) { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; + EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2]; + if (! p2.used) + continue; for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { - EngineObjLevel3& p3 = p2.next[l3]; - if (! p3.used) continue; + EngineBaseObjLODTier& p3 = p2.next[l3]; + if (! p3.used) + continue; if ( Math::IsEqual(p3.min, 0.0f ) && Math::IsEqual(p3.max, oldLimit[0]) ) @@ -1224,43 +1051,40 @@ void CEngine::ChangeLOD() m_lastClippingDistance = m_clippingDistance; } -bool CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name) +void CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name) { - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) - { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; - - if (p1.tex2Name == tex2Name) continue; // already new - - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) - { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; - - if (p2.objRank != objRank) continue; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - EngineObjLevel1& newP1 = AddLevel1(p1.tex1Name, tex2Name); + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); + + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; - newP1.next.push_back(EngineObjLevel2(true, objRank)); + for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) + { + EngineBaseObjTexTier& p2 = p1.next[l2]; + if (! p2.used) + continue; - EngineObjLevel2& newP2 = newP1.next.back(); - newP2.next.swap(p2.next); + if (p2.tex2Name == tex2Name) + continue; // already new - p2.used = false; - } + EngineBaseObjTexTier& newP2 = AddLevel2(baseObjRank, p2.tex1Name, tex2Name); + newP2.next.swap(p2.next); + p2.used = false; } - return true; } -bool CEngine::ChangeTextureMapping(int objRank, const Material& mat, int state, - const std::string& tex1Name, const std::string& tex2Name, - float min, float max, EngineTextureMapping mode, - float au, float bu, float av, float bv) +void CEngine::ChangeTextureMapping(int objRank, const Material& mat, int state, + const std::string& tex1Name, const std::string& tex2Name, + float min, float max, EngineTextureMapping mode, + float au, float bu, float av, float bv) { - EngineObjLevel4* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, min, max); + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, min, max); if (p4 == nullptr) - return false; + return; int nb = p4->vertices.size(); @@ -1310,21 +1134,25 @@ bool CEngine::ChangeTextureMapping(int objRank, const Material& mat, int state, } } - return true; + UpdateStaticBuffer(*p4); } -bool CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, +void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, const std::string& tex1Name, const std::string& tex2Name, float min, float max, EngineTextureMapping mode, float pos, float factor, float tl, float ts, float tt) { - EngineObjLevel4* triangles = FindTriangles(objRank, mat, state, tex1Name, tex2Name, min, max); - if (triangles == nullptr) return false; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + + EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, min, max); + if (p4 == nullptr) + return; - int tNum = triangles->vertices.size(); - if (tNum < 12 || tNum % 6 != 0) return false; + int tNum = p4->vertices.size(); + if (tNum < 12 || tNum % 6 != 0) + return; - std::vector& vs = triangles->vertices; + std::vector& vs = p4->vertices; while (pos < 0.0f) pos += 1.0f; // never negative! @@ -1402,17 +1230,17 @@ bool CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, tBase += 6; } - return true; + UpdateStaticBuffer(*p4); } -bool CEngine::CreateShadow(int objRank) +void CEngine::CreateShadow(int objRank) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); // Already allocated? - if (m_objects[objRank].shadowRank != -1) return true; + if (m_objects[objRank].shadowRank != -1) + return; int index = 0; for ( ; index < static_cast( m_shadows.size() ); index++) @@ -1424,146 +1252,147 @@ bool CEngine::CreateShadow(int objRank) } } - m_shadows.push_back(EngineShadow()); + if (index == static_cast( m_shadows.size() )) + m_shadows.push_back(EngineShadow()); m_shadows[index].used = true; m_shadows[index].objRank = objRank; m_shadows[index].height = 0.0f; m_objects[objRank].shadowRank = index; - - return true; } void CEngine::DeleteShadow(int objRank) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - int i = m_objects[objRank].shadowRank; - if (i == -1) + int shadowRank = m_objects[objRank].shadowRank; + if (shadowRank == -1) return; - m_shadows[i].used = false; - m_shadows[i].objRank = -1; + assert(shadowRank >= 0 && shadowRank < static_cast( m_shadows.size() )); + + m_shadows[shadowRank].used = false; + m_shadows[shadowRank].objRank = -1; m_objects[objRank].shadowRank = -1; } -bool CEngine::SetObjectShadowHide(int objRank, bool hide) +void CEngine::SetObjectShadowHide(int objRank, bool hide) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - int i = m_objects[objRank].shadowRank; - if (i == -1) - return false; + int shadowRank = m_objects[objRank].shadowRank; + if (shadowRank == -1) + return; - m_shadows[i].hide = hide; - return true; + assert(shadowRank >= 0 && shadowRank < static_cast( m_shadows.size() )); + + m_shadows[shadowRank].hide = hide; } -bool CEngine::SetObjectShadowType(int objRank, EngineShadowType type) +void CEngine::SetObjectShadowType(int objRank, EngineShadowType type) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - int i = m_objects[objRank].shadowRank; - if (i == -1) - return false; + int shadowRank = m_objects[objRank].shadowRank; + if (shadowRank == -1) + return; - m_shadows[i].type = type; - return true; + assert(shadowRank >= 0 && shadowRank < static_cast( m_shadows.size() )); + + m_shadows[shadowRank].type = type; } -bool CEngine::SetObjectShadowPos(int objRank, const Math::Vector& pos) +void CEngine::SetObjectShadowPos(int objRank, const Math::Vector& pos) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - int i = m_objects[objRank].shadowRank; - if (i == -1) - return false; + int shadowRank = m_objects[objRank].shadowRank; + if (shadowRank == -1) + return; - m_shadows[i].pos = pos; - return true; + assert(shadowRank >= 0 && shadowRank < static_cast( m_shadows.size() )); + + m_shadows[shadowRank].pos = pos; } -bool CEngine::SetObjectShadowNormal(int objRank, const Math::Vector& normal) +void CEngine::SetObjectShadowNormal(int objRank, const Math::Vector& normal) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - int i = m_objects[objRank].shadowRank; - if (i == -1) - return false; + int shadowRank = m_objects[objRank].shadowRank; + if (shadowRank == -1) + return; - m_shadows[i].normal = normal; - return true; + assert(shadowRank >= 0 && shadowRank < static_cast( m_shadows.size() )); + + m_shadows[shadowRank].normal = normal; } -bool CEngine::SetObjectShadowAngle(int objRank, float angle) +void CEngine::SetObjectShadowAngle(int objRank, float angle) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - int i = m_objects[objRank].shadowRank; - if (i == -1) - return false; + int shadowRank = m_objects[objRank].shadowRank; + if (shadowRank == -1) + return; - m_shadows[i].angle = angle; - return true; + assert(shadowRank >= 0 && shadowRank < static_cast( m_shadows.size() )); + + m_shadows[shadowRank].angle = angle; } -bool CEngine::SetObjectShadowRadius(int objRank, float radius) +void CEngine::SetObjectShadowRadius(int objRank, float radius) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - int i = m_objects[objRank].shadowRank; - if (i == -1) - return false; + int shadowRank = m_objects[objRank].shadowRank; + if (shadowRank == -1) + return; - m_shadows[i].radius = radius; - return true; + assert(shadowRank >= 0 && shadowRank < static_cast( m_shadows.size() )); + + m_shadows[shadowRank].radius = radius; } -bool CEngine::SetObjectShadowIntensity(int objRank, float intensity) +void CEngine::SetObjectShadowIntensity(int objRank, float intensity) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - int i = m_objects[objRank].shadowRank; - if (i == -1) - return false; + int shadowRank = m_objects[objRank].shadowRank; + if (shadowRank == -1) + return; - m_shadows[i].intensity = intensity; - return true; + assert(shadowRank >= 0 && shadowRank < static_cast( m_shadows.size() )); + + m_shadows[shadowRank].intensity = intensity; } -bool CEngine::SetObjectShadowHeight(int objRank, float height) +void CEngine::SetObjectShadowHeight(int objRank, float height) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return false; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - int i = m_objects[objRank].shadowRank; - if (i == -1) - return false; + int shadowRank = m_objects[objRank].shadowRank; + if (shadowRank == -1) + return; - m_shadows[i].height = height; - return true; + assert(shadowRank >= 0 && shadowRank < static_cast( m_shadows.size() )); + + m_shadows[shadowRank].height = height; } float CEngine::GetObjectShadowRadius(int objRank) { - if ( objRank < 0 || objRank >= static_cast( m_objects.size() ) ) - return 0.0f; + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - int i = m_objects[objRank].shadowRank; - if (i == -1) + int shadowRank = m_objects[objRank].shadowRank; + if (shadowRank == -1) return 0.0f; - return m_shadows[i].radius; + assert(shadowRank >= 0 && shadowRank < static_cast( m_shadows.size() )); + + return m_shadows[shadowRank].radius; } bool CEngine::GetHighlight(Math::Point &p1, Math::Point &p2) @@ -1585,21 +1414,26 @@ void CEngine::SetHighlightRank(int *rankList) bool CEngine::GetBBox2D(int objRank, Math::Point &min, Math::Point &max) { + assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + min.x = 1000000.0f; min.y = 1000000.0f; max.x = -1000000.0f; max.y = -1000000.0f; + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); + for (int i = 0; i < 8; i++) { Math::Vector p; - if ( i & (1<<0) ) p.x = m_objects[objRank].bboxMin.x; - else p.x = m_objects[objRank].bboxMax.x; - if ( i & (1<<1) ) p.y = m_objects[objRank].bboxMin.y; - else p.y = m_objects[objRank].bboxMax.y; - if ( i & (1<<2) ) p.z = m_objects[objRank].bboxMin.z; - else p.z = m_objects[objRank].bboxMax.z; + 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; Math::Vector pp; if (TransformPoint(pp, objRank, p)) @@ -1611,15 +1445,16 @@ bool CEngine::GetBBox2D(int objRank, Math::Point &min, Math::Point &max) } } - if ( min.x == 1000000.0f || - min.y == 1000000.0f || - max.x == -1000000.0f || - max.y == -1000000.0f ) return false; + if (min.x == 1000000.0f || + min.y == 1000000.0f || + max.x == -1000000.0f || + max.y == -1000000.0f) + return false; return true; } -void CEngine::FlushGroundSpot() +void CEngine::DeleteAllGroundSpots() { m_groundSpots.clear(); m_firstGroundSpot = true; @@ -1664,54 +1499,46 @@ int CEngine::CreateGroundSpot() void CEngine::DeleteGroundSpot(int rank) { + assert(rank >= 0 && rank < static_cast( m_groundSpots.size() )); + m_groundSpots[rank].used = false; m_groundSpots[rank].pos = Math::Vector(0.0f, 0.0f, 0.0f); } -bool CEngine::SetObjectGroundSpotPos(int rank, const Math::Vector& pos) +void CEngine::SetObjectGroundSpotPos(int rank, const Math::Vector& pos) { - if ( rank < 0 || rank >= static_cast( m_groundSpots.size() ) ) - return 0.0f; + assert(rank >= 0 && rank < static_cast( m_groundSpots.size() )); m_groundSpots[rank].pos = pos; - return true; } -bool CEngine::SetObjectGroundSpotRadius(int rank, float radius) +void CEngine::SetObjectGroundSpotRadius(int rank, float radius) { - if ( rank < 0 || rank >= static_cast( m_groundSpots.size() ) ) - return 0.0f; + assert(rank >= 0 && rank < static_cast( m_groundSpots.size() )); m_groundSpots[rank].radius = radius; - return true; } -bool CEngine::SetObjectGroundSpotColor(int rank, const Color& color) +void CEngine::SetObjectGroundSpotColor(int rank, const Color& color) { - if ( rank < 0 || rank >= static_cast( m_groundSpots.size() ) ) - return 0.0f; + assert(rank >= 0 && rank < static_cast( m_groundSpots.size() )); m_groundSpots[rank].color = color; - return true; } -bool CEngine::SetObjectGroundSpotMinMax(int rank, float min, float max) +void CEngine::SetObjectGroundSpotMinMax(int rank, float min, float max) { - if ( rank < 0 || rank >= static_cast( m_groundSpots.size() ) ) - return 0.0f; + assert(rank >= 0 && rank < static_cast( m_groundSpots.size() )); m_groundSpots[rank].min = min; m_groundSpots[rank].max = max; - return true; } -bool CEngine::SetObjectGroundSpotSmooth(int rank, float smooth) +void CEngine::SetObjectGroundSpotSmooth(int rank, float smooth) { - if ( rank < 0 || rank >= static_cast( m_groundSpots.size() ) ) - return 0.0f; + assert(rank >= 0 && rank < static_cast( m_groundSpots.size() )); m_groundSpots[rank].smooth = smooth; - return true; } void CEngine::CreateGroundMark(Math::Vector pos, float radius, @@ -1758,51 +1585,45 @@ void CEngine::UpdateGeometry() if (! m_updateGeometry) return; - for (int i = 0; i < static_cast( m_objects.size() ); i++) + for (int baseObjRank = 0; baseObjRank < static_cast( m_baseObjects.size() ); baseObjRank++) { - m_objects[i].bboxMin.x = 0; - m_objects[i].bboxMin.y = 0; - m_objects[i].bboxMin.z = 0; - m_objects[i].bboxMax.x = 0; - m_objects[i].bboxMax.y = 0; - m_objects[i].bboxMax.z = 0; - m_objects[i].radius = 0; - } + EngineBaseObject &p1 = m_baseObjects[baseObjRank]; + if (! p1.used) + continue; - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) - { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; + p1.bboxMin.LoadZero(); + p1.bboxMax.LoadZero(); + p1.radius = 0; for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; + EngineBaseObjTexTier& p2 = p1.next[l2]; + if (! p2.used) + continue; for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { - EngineObjLevel3& p3 = p2.next[l3]; - if (! p3.used) continue; + EngineBaseObjLODTier& p3 = p2.next[l3]; + if (! p3.used) + continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { - EngineObjLevel4& p4 = p3.next[l4]; - if (! p4.used) continue; - - int objRank = p2.objRank; + EngineBaseObjDataTier& p4 = p3.next[l4]; + if (! p4.used) + continue; for (int i = 0; i < static_cast( p4.vertices.size() ); i++) { - m_objects[objRank].bboxMin.x = Math::Min(p4.vertices[i].coord.x, m_objects[objRank].bboxMin.x); - m_objects[objRank].bboxMin.y = Math::Min(p4.vertices[i].coord.y, m_objects[objRank].bboxMin.y); - m_objects[objRank].bboxMin.z = Math::Min(p4.vertices[i].coord.z, m_objects[objRank].bboxMin.z); - m_objects[objRank].bboxMax.x = Math::Max(p4.vertices[i].coord.x, m_objects[objRank].bboxMax.x); - m_objects[objRank].bboxMax.y = Math::Max(p4.vertices[i].coord.y, m_objects[objRank].bboxMax.y); - m_objects[objRank].bboxMax.z = Math::Max(p4.vertices[i].coord.z, m_objects[objRank].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_objects[objRank].radius = Math::Max(m_objects[objRank].bboxMin.Length(), - m_objects[objRank].bboxMax.Length()); + p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length()); } } } @@ -1811,46 +1632,57 @@ void CEngine::UpdateGeometry() m_updateGeometry = false; } -void CEngine::UpdateStaticObjects() +void CEngine::UpdateStaticBuffer(EngineBaseObjDataTier& p4) +{ + PrimitiveType type; + if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) + type = PRIMITIVE_TRIANGLES; + else + type = PRIMITIVE_TRIANGLE_STRIP; + + if (p4.staticBufferId == 0) + p4.staticBufferId = m_device->CreateStaticBuffer(type, &p4.vertices[0], p4.vertices.size()); + else + m_device->UpdateStaticBuffer(p4.staticBufferId, type, &p4.vertices[0], p4.vertices.size()); + + p4.updateStaticBuffer = false; +} + +void CEngine::UpdateStaticBuffers() { - if (!m_updateStaticObjects) + if (!m_updateStaticBuffers) return; - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) + m_updateStaticBuffers = false; + + for (int baseObjRank = 0; baseObjRank < static_cast( m_baseObjects.size() ); baseObjRank++) { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; + if (! p1.used) + continue; for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; - - int objRank = p2.objRank; - - if (!m_objects[objRank].staticBuffer) + EngineBaseObjTexTier& p2 = p1.next[l2]; + if (! p2.used) continue; for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { - EngineObjLevel3& p3 = p2.next[l3]; - if (! p3.used) continue; + EngineBaseObjLODTier& p3 = p2.next[l3]; + if (! p3.used) + continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { - EngineObjLevel4& p4 = p3.next[l4]; - if (! p4.used) continue; - - if (p4.staticBufferId != 0) + EngineBaseObjDataTier& p4 = p3.next[l4]; + if (! p4.used) continue; - PrimitiveType type; - if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) - type = PRIMITIVE_TRIANGLES; - else - type = PRIMITIVE_TRIANGLE_STRIP; + if (! p4.updateStaticBuffer) + continue; - p4.staticBufferId = m_device->CreateStaticObject(type, &p4.vertices[0], p4.vertices.size()); + UpdateStaticBuffer(p4); } } } @@ -1861,11 +1693,16 @@ void CEngine::Update() { ComputeDistance(); UpdateGeometry(); - UpdateStaticObjects(); + UpdateStaticBuffers(); } bool CEngine::DetectBBox(int objRank, Math::Point mouse) { + assert(objRank >= 0 && objRank < static_cast(m_objects.size())); + + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast(m_baseObjects.size())); + Math::Point min, max; min.x = 1000000.0f; min.y = 1000000.0f; @@ -1876,12 +1713,12 @@ bool CEngine::DetectBBox(int objRank, Math::Point mouse) { Math::Vector p; - if ( i & (1<<0) ) p.x = m_objects[objRank].bboxMin.x; - else p.x = m_objects[objRank].bboxMax.x; - if ( i & (1<<1) ) p.y = m_objects[objRank].bboxMin.y; - else p.y = m_objects[objRank].bboxMax.y; - if ( i & (1<<2) ) p.z = m_objects[objRank].bboxMin.z; - else p.z = m_objects[objRank].bboxMax.z; + 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; Math::Vector pp; if ( TransformPoint(pp, objRank, p) ) @@ -1904,41 +1741,54 @@ int CEngine::DetectObject(Math::Point mouse) float min = 1000000.0f; int nearest = -1; - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) + for (int objRank = 0; objRank < static_cast( m_objects.size() ); objRank++) { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; + if (! m_objects[objRank].used) + continue; - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) - { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; + if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN) + continue; + + if (! DetectBBox(objRank, mouse)) + continue; + + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast(m_baseObjects.size())); - if (m_objects[p2.objRank].type == ENG_OBJTYPE_TERRAIN) continue; + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; + if (! p1.used) + continue; - if (! DetectBBox(p2.objRank, mouse)) continue; + for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) + { + EngineBaseObjTexTier& p2 = p1.next[l2]; + if (! p2.used) + continue; for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { - EngineObjLevel3& p3 = p2.next[l3]; - if (! p3.used) continue; + EngineBaseObjLODTier& p3 = p2.next[l3]; + if (! p3.used) + continue; - if (p3.min != 0.0f) continue; // LOD B or C? + if (p3.min != 0.0f) + continue; // LOD B or C? for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { - EngineObjLevel4& p4 = p3.next[l4]; - if (! p4.used) continue; + EngineBaseObjDataTier& p4 = p3.next[l4]; + if (! p4.used) + continue; if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) { for (int i = 0; i < static_cast( p4.vertices.size() ); i += 3) { float dist = 0.0f; - if (DetectTriangle(mouse, &p4.vertices[i], p2.objRank, dist) && dist < min) + if (DetectTriangle(mouse, &p4.vertices[i], objRank, dist) && dist < min) { min = dist; - nearest = p2.objRank; + nearest = objRank; } } } @@ -1947,10 +1797,10 @@ int CEngine::DetectObject(Math::Point mouse) for (int i = 0; i < static_cast( p4.vertices.size() ) - 2; i += 1) { float dist = 0.0f; - if (DetectTriangle(mouse, &p4.vertices[i], p2.objRank, dist) && dist < min) + if (DetectTriangle(mouse, &p4.vertices[i], objRank, dist) && dist < min) { min = dist; - nearest = p2.objRank; + nearest = objRank; } } } @@ -1964,6 +1814,8 @@ int CEngine::DetectObject(Math::Point mouse) bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRank, float& dist) { + assert(objRank >= 0 && objRank < static_cast(m_objects.size())); + Math::Vector p2D[3], p3D; for (int i = 0; i < 3; i++) @@ -1976,18 +1828,25 @@ bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRan return false; } - if ( mouse.x < p2D[0].x && - mouse.x < p2D[1].x && - mouse.x < p2D[2].x ) return false; - if ( mouse.x > p2D[0].x && - mouse.x > p2D[1].x && - mouse.x > p2D[2].x ) return false; - if ( mouse.y < p2D[0].y && - mouse.y < p2D[1].y && - mouse.y < p2D[2].y ) return false; - if ( mouse.y > p2D[0].y && - mouse.y > p2D[1].y && - mouse.y > p2D[2].y ) return false; + if (mouse.x < p2D[0].x && + mouse.x < p2D[1].x && + mouse.x < p2D[2].x) + return false; + + if (mouse.x > p2D[0].x && + mouse.x > p2D[1].x && + mouse.x > p2D[2].x) + return false; + + if (mouse.y < p2D[0].y && + mouse.y < p2D[1].y && + mouse.y < p2D[2].y) + return false; + + if (mouse.y > p2D[0].y && + mouse.y > p2D[1].y && + mouse.y > p2D[2].y) + return false; Math::Point a, b, c; a.x = p2D[0].x; @@ -2007,7 +1866,12 @@ bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRan //! Use only after world transform already set bool CEngine::IsVisible(int objRank) { - float radius = m_objects[objRank].radius; + assert(objRank >= 0 && objRank < static_cast(m_objects.size())); + + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast(m_baseObjects.size())); + + float radius = m_baseObjects[baseObjRank].radius; Math::Vector center(0.0f, 0.0f, 0.0f); if (m_device->ComputeSphereVisibility(center, radius) == Gfx::FRUSTUM_PLANE_ALL) { @@ -2016,15 +1880,18 @@ bool CEngine::IsVisible(int objRank) } m_objects[objRank].visible = false; - return true; + return false; } bool CEngine::TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p3D) { + assert(objRank >= 0 && objRank < static_cast(m_objects.size())); + p3D = Math::Transform(m_objects[objRank].transform, p3D); p3D = Math::Transform(m_matView, p3D); - if (p3D.z < 2.0f) return false; // behind? + if (p3D.z < 2.0f) + return false; // behind? p2D.x = (p3D.x/p3D.z)*m_matProj.Get(1,1); p2D.y = (p3D.y/p3D.z)*m_matProj.Get(2,2); @@ -2387,42 +2254,49 @@ bool CEngine::LoadAllTextures() bool ok = true; - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) + for (int objRank = 0; objRank < static_cast( m_objects.size() ); objRank++) { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; + if (! m_objects[objRank].used) + continue; bool terrain = false; + if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN) + terrain = true; - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) - { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); - if (m_objects[p2.objRank].type == ENG_OBJTYPE_TERRAIN) - terrain = true; - } + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; + if (! p1.used) + continue; - if (! p1.tex1Name.empty()) + for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) { - if (terrain) - p1.tex1 = LoadTexture(p1.tex1Name, m_terrainTexParams); - else - p1.tex1 = LoadTexture(p1.tex1Name); + EngineBaseObjTexTier& p2 = p1.next[l2]; + if (! p2.used) + continue; - if (! p1.tex1.Valid()) - ok = false; - } + if (! p2.tex1Name.empty()) + { + if (terrain) + p2.tex1 = LoadTexture(p2.tex1Name, m_terrainTexParams); + else + p2.tex1 = LoadTexture(p2.tex1Name); - if (! p1.tex2Name.empty()) - { - if (terrain) - p1.tex2 = LoadTexture(p1.tex2Name, m_terrainTexParams); - else - p1.tex2 = LoadTexture(p1.tex2Name); + if (! p2.tex1.Valid()) + ok = false; + } + + if (! p2.tex2Name.empty()) + { + if (terrain) + p2.tex2 = LoadTexture(p2.tex2Name, m_terrainTexParams); + else + p2.tex2 = LoadTexture(p2.tex2Name); - if (! p1.tex2.Valid()) - ok = false; + if (! p2.tex2.Valid()) + ok = false; + } } } @@ -2438,7 +2312,8 @@ bool IsExcludeColor(Math::Point *exclude, int x, int y) if ( x >= static_cast(exclude[i+0].x*256.0f) && x < static_cast(exclude[i+1].x*256.0f) && y >= static_cast(exclude[i+0].y*256.0f) && - y < static_cast(exclude[i+1].y*256.0f) ) return true; // exclude + y < static_cast(exclude[i+1].y*256.0f) ) + return true; // exclude i += 2; } @@ -2454,12 +2329,13 @@ bool CEngine::ChangeTextureColor(const std::string& texName, Math::Point ts, Math::Point ti, Math::Point *exclude, float shift, bool hsv) { - if ( colorRef1.r == colorNew1.r && - colorRef1.g == colorNew1.g && - colorRef1.b == colorNew1.b && - colorRef2.r == colorNew2.r && - colorRef2.g == colorNew2.g && - colorRef2.b == colorNew2.b ) return true; + if (colorRef1.r == colorNew1.r && + colorRef1.g == colorNew1.g && + colorRef1.b == colorNew1.b && + colorRef2.r == colorNew2.r && + colorRef2.g == colorNew2.g && + colorRef2.b == colorNew2.b) + return true; DeleteTexture(texName); @@ -2494,7 +2370,8 @@ bool CEngine::ChangeTextureColor(const std::string& texName, { for (int x = sx; x < ex; x++) { - if (exclude != nullptr && IsExcludeColor(exclude, x,y) ) continue; + if (exclude != nullptr && IsExcludeColor(exclude, x,y) ) + continue; Color color = img.GetPixel(Math::IntPoint(x, y)); @@ -3124,7 +3001,8 @@ void CEngine::ApplyChange() viewport, and renders the scene. */ void CEngine::Render() { - if (! m_render) return; + if (! m_render) + return; m_statisticTriangle = 0; m_lastState = -1; @@ -3187,35 +3065,44 @@ void CEngine::Draw3DScene() { m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN); - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) + for (int objRank = 0; objRank < static_cast(m_objects.size()); objRank++) { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; + if (! m_objects[objRank].used) + continue; - // Should be loaded by now - SetTexture(p1.tex1, 0); - SetTexture(p1.tex2, 1); + if (m_objects[objRank].type != ENG_OBJTYPE_TERRAIN) + continue; - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) - { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; + if (! m_objects[objRank].drawWorld) + continue; - int objRank = p2.objRank; - if (m_objects[objRank].type != ENG_OBJTYPE_TERRAIN) - continue; - if (! m_objects[objRank].drawWorld) - continue; + m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform); + + if (! IsVisible(objRank)) + continue; - m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform); + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); + + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; + if (! p1.used) + continue; - if (! IsVisible(objRank)) + for (int l2 = 0; l2 < static_cast( 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( p2.next.size() ); l3++) { - EngineObjLevel3& p3 = p2.next[l3]; - if (! p3.used) continue; + EngineBaseObjLODTier& p3 = p2.next[l3]; + if (! p3.used) + continue; if ( m_objects[objRank].distance < p3.min || m_objects[objRank].distance >= p3.max ) @@ -3223,13 +3110,14 @@ void CEngine::Draw3DScene() for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { - EngineObjLevel4& p4 = p3.next[l4]; - if (! p4.used) continue; + EngineBaseObjDataTier& p4 = p3.next[l4]; + if (! p4.used) + continue; SetMaterial(p4.material); SetState(p4.state); - DrawObject(p4, m_objects[objRank].staticBuffer); + DrawObject(p4); } } } @@ -3247,47 +3135,56 @@ void CEngine::Draw3DScene() bool transparent = false; - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) + for (int objRank = 0; objRank < static_cast(m_objects.size()); objRank++) { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; + if (! m_objects[objRank].used) + continue; - // Should be loaded by now - SetTexture(p1.tex1, 0); - SetTexture(p1.tex2, 1); + if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN) + continue; - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) - { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; + if (! m_objects[objRank].drawWorld) + continue; - int objRank = p2.objRank; + m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform); - if (m_shadowVisible && m_objects[objRank].type == ENG_OBJTYPE_TERRAIN) - continue; + if (! IsVisible(objRank)) + continue; - if (! m_objects[objRank].drawWorld) - continue; + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); - m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform); + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; + if (! p1.used) + continue; - if (! IsVisible(objRank)) + m_lightMan->UpdateDeviceLights(m_objects[objRank].type); + + for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) + { + EngineBaseObjTexTier& p2 = p1.next[l2]; + if (! p2.used) continue; - m_lightMan->UpdateDeviceLights(m_objects[objRank].type); + // Should be loaded by now + SetTexture(p2.tex1, 0); + SetTexture(p2.tex2, 1); for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { - EngineObjLevel3& p3 = p2.next[l3]; - if (! p3.used) continue; + EngineBaseObjLODTier& p3 = p2.next[l3]; + if (! p3.used) + continue; if ( m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max ) continue; + m_objects[objRank].distance >= p3.max ) + continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { - EngineObjLevel4& p4 = p3.next[l4]; - if (! p4.used) continue; + EngineBaseObjDataTier& p4 = p3.next[l4]; + if (! p4.used) + continue; if (m_objects[objRank].transparency != 0.0f) // transparent ? { @@ -3298,7 +3195,7 @@ void CEngine::Draw3DScene() SetMaterial(p4.material); SetState(p4.state); - DrawObject(p4, m_objects[objRank].staticBuffer); + DrawObject(p4); } } } @@ -3311,47 +3208,56 @@ void CEngine::Draw3DScene() int tState = ENG_RSTATE_TTEXTURE_BLACK | ENG_RSTATE_2FACE; Color tColor = Color(68.0f / 255.0f, 68.0f / 255.0f, 68.0f / 255.0f, 68.0f / 255.0f); - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) + for (int objRank = 0; objRank < static_cast(m_objects.size()); objRank++) { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; + if (! m_objects[objRank].used) + continue; - // Should be loaded by now - SetTexture(p1.tex1, 0); - SetTexture(p1.tex2, 1); + if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN) + continue; - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) - { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; + if (! m_objects[objRank].drawWorld) + continue; - int objRank = p2.objRank; + m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform); - if (m_shadowVisible && m_objects[objRank].type == ENG_OBJTYPE_TERRAIN) - continue; + if (! IsVisible(objRank)) + continue; - if (! m_objects[objRank].drawWorld) - continue; + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); + + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; + if (! p1.used) + continue; - m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform); + m_lightMan->UpdateDeviceLights(m_objects[objRank].type); - if (! IsVisible(objRank)) + for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) + { + EngineBaseObjTexTier& p2 = p1.next[l2]; + if (! p2.used) continue; - m_lightMan->UpdateDeviceLights(m_objects[objRank].type); + // Should be loaded by now + SetTexture(p2.tex1, 0); + SetTexture(p2.tex2, 1); for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { - EngineObjLevel3& p3 = p2.next[l3]; - if (! p3.used) continue; + EngineBaseObjLODTier& p3 = p2.next[l3]; + if (! p3.used) + continue; - if ( m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max ) continue; + if (m_objects[objRank].distance < p3.min || + m_objects[objRank].distance >= p3.max) + continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { - EngineObjLevel4& p4 = p3.next[l4]; - if (! p4.used) continue; + EngineBaseObjDataTier& p4 = p3.next[l4]; + if (! p4.used) + continue; if (m_objects[objRank].transparency == 0.0f) continue; @@ -3359,7 +3265,7 @@ void CEngine::Draw3DScene() SetMaterial(p4.material); SetState(tState, tColor); - DrawObject(p4, m_objects[objRank].staticBuffer); + DrawObject(p4); } } } @@ -3388,28 +3294,28 @@ void CEngine::Draw3DScene() if (! m_overFront) DrawOverColor(); // draws the foreground color } -void CEngine::DrawObject(const EngineObjLevel4& obj, bool staticBuffer) +void CEngine::DrawObject(const EngineBaseObjDataTier& p4) { - if (staticBuffer) + if (p4.staticBufferId != 0) { - m_device->DrawStaticObject(obj.staticBufferId); + m_device->DrawStaticBuffer(p4.staticBufferId); - if (obj.type == ENG_TRIANGLE_TYPE_TRIANGLES) - m_statisticTriangle += obj.vertices.size() / 3; + if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) + m_statisticTriangle += p4.vertices.size() / 3; else - m_statisticTriangle += obj.vertices.size() - 2; + m_statisticTriangle += p4.vertices.size() - 2; } else { - if (obj.type == ENG_TRIANGLE_TYPE_TRIANGLES) + if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) { - m_device->DrawPrimitive(PRIMITIVE_TRIANGLES, &obj.vertices[0], obj.vertices.size()); - m_statisticTriangle += obj.vertices.size() / 3; + m_device->DrawPrimitive(PRIMITIVE_TRIANGLES, &p4.vertices[0], p4.vertices.size()); + m_statisticTriangle += p4.vertices.size() / 3; } else { - m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, &obj.vertices[0], obj.vertices.size() ); - m_statisticTriangle += obj.vertices.size() - 2; + m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, &p4.vertices[0], p4.vertices.size() ); + m_statisticTriangle += p4.vertices.size() - 2; } } } @@ -3459,52 +3365,60 @@ void CEngine::DrawInterface() m_device->SetTransform(TRANSFORM_VIEW, m_matView); - for (int l1 = 0; l1 < static_cast( m_objectTree.size() ); l1++) + for (int objRank = 0; objRank < static_cast(m_objects.size()); objRank++) { - EngineObjLevel1& p1 = m_objectTree[l1]; - if (! p1.used) continue; + if (! m_objects[objRank].used) + continue; - // Should be loaded by now - SetTexture(p1.tex1, 0); - SetTexture(p1.tex2, 1); + if (m_shadowVisible && m_objects[objRank].type == ENG_OBJTYPE_TERRAIN) + continue; - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) - { - EngineObjLevel2& p2 = p1.next[l2]; - if (! p2.used) continue; + if (! m_objects[objRank].drawFront) + continue; - int objRank = p2.objRank; + m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform); - if (m_shadowVisible && m_objects[objRank].type == ENG_OBJTYPE_TERRAIN) - continue; + if (! IsVisible(objRank)) + continue; - if (! m_objects[objRank].drawFront) - continue; + int baseObjRank = m_objects[objRank].baseObjRank; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); - m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform); + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; + if (! p1.used) + continue; + + m_lightMan->UpdateDeviceLights(m_objects[objRank].type); - if (! IsVisible(objRank)) + for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) + { + EngineBaseObjTexTier& p2 = p1.next[l2]; + if (! p2.used) continue; - m_lightMan->UpdateDeviceLights(m_objects[objRank].type); + SetTexture(p2.tex1, 0); + SetTexture(p2.tex2, 1); for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { - EngineObjLevel3& p3 = p2.next[l3]; - if (! p3.used) continue; + EngineBaseObjLODTier& p3 = p2.next[l3]; + if (! p3.used) + continue; - if ( m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max ) continue; + if (m_objects[objRank].distance < p3.min || + m_objects[objRank].distance >= p3.max) + continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { - EngineObjLevel4& p4 = p3.next[l4]; - if (! p4.used) continue; + EngineBaseObjDataTier& p4 = p3.next[l4]; + if (! p4.used) + continue; SetMaterial(p4.material); SetState(p4.state); - DrawObject(p4, m_objects[objRank].staticBuffer); + DrawObject(p4); } } } @@ -3537,7 +3451,8 @@ void CEngine::UpdateGroundSpotTextures() m_groundMark.drawPos.x == m_groundMark.pos.x && m_groundMark.drawPos.z == m_groundMark.pos.z && m_groundMark.drawRadius == m_groundMark.radius && - m_groundMark.drawIntensity == m_groundMark.intensity) return; + m_groundMark.drawIntensity == m_groundMark.intensity) + return; for (int s = 0; s < 16; s++) { @@ -3612,11 +3527,12 @@ void CEngine::UpdateGroundSpotTextures() // Draw the new shadows. for (int i = 0; i < static_cast( m_groundSpots.size() ); i++) { - if ( m_groundSpots[i].used == false || - m_groundSpots[i].radius == 0.0f ) continue; + if (m_groundSpots[i].used == false || + m_groundSpots[i].radius == 0.0f) + continue; - if ( m_groundSpots[i].min == 0.0f && - m_groundSpots[i].max == 0.0f ) + if (m_groundSpots[i].min == 0.0f && + m_groundSpots[i].max == 0.0f) { dot = static_cast(m_groundSpots[i].radius/2.0f); @@ -3635,8 +3551,9 @@ void CEngine::UpdateGroundSpotTextures() px = cx-Math::Mod(cx, 1.0f); py = cy-Math::Mod(cy, 1.0f); // multiple of 1 - if ( px+dot < min.x || py+dot < min.y || - px-dot > max.x || py-dot > max.y ) continue; + if (px+dot < min.x || py+dot < min.y || + px-dot > max.x || py-dot > max.y) + continue; for (int iy = -dot; iy <= dot; iy++) { @@ -3645,8 +3562,9 @@ void CEngine::UpdateGroundSpotTextures() float ppx = px+ix; float ppy = py+iy; - if ( ppx < min.x || ppy < min.y || - ppx >= max.x || ppy >= max.y ) continue; + if (ppx < min.x || ppy < min.y || + ppx >= max.x || ppy >= max.y) + continue; float intensity; if (dot == 0) @@ -3678,8 +3596,9 @@ void CEngine::UpdateGroundSpotTextures() pos.y = 0.0f; float level = m_terrain->GetFloorLevel(pos, true); - if ( level < m_groundSpots[i].min || - level > m_groundSpots[i].max ) continue; + if (level < m_groundSpots[i].min || + level > m_groundSpots[i].max) + continue; float intensity; if (level > (m_groundSpots[i].max+m_groundSpots[i].min)/2.0f) @@ -3727,13 +3646,16 @@ void CEngine::UpdateGroundSpotTextures() float ppy = py+iy; if (ppx < min.x || ppy < min.y || - ppx >= max.x || ppy >= max.y) continue; + ppx >= max.x || ppy >= max.y) + continue; ppx -= min.x; // on the texture ppy -= min.y; float intensity = 1.0f - Math::Point(ix, iy).Length() / dot; - if (intensity <= 0.0f) continue; + if (intensity <= 0.0f) + continue; + intensity *= m_groundMark.intensity; int j = (ix+dot) + (iy+dot) * m_groundMark.dx; @@ -3825,11 +3747,13 @@ void CEngine::DrawShadow() float lastIntensity = -1.0f; for (int i = 0; i < static_cast( m_shadows.size() ); i++) { - if (m_shadows[i].hide) continue; + if (m_shadows[i].hide) + continue; Math::Vector pos = m_shadows[i].pos; // pos = center of the shadow on the ground - if (m_eyePt.y == pos.y) continue; // camera at the same level? + if (m_eyePt.y == pos.y) + continue; // camera at the same level? float d = 0.0f; float D = 0.0f; @@ -3845,7 +3769,9 @@ void CEngine::DrawShadow() if ( h > 4.0f ) h = 4.0f; D = Math::Distance(m_eyePt, pos); - if ( D >= endDeepView ) continue; + if (D >= endDeepView) + continue; + d = D*h/height; pos.x += (m_eyePt.x-pos.x)*d/D; @@ -3861,7 +3787,9 @@ void CEngine::DrawShadow() if ( h > 4.0f ) h = 4.0f; D = Math::Distance(m_eyePt, pos); - if ( D >= endDeepView ) continue; + if (D >= endDeepView) + continue; + d = D*h/height; pos.x += (m_eyePt.x-pos.x)*d/D; @@ -3969,7 +3897,8 @@ void CEngine::DrawShadow() if ( D > startDeepView ) intensity *= 1.0f-(D-startDeepView)/(endDeepView-startDeepView); - if (intensity == 0.0f) continue; + if (intensity == 0.0f) + continue; if (lastIntensity != intensity) // intensity changed? { @@ -4091,7 +4020,8 @@ void CEngine::DrawBackgroundImage() void CEngine::DrawPlanet() { - if (! m_planet->PlanetExist()) return; + if (! m_planet->PlanetExist()) + return; m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false); m_device->SetRenderState(RENDER_STATE_LIGHTING, false); @@ -4106,7 +4036,8 @@ void CEngine::DrawPlanet() void CEngine::DrawForegroundImage() { - if (m_foregroundName.empty()) return; + if (m_foregroundName.empty()) + return; Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal @@ -4141,8 +4072,9 @@ void CEngine::DrawForegroundImage() void CEngine::DrawOverColor() { - if ( (m_overColor == Color(0.0f, 0.0f, 0.0f, 0.0f) && m_overMode == ENG_RSTATE_TCOLOR_BLACK) || - (m_overColor == Color(1.0f, 1.0f, 1.0f, 1.0f) && m_overMode == ENG_RSTATE_TCOLOR_WHITE) ) return; + if ((m_overColor == Color(0.0f, 0.0f, 0.0f, 0.0f) && m_overMode == ENG_RSTATE_TCOLOR_BLACK) || + (m_overColor == Color(1.0f, 1.0f, 1.0f, 1.0f) && m_overMode == ENG_RSTATE_TCOLOR_WHITE)) + return; Math::Point p1(0.0f, 0.0f); Math::Point p2(1.0f, 1.0f); diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index de57e4d..ad934a6 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -151,7 +151,7 @@ struct EngineTriangle //! 2nd texture std::string tex2Name; - EngineTriangle() + inline EngineTriangle() { state = ENG_RSTATE_NORMAL; } @@ -178,6 +178,97 @@ enum EngineObjectType ENG_OBJTYPE_METAL = 6 }; + +/** + * \struct EngineBaseObjDataTier + * \brief Tier 4 of object tree (data) + */ +struct EngineBaseObjDataTier +{ + bool used; + EngineTriangleType type; + Material material; + int state; + std::vector vertices; + unsigned int staticBufferId; + bool updateStaticBuffer; + + inline EngineBaseObjDataTier(bool used = false, + 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) {} +}; + +/** + * \struct EngineBaseObjLODTier + * \brief Tier 3 of base object tree (LOD) + */ +struct EngineBaseObjLODTier +{ + bool used; + float min; + float max; + std::vector next; + + inline EngineBaseObjLODTier(bool used = false, float min = 0.0f, float max = 0.0f) + : used(used), min(min), max(max) {} +}; + +/** + * \struct EngineBaseObjTexTier + * \brief Tier 2 of base object tree (textures) + */ +struct EngineBaseObjTexTier +{ + bool used; + std::string tex1Name; + Texture tex1; + std::string tex2Name; + Texture tex2; + std::vector next; + + inline EngineBaseObjTexTier(bool used = false, const std::string& tex1Name = "", + const std::string& tex2Name = "") + : used(used), tex1Name(tex1Name), tex2Name(tex2Name) {} +}; + +/** + * \struct BaseEngineObject + * \brief Base (template) object - geometry for engine objects + * + * This is also the tier 1 of base object tree. + */ +struct EngineBaseObject +{ + //! If true, base object is valid in objects vector + bool used; + //! Number of triangles + int totalTriangles; + //! Bounding box min (origin 0,0,0 always included) + Math::Vector bboxMin; + //! bounding box max (origin 0,0,0 always included) + Math::Vector bboxMax; + //! Radius of the sphere at the origin + float radius; + //! Next tier (LOD) + std::vector next; + + inline EngineBaseObject() + { + LoadDefault(); + } + + inline void LoadDefault() + { + used = false; + totalTriangles = 0; + bboxMax.LoadZero(); + bboxMin.LoadZero(); + radius = 0.0f; + } +}; + /** * \struct EngineObject * \brief Object drawn by the graphics engine @@ -186,35 +277,27 @@ struct EngineObject { //! If true, object is valid in objects vector bool used; + //! Rank of associated base engine object + int baseObjRank; //! If true, the object is drawn bool visible; //! If true, object is behind the 2D interface bool drawWorld; //! If true, the shape is before the 2D interface bool drawFront; - //! Number of triangles - int totalTriangles; //! Type of object EngineObjectType type; - //! Whether the object is stored and rendered as static buffer - bool staticBuffer; //! Transformation matrix Math::Matrix transform; //! Distance to object from eye point float distance; - //! Bounding box min (origin 0,0,0 always included) - Math::Vector bboxMin; - //! bounding box max (origin 0,0,0 always included) - Math::Vector bboxMax; - //! Radius of the sphere at the origin - float radius; //! Rank of the associated shadow int shadowRank; //! Transparency of the object [0, 1] float transparency; //! Calls LoadDefault() - EngineObject() + inline EngineObject() { LoadDefault(); } @@ -223,90 +306,18 @@ struct EngineObject inline void LoadDefault() { used = false; + baseObjRank = -1; visible = false; drawWorld = false; drawFront = false; - totalTriangles = 0; - staticBuffer = false; type = ENG_OBJTYPE_NULL; transform.LoadIdentity(); - bboxMax.LoadZero(); - bboxMin.LoadZero(); distance = 0.0f; - radius = 0.0f; shadowRank = -1; transparency = 0.0f; } }; -struct EngineObjLevel1; -struct EngineObjLevel2; -struct EngineObjLevel3; -struct EngineObjLevel4; - -/** - * \struct EngineObjLevel4 - * \brief Tier 4 of object tree - */ -struct EngineObjLevel4 -{ - bool used; - EngineTriangleType type; - Material material; - int state; - std::vector vertices; - unsigned int staticBufferId; - - EngineObjLevel4(bool used = false, - EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES, - const Material& material = Material(), - int state = ENG_RSTATE_NORMAL); -}; - -/** - * \struct EngineObjLevel3 - * \brief Tier 3 of object tree - */ -struct EngineObjLevel3 -{ - bool used; - float min; - float max; - std::vector next; - - EngineObjLevel3(bool used = false, float min = 0.0f, float max = 0.0f); -}; - -/** - * \struct EngineObjLevel2 - * \brief Tier 2 of object tree - */ -struct EngineObjLevel2 -{ - bool used; - int objRank; - std::vector next; - - EngineObjLevel2(bool used = false, int objRank = -1); -}; - -/** - * \struct EngineObjLevel1 - * \brief Tier 1 of object tree - */ -struct EngineObjLevel1 -{ - bool used; - std::string tex1Name; - Texture tex1; - std::string tex2Name; - Texture tex2; - std::vector next; - - EngineObjLevel1(bool used = false, const std::string& tex1Name = "", - const std::string& tex2Name = ""); -}; - /** * \struct EngineShadowType * \brief Type of shadow drawn by the graphics engine @@ -346,12 +357,12 @@ struct EngineShadow //! Height from the ground float height; - EngineShadow() + inline EngineShadow() { LoadDefault(); } - void LoadDefault() + inline void LoadDefault() { used = false; hide = false; @@ -388,12 +399,12 @@ struct EngineGroundSpot //! Radius of the shadow drawn float drawRadius; - EngineGroundSpot() + inline EngineGroundSpot() { LoadDefault(); } - void LoadDefault() + inline void LoadDefault() { used = false; color = Color(); @@ -452,12 +463,12 @@ struct EngineGroundMark //! Pointer to the table char* table; - EngineGroundMark() + inline EngineGroundMark() { LoadDefault(); } - void LoadDefault() + inline void LoadDefault() { draw = false; phase = ENG_GR_MARK_PHASE_NULL; @@ -549,10 +560,10 @@ struct EngineMouse //! Hot point Math::Point hotPoint; - EngineMouse(int icon1 = -1, int icon2 = -1, int iconShadow = -1, - EngineRenderState mode1 = ENG_RSTATE_NORMAL, - EngineRenderState mode2 = ENG_RSTATE_NORMAL, - Math::Point hotPoint = Math::Point()) + inline EngineMouse(int icon1 = -1, int icon2 = -1, int iconShadow = -1, + EngineRenderState mode1 = ENG_RSTATE_NORMAL, + EngineRenderState mode2 = ENG_RSTATE_NORMAL, + Math::Point hotPoint = Math::Point()) { this->icon1 = icon1; this->icon2 = icon2; @@ -745,64 +756,73 @@ public: /* *************** Object management *************** */ + // Base objects + + //! Creates a base object and returns its rank + int CreateBaseObject(); + //! Deletes a base object + void DeleteBaseObject(int baseObjRank); + //! Deletes all base objects + void DeleteAllBaseObjects(); + + //! Copies geometry between two base objects + void CopyBaseObject(int sourceBaseObjRank, int destBaseObjRank); + + //! Adds triangles to given object with the specified params + void AddBaseObjTriangles(int baseObjRank, const std::vector& vertices, + EngineTriangleType triangleType, + const Material& material, int state, + std::string tex1Name, std::string tex2Name, + float min, float max, bool globalUpdate); + + //! Adds a tier 4 engine object directly + void AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer, + std::string tex1Name, std::string tex2Name, + float min, float max, bool globalUpdate); + + // Objects + //! Creates a new object and returns its rank int CreateObject(); //! Deletes all objects, shadows and ground spots - void FlushObject(); + void DeleteAllObjects(); //! Deletes the given object - bool DeleteObject(int objRank); + void DeleteObject(int objRank); //@{ - //! Management of engine object type - bool SetObjectType(int objRank, EngineObjectType type); - EngineObjectType GetObjectType(int objRank); + //! Management of the base object rank for engine object + void SetObjectBaseRank(int objRank, int baseObjRank); + int GetObjectBaseRank(int objRank); //@} //@{ - //! Management of object transform - bool SetObjectTransform(int objRank, const Math::Matrix& transform); - bool GetObjectTransform(int objRank, Math::Matrix& transform); + //! Management of engine object type + void SetObjectType(int objRank, EngineObjectType type); + EngineObjectType GetObjectType(int objRank); //@} //@{ - //! Management of object static drawing flag - void SetObjectStatic(int objRank, bool staticBuffer); - bool GetObjectStatic(int objRank); + //! Management of object transform + void SetObjectTransform(int objRank, const Math::Matrix& transform); + void GetObjectTransform(int objRank, Math::Matrix& transform); //@} //! Sets drawWorld for given object - bool SetObjectDrawWorld(int objRank, bool draw); + void SetObjectDrawWorld(int objRank, bool draw); //! Sets drawFront for given object - bool SetObjectDrawFront(int objRank, bool draw); + void SetObjectDrawFront(int objRank, bool draw); //! Sets the transparency level for given object - bool SetObjectTransparency(int objRank, float value); + void SetObjectTransparency(int objRank, float value); //! Returns the bounding box for an object - bool GetObjectBBox(int objRank, Math::Vector& min, Math::Vector& max); + void GetObjectBBox(int objRank, Math::Vector& min, Math::Vector& max); //! Returns the total number of triangles of given object int GetObjectTotalTriangles(int objRank); - //! Adds triangles to given object with the specified params - bool AddTriangles(int objRank, const std::vector& vertices, - const Material& material, int state, - std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate); - - //! Adds a surface to given object with the specified params - bool AddSurface(int objRank, const std::vector& vertices, - const Material& material, int state, - std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate); - - //! Adds a tier 4 engine object directly - bool AddQuick(int objRank, const EngineObjLevel4& buffer, - std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate); - //! Returns the first found tier 4 engine object for the given params or nullptr if not found - EngineObjLevel4* FindTriangles(int objRank, const Material& material, + EngineBaseObjDataTier* FindTriangles(int objRank, const Material& material, int state, std::string tex1Name, std::string tex2Name, float min, float max); @@ -814,16 +834,16 @@ public: void ChangeLOD(); //! Changes the 2nd texure for given object - bool ChangeSecondTexture(int objRank, const std::string& tex2Name); + void ChangeSecondTexture(int objRank, const std::string& tex2Name); //! Changes (recalculates) texture mapping for given object - bool ChangeTextureMapping(int objRank, const Material& mat, int state, + void ChangeTextureMapping(int objRank, const Material& mat, int state, const std::string& tex1Name, const std::string& tex2Name, float min, float max, EngineTextureMapping mode, float au, float bu, float av, float bv); //! Changes texture mapping for robot tracks - bool TrackTextureMapping(int objRank, const Material& mat, int state, + void TrackTextureMapping(int objRank, const Material& mat, int state, const std::string& tex1Name, const std::string& tex2Name, float min, float max, EngineTextureMapping mode, float pos, float factor, float tl, float ts, float tt); @@ -833,20 +853,20 @@ public: int DetectObject(Math::Point mouse); //! Creates a shadow for the given object - bool CreateShadow(int objRank); + void CreateShadow(int objRank); //! Deletes the shadow for given object void DeleteShadow(int objRank); //@{ //! Management of different shadow params - bool SetObjectShadowHide(int objRank, bool hide); - bool SetObjectShadowType(int objRank, EngineShadowType type); - bool SetObjectShadowPos(int objRank, const Math::Vector& pos); - bool SetObjectShadowNormal(int objRank, const Math::Vector& normal); - bool SetObjectShadowAngle(int objRank, float angle); - bool SetObjectShadowRadius(int objRank, float radius); - bool SetObjectShadowIntensity(int objRank, float intensity); - bool SetObjectShadowHeight(int objRank, float height); + void SetObjectShadowHide(int objRank, bool hide); + void SetObjectShadowType(int objRank, EngineShadowType type); + void SetObjectShadowPos(int objRank, const Math::Vector& pos); + void SetObjectShadowNormal(int objRank, const Math::Vector& normal); + void SetObjectShadowAngle(int objRank, float angle); + void SetObjectShadowRadius(int objRank, float radius); + void SetObjectShadowIntensity(int objRank, float intensity); + void SetObjectShadowHeight(int objRank, float height); float GetObjectShadowRadius(int objRank); //@} @@ -856,7 +876,7 @@ public: bool GetHighlight(Math::Point& p1, Math::Point& p2); //! Deletes all ground spots - void FlushGroundSpot(); + void DeleteAllGroundSpots(); //! Creates a new ground spot and returns its rank int CreateGroundSpot(); //! Deletes the given ground spot @@ -864,11 +884,11 @@ public: //@{ //! Management of different ground spot params - bool SetObjectGroundSpotPos(int rank, const Math::Vector& pos); - bool SetObjectGroundSpotRadius(int rank, float radius); - bool SetObjectGroundSpotColor(int rank, const Color& color); - bool SetObjectGroundSpotMinMax(int rank, float min, float max); - bool SetObjectGroundSpotSmooth(int rank, float smooth); + void SetObjectGroundSpotPos(int rank, const Math::Vector& pos); + void SetObjectGroundSpotRadius(int rank, float radius); + void SetObjectGroundSpotColor(int rank, const Color& color); + void SetObjectGroundSpotMinMax(int rank, float min, float max); + void SetObjectGroundSpotSmooth(int rank, float smooth); //@} //! Creates the ground mark with the given params @@ -1162,7 +1182,7 @@ protected: //! Prepares the interface for 3D scene void Draw3DScene(); //! Draw 3D object - void DrawObject(const EngineObjLevel4& obj, bool staticBuffer); + void DrawObject(const EngineBaseObjDataTier& p4); //! Draws the user interface over the scene void DrawInterface(); @@ -1192,15 +1212,13 @@ protected: //! Draw statistic texts void DrawStats(); - //! Creates new tier 1 object - EngineObjLevel1& AddLevel1(const std::string& tex1Name, const std::string& tex2Name); - //! Creates a new tier 2 object - EngineObjLevel2& AddLevel2(EngineObjLevel1 &p1, int objRank); - //! Creates a new tier 3 object - EngineObjLevel3& AddLevel3(EngineObjLevel2 &p2, float min, float max); - //! Creates a new tier 4 object - EngineObjLevel4& AddLevel4(EngineObjLevel3 &p3, EngineTriangleType type, - const Material& mat, int state); + //! Creates a new tier 2 object (texture) + EngineBaseObjTexTier& AddLevel2(int baseObjRank, 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) + EngineBaseObjDataTier& AddLevel4(EngineBaseObjLODTier &p3, EngineTriangleType type, + const Material& mat, int state); //! Create texture and add it to cache Texture CreateTexture(const std::string &texName, const TextureCreateParams ¶ms, CImage* image = nullptr); @@ -1227,8 +1245,11 @@ protected: //! Updates geometric parameters of objects (bounding box and radius) void UpdateGeometry(); + //! Updates a given static buffer + void UpdateStaticBuffer(EngineBaseObjDataTier& p4); + //! Updates static buffers of changed objects - void UpdateStaticObjects(); + void UpdateStaticBuffers(); protected: CInstanceManager* m_iMan; @@ -1282,8 +1303,8 @@ protected: //! Previous size of viewport window Math::IntPoint m_lastSize; - //! Root of tree object structure (level 1 list) - std::vector m_objectTree; + //! Base objects (also level 1 tier list) + std::vector m_baseObjects; //! Object parameters std::vector m_objects; //! Shadow list @@ -1308,7 +1329,7 @@ protected: Color m_waterAddColor; int m_statisticTriangle; bool m_updateGeometry; - bool m_updateStaticObjects; + bool m_updateStaticBuffers; int m_alphaMode; bool m_groundSpotVisible; bool m_shadowVisible; diff --git a/src/graphics/engine/modelfile.cpp b/src/graphics/engine/modelfile.cpp index a9972fe..a942b08 100644 --- a/src/graphics/engine/modelfile.cpp +++ b/src/graphics/engine/modelfile.cpp @@ -34,22 +34,10 @@ #include -/* - * NOTE: #ifndef checking for MODELFILE_NO_ENGINE - * is provided in this module to conditionally - * disable dependence on CEngine. - */ - - // Graphics module namespace namespace Gfx { -//! How big the triangle vector is by default -const int TRIANGLE_PREALLOCATE_COUNT = 2000; - - - bool ReadBinaryVertex(std::istream& stream, Vertex& vertex) { vertex.coord.x = IOUtils::ReadBinaryFloat(stream); @@ -322,15 +310,8 @@ bool ReadLineString(std::istream& stream, const std::string& prefix, std::string } -CModelFile::CModelFile(CInstanceManager* iMan) +CModelFile::CModelFile() { - m_iMan = iMan; - -#ifndef MODELFILE_NO_ENGINE - m_engine = static_cast(m_iMan->SearchInstance(CLASS_ENGINE)); -#endif - - m_triangles.reserve(TRIANGLE_PREALLOCATE_COUNT); } CModelFile::~CModelFile() @@ -1155,99 +1136,6 @@ bool CModelFile::WriteBinaryModel(std::ostream& stream) Other stuff *******************************************************/ -#ifndef MODELFILE_NO_ENGINE - - -/** - * TODO: move the function to CEngine or new class (CModelManager?) - * and make models shared static objects. - */ - -bool CModelFile::CreateEngineObject(int objRank) -{ - std::vector vs(3, VertexTex2()); - - m_engine->SetObjectStatic(objRank, true); // TODO: make optional in the future - - float limit[2]; - limit[0] = m_engine->GetLimitLOD(0); // frontier AB as config - limit[1] = m_engine->GetLimitLOD(1); // frontier BC as config - - for (int i = 0; i < static_cast( m_triangles.size() ); i++) - { - float min = m_triangles[i].min; - float max = m_triangles[i].max; - - // Standard frontiers -> config - if (min == 0.0f && max == 100.0f) // resolution A ? - { - max = limit[0]; - } - else if (min == 100.0f && max == 200.0f) // resolution B ? - { - min = limit[0]; - max = limit[1]; - } - else if (min == 200.0f && max == 1000000.0f) // resolution C ? - { - min = limit[1]; - } - - int state = m_triangles[i].state; - std::string tex2Name = m_triangles[i].tex2Name; - - if (m_triangles[i].variableTex2) - { - int texNum = m_engine->GetSecondTexture(); - - if (texNum >= 1 && texNum <= 10) - state |= ENG_RSTATE_DUAL_BLACK; - - if (texNum >= 11 && texNum <= 20) - state |= ENG_RSTATE_DUAL_WHITE; - - char name[20] = { 0 }; - sprintf(name, "dirty%.2d.png", texNum); - tex2Name = name; - } - - vs[0] = m_triangles[i].p1; - vs[1] = m_triangles[i].p2; - vs[2] = m_triangles[i].p3; - - bool ok = m_engine->AddTriangles(objRank, vs, - m_triangles[i].material, - state, - m_triangles[i].tex1Name, - tex2Name, - min, max, false); - if (!ok) - return false; - } - - return true; -} - -#endif - -void CModelFile::Mirror() -{ - for (int i = 0; i < static_cast( m_triangles.size() ); i++) - { - VertexTex2 t = m_triangles[i].p1; - m_triangles[i].p1 = m_triangles[i].p2; - m_triangles[i].p2 = t; - - m_triangles[i].p1.coord.z = -m_triangles[i].p1.coord.z; - m_triangles[i].p2.coord.z = -m_triangles[i].p2.coord.z; - m_triangles[i].p3.coord.z = -m_triangles[i].p3.coord.z; - - m_triangles[i].p1.normal.z = -m_triangles[i].p1.normal.z; - m_triangles[i].p2.normal.z = -m_triangles[i].p2.normal.z; - m_triangles[i].p3.normal.z = -m_triangles[i].p3.normal.z; - } -} - const std::vector& CModelFile::GetTriangles() { return m_triangles; @@ -1258,28 +1146,6 @@ int CModelFile::GetTriangleCount() return m_triangles.size(); } -float CModelFile::GetHeight(Math::Vector pos) -{ - float limit = 5.0f; - - for (int i = 0; i < static_cast( m_triangles.size() ); i++) - { - if ( fabs(pos.x - m_triangles[i].p1.coord.x) < limit && - fabs(pos.z - m_triangles[i].p1.coord.z) < limit ) - return m_triangles[i].p1.coord.y; - - if ( fabs(pos.x - m_triangles[i].p2.coord.x) < limit && - fabs(pos.z - m_triangles[i].p2.coord.z) < limit ) - return m_triangles[i].p2.coord.y; - - if ( fabs(pos.x - m_triangles[i].p3.coord.x) < limit && - fabs(pos.z - m_triangles[i].p3.coord.z) < limit ) - return m_triangles[i].p3.coord.y; - } - - return 0.0f; -} - void CModelFile::CreateTriangle(Math::Vector p1, Math::Vector p2, Math::Vector p3, float min, float max) { ModelTriangle triangle; diff --git a/src/graphics/engine/modelfile.h b/src/graphics/engine/modelfile.h index 6c573b8..b2b5d87 100644 --- a/src/graphics/engine/modelfile.h +++ b/src/graphics/engine/modelfile.h @@ -33,14 +33,10 @@ #include -class CInstanceManager; - // Graphics module namespace namespace Gfx { -class CEngine; - /** \struct ModelTriangle @@ -79,14 +75,15 @@ struct ModelTriangle /** - \class CModelFile - \brief Model file reader/writer - - Allows reading and writing model objects. Models are collections of ModelTriangle structs. */ + * \class CModelFile + * \brief Model file reader/writer + * + * Allows reading and writing model objects. Models are collections of ModelTriangle structs. + */ class CModelFile { public: - CModelFile(CInstanceManager* iMan); + CModelFile(); ~CModelFile(); //! Reads a model in text format from file @@ -128,23 +125,11 @@ public: //! Returns the triangle vector const std::vector& GetTriangles(); - //! Returns the height of model -- closest point to X and Z coords of \a pos - float GetHeight(Math::Vector pos); - - //! Mirrors the model along the Z axis - void Mirror(); - - //! Creates an object in the graphics engine from the model - bool CreateEngineObject(int objRank); - protected: //! Adds a triangle to the list void CreateTriangle(Math::Vector p1, Math::Vector p2, Math::Vector p3, float min, float max); protected: - CInstanceManager* m_iMan; - CEngine* m_engine; - //! Model triangles std::vector m_triangles; }; diff --git a/src/graphics/engine/modelmanager.cpp b/src/graphics/engine/modelmanager.cpp new file mode 100644 index 0000000..afaa718 --- /dev/null +++ b/src/graphics/engine/modelmanager.cpp @@ -0,0 +1,213 @@ +#include "graphics/engine/modelmanager.h" + +#include "app/app.h" + +#include "common/logger.h" + +#include "graphics/engine/engine.h" + +#include + +namespace Gfx { + +template<> CModelManager* CSingleton::mInstance = nullptr; + +CModelManager::CModelManager(CEngine* engine) +{ + m_engine = engine; +} + +CModelManager::~CModelManager() +{ +} + +bool CModelManager::LoadModel(const std::string& fileName, bool mirrored) +{ + GetLogger()->Info("Loading model '%s'\n", fileName.c_str()); + + CModelFile modelFile; + + std::string filePath = CApplication::GetInstance().GetDataFilePath(DIR_MODEL, fileName); + + if (!modelFile.ReadModel(filePath)) + { + GetLogger()->Error("Loading model '%s' failed\n", filePath.c_str()); + return false; + } + + ModelInfo modelInfo; + modelInfo.baseObjRank = m_engine->CreateBaseObject(); + modelInfo.triangles = modelFile.GetTriangles(); + + if (mirrored) + Mirror(modelInfo.triangles); + + FileInfo fileInfo(fileName, mirrored); + m_models[fileInfo] = modelInfo; + + std::vector vs(3, VertexTex2()); + + float limit[2]; + limit[0] = m_engine->GetLimitLOD(0); // frontier AB as config + limit[1] = m_engine->GetLimitLOD(1); // frontier BC as config + + for (int i = 0; i < static_cast( modelInfo.triangles.size() ); i++) + { + float min = modelInfo.triangles[i].min; + float max = modelInfo.triangles[i].max; + + // Standard frontiers -> config + if (min == 0.0f && max == 100.0f) // resolution A ? + { + max = limit[0]; + } + else if (min == 100.0f && max == 200.0f) // resolution B ? + { + min = limit[0]; + max = limit[1]; + } + else if (min == 200.0f && max == 1000000.0f) // resolution C ? + { + min = limit[1]; + } + + int state = modelInfo.triangles[i].state; + std::string tex2Name = modelInfo.triangles[i].tex2Name; + + if (modelInfo.triangles[i].variableTex2) + { + int texNum = m_engine->GetSecondTexture(); + + if (texNum >= 1 && texNum <= 10) + state |= ENG_RSTATE_DUAL_BLACK; + + if (texNum >= 11 && texNum <= 20) + state |= ENG_RSTATE_DUAL_WHITE; + + char name[20] = { 0 }; + sprintf(name, "dirty%.2d.png", texNum); + tex2Name = name; + } + + vs[0] = modelInfo.triangles[i].p1; + vs[1] = modelInfo.triangles[i].p2; + vs[2] = modelInfo.triangles[i].p3; + + m_engine->AddBaseObjTriangles(modelInfo.baseObjRank, vs, ENG_TRIANGLE_TYPE_TRIANGLES, + modelInfo.triangles[i].material, state, + modelInfo.triangles[i].tex1Name, tex2Name, + min, max, false); + } + + return true; +} + +bool CModelManager::AddModelReference(const std::string& fileName, bool mirrored, int objRank) +{ + auto it = m_models.find(FileInfo(fileName, mirrored)); + if (it == m_models.end()) + { + if (!LoadModel(fileName, mirrored)) + return false; + + it = m_models.find(FileInfo(fileName, mirrored)); + } + + m_engine->SetObjectBaseRank(objRank, (*it).second.baseObjRank); + + return true; +} + +bool CModelManager::AddModelCopy(const std::string& fileName, bool mirrored, int objRank) +{ + auto it = m_models.find(FileInfo(fileName, mirrored)); + if (it == m_models.end()) + { + if (!LoadModel(fileName, mirrored)) + return false; + + it = m_models.find(FileInfo(fileName, mirrored)); + } + + int copyBaseObjRank = m_engine->CreateBaseObject(); + m_engine->CopyBaseObject((*it).second.baseObjRank, copyBaseObjRank); + m_engine->SetObjectBaseRank(objRank, copyBaseObjRank); + + return true; +} + +bool CModelManager::IsModelLoaded(const std::string& fileName, bool mirrored) +{ + return m_models.count(FileInfo(fileName, mirrored)) > 0; +} + +int CModelManager::GetModelBaseObjRank(const std::string& fileName, bool mirrored) +{ + auto it = m_models.find(FileInfo(fileName, mirrored)); + if (it == m_models.end()) + return -1; + + return (*it).second.baseObjRank; +} + +void CModelManager::UnloadModel(const std::string& fileName, bool mirrored) +{ + auto it = m_models.find(FileInfo(fileName, mirrored)); + if (it == m_models.end()) + return; + + m_engine->DeleteBaseObject((*it).second.baseObjRank); + + m_models.erase(it); +} + +void CModelManager::UnloadAllModels() +{ + for (auto& mf : m_models) + m_engine->DeleteBaseObject(mf.second.baseObjRank); + + m_models.clear(); +} + +void CModelManager::Mirror(std::vector& triangles) +{ + for (int i = 0; i < static_cast( triangles.size() ); i++) + { + VertexTex2 t = triangles[i].p1; + triangles[i].p1 = triangles[i].p2; + triangles[i].p2 = t; + + triangles[i].p1.coord.z = -triangles[i].p1.coord.z; + triangles[i].p2.coord.z = -triangles[i].p2.coord.z; + triangles[i].p3.coord.z = -triangles[i].p3.coord.z; + + triangles[i].p1.normal.z = -triangles[i].p1.normal.z; + triangles[i].p2.normal.z = -triangles[i].p2.normal.z; + triangles[i].p3.normal.z = -triangles[i].p3.normal.z; + } +} + +float CModelManager::GetHeight(std::vector& triangles, Math::Vector pos) +{ + const float limit = 5.0f; + + for (int i = 0; i < static_cast( triangles.size() ); i++) + { + if ( fabs(pos.x - triangles[i].p1.coord.x) < limit && + fabs(pos.z - triangles[i].p1.coord.z) < limit ) + return triangles[i].p1.coord.y; + + if ( fabs(pos.x - triangles[i].p2.coord.x) < limit && + fabs(pos.z - triangles[i].p2.coord.z) < limit ) + return triangles[i].p2.coord.y; + + if ( fabs(pos.x - triangles[i].p3.coord.x) < limit && + fabs(pos.z - triangles[i].p3.coord.z) < limit ) + return triangles[i].p3.coord.y; + } + + return 0.0f; +} + + +} diff --git a/src/graphics/engine/modelmanager.h b/src/graphics/engine/modelmanager.h new file mode 100644 index 0000000..601d636 --- /dev/null +++ b/src/graphics/engine/modelmanager.h @@ -0,0 +1,97 @@ +#pragma once + +#include "common/singleton.h" + +#include "graphics/engine/modelfile.h" + +#include +#include +#include + +namespace Gfx { + +class CEngine; +class CModelFile; + +/** + * \class CModelManager + * \brief Manager for static models + * + * The manager allows for loading models as static objects and adding + * new instances of models to the engine. + * + * The models are loaded from stanard application model directory and + * they are identified by unique file names. + * + * The models are loaded by creating (if it doesn't exist yet) + * a base engine object from the model geometry. This base object + * is then shared among all instances of this model with the instances + * being engine objects linked to the shared base object. + * + * There is also a possibility of creating a copy of model so it has + * its own and unique base engine object. This is especially useful + * for models where the geometry must be altered. + */ +class CModelManager : public CSingleton +{ +public: + CModelManager(CEngine* engine); + ~CModelManager(); + + //! Loads a model from given file + bool LoadModel(const std::string& fileName, bool mirrored); + + //! Adds an instance of model to the given object rank as a reference to base object + bool AddModelReference(const std::string& fileName, bool mirrored, int objRank); + + //! Adds an instance of model to the given object rank as a copy (copied base object) + bool AddModelCopy(const std::string& fileName, bool mirrored, int objRank); + + //! Returns true if given model is loaded + bool IsModelLoaded(const std::string& fileName, bool mirrored); + + //! Returns the rank of base engine object of given loaded model + int GetModelBaseObjRank(const std::string& fileName, bool mirrored); + + //! Unloads the given model + void UnloadModel(const std::string& fileName, bool mirrored); + //! Unloads all models + void UnloadAllModels(); + +protected: + //! Returns the height of model -- closest point to X and Z coords of \a pos + float GetHeight(std::vector& triangles, Math::Vector pos); + + //! Mirrors the model along the Z axis + void Mirror(std::vector& triangles); + +private: + struct ModelInfo + { + std::vector triangles; + int baseObjRank; + }; + struct FileInfo + { + std::string fileName; + bool mirrored; + + inline FileInfo(const std::string& fileName, bool mirrored) + : fileName(fileName), mirrored(mirrored) {} + + inline bool operator<(const FileInfo& other) const + { + int compare = fileName.compare(other.fileName); + if (compare < 0) + return true; + if (compare > 0) + return false; + + return !mirrored && mirrored != other.mirrored; + } + }; + std::map m_models; + CEngine* m_engine; +}; + +} // namespace Gfx diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index 73c5cec..978471b 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -363,7 +363,6 @@ bool CPyro::Create(PyroType type, CObject* obj, float force) m_type == PT_EXPLOW ) { CreateTriangle(obj, oType, 0); - m_engine->SetObjectStatic(m_object->GetObjectRank(0), false); m_engine->DeleteShadow(m_object->GetObjectRank(0)); ExploStart(); } @@ -1398,8 +1397,6 @@ void CPyro::CreateTriangle(CObject* obj, ObjectType oType, int part) int objRank = obj->GetObjectRank(part); if (objRank == -1) return; - m_engine->SetObjectStatic(objRank, false); - float min = 0.0f; float max = m_engine->GetLimitLOD(0); int total = m_engine->GetObjectTotalTriangles(objRank); diff --git a/src/graphics/engine/terrain.cpp b/src/graphics/engine/terrain.cpp index 0e77ea2..a66b4b0 100644 --- a/src/graphics/engine/terrain.cpp +++ b/src/graphics/engine/terrain.cpp @@ -34,10 +34,6 @@ // Graphics module namespace namespace Gfx { -const int LEVEL_MAT_PREALLOCATE_COUNT = 101; -const int FLYING_LIMIT_PREALLOCATE_COUNT = 10; -const int BUILDING_LEVEL_PREALLOCATE_COUNT = 101; - CTerrain::CTerrain(CInstanceManager* iMan) { @@ -60,10 +56,6 @@ CTerrain::CTerrain(CInstanceManager* iMan) m_defaultHardness = 0.5f; m_useMaterials = false; - m_materials.reserve(LEVEL_MAT_PREALLOCATE_COUNT); - m_flyingLimits.reserve(FLYING_LIMIT_PREALLOCATE_COUNT); - m_buildingLevels.reserve(BUILDING_LEVEL_PREALLOCATE_COUNT); - FlushBuildingLevel(); FlushFlyingLimit(); FlushMaterials(); @@ -498,6 +490,13 @@ bool CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, const Material &mat, float min, float max) { + int baseObjRank = m_engine->GetObjectBaseRank(objRank); + if (baseObjRank == -1) + { + baseObjRank = m_engine->CreateBaseObject(); + m_engine->SetObjectBaseRank(objRank, baseObjRank); + } + std::string texName1; std::string texName2; @@ -547,7 +546,7 @@ bool CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, for (int y = 0; y < brick; y += step) { - EngineObjLevel4 buffer; + EngineBaseObjDataTier buffer; buffer.vertices.reserve(total); buffer.type = ENG_TRIANGLE_TYPE_SURFACE; @@ -640,7 +639,8 @@ bool CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, buffer.vertices.push_back(p1); buffer.vertices.push_back(p2); } - m_engine->AddQuick(objRank, buffer, texName1, texName2, min, max, true); + + m_engine->AddBaseObjQuick(baseObjRank, buffer, texName1, texName2, min, max, true); } } } @@ -1168,10 +1168,6 @@ bool CTerrain::CreateSquare(int x, int y) int objRank = m_engine->CreateObject(); m_engine->SetObjectType(objRank, ENG_OBJTYPE_TERRAIN); - // TODO: create a static object, but not split into squares, but a single object for all terrain - // Squares should be sub-objects accessing parts of triangle list - // m_engine->SetObjectStatic(objRank, true); - m_objRanks[x+y*m_mosaicCount] = objRank; float min = 0.0f; @@ -1278,7 +1274,10 @@ bool CTerrain::Terraform(const Math::Vector &p1, const Math::Vector &p2, float h { for (int x = pp1.x; x <= pp2.x; x++) { - m_engine->DeleteObject(m_objRanks[x+y*m_mosaicCount]); + int objRank = m_objRanks[x+y*m_mosaicCount]; + int baseObjRank = m_engine->GetObjectBaseRank(objRank); + m_engine->DeleteBaseObject(baseObjRank); + m_engine->DeleteObject(objRank); CreateSquare(x, y); // recreates the square } } diff --git a/src/graphics/engine/terrain.h b/src/graphics/engine/terrain.h index 3012e62..e17144e 100644 --- a/src/graphics/engine/terrain.h +++ b/src/graphics/engine/terrain.h @@ -328,7 +328,7 @@ protected: //! Calculates a vector of the terrain Math::Vector GetVector(int x, int y); //! Calculates a vertex of the terrain - VertexTex2 GetVertex(int x, int y, int step); + VertexTex2 GetVertex(int x, int y, int step); //! Creates all objects of a mosaic bool CreateMosaic(int ox, int oy, int step, int objRank, const Material& mat, float min, float max); //! Creates all objects in a mesh square ground diff --git a/src/graphics/engine/test/CMakeLists.txt b/src/graphics/engine/test/CMakeLists.txt index 4e3263b..b1db2c7 100644 --- a/src/graphics/engine/test/CMakeLists.txt +++ b/src/graphics/engine/test/CMakeLists.txt @@ -8,7 +8,6 @@ modelfile_test.cpp ../modelfile.cpp ../../../common/logger.cpp ../../../common/stringutils.cpp -../../../common/iman.cpp ) add_definitions(-DMODELFILE_NO_ENGINE) diff --git a/src/graphics/engine/test/modelfile_test.cpp b/src/graphics/engine/test/modelfile_test.cpp index 6879a1b..43cd43b 100644 --- a/src/graphics/engine/test/modelfile_test.cpp +++ b/src/graphics/engine/test/modelfile_test.cpp @@ -15,12 +15,11 @@ // * along with this program. If not, see http://www.gnu.org/licenses/. -#include "common/iman.h" #include "common/logger.h" #include "graphics/engine/modelfile.h" #include "math/func.h" -#include "gtest/gtest.h" +#include #include #include @@ -190,8 +189,7 @@ TEST(ModelFileTest, RWTxtModel) std::stringstream str; str.str(TEXT_MODEL); - CInstanceManager iMan; - Gfx::CModelFile modelFile(&iMan); + Gfx::CModelFile modelFile; EXPECT_TRUE(modelFile.ReadTextModel(str)); @@ -216,8 +214,7 @@ TEST(ModelFileTest, RWBinModel) std::stringstream str; str.str(TEXT_MODEL); - CInstanceManager iMan; - Gfx::CModelFile modelFile(&iMan); + Gfx::CModelFile modelFile; EXPECT_TRUE(modelFile.ReadTextModel(str)); @@ -242,8 +239,7 @@ TEST(ModelFileTest, RWOldModel) std::stringstream str; str.str(TEXT_MODEL); - CInstanceManager iMan; - Gfx::CModelFile modelFile(&iMan); + Gfx::CModelFile modelFile; EXPECT_TRUE(modelFile.ReadTextModel(str)); diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index 2d284d0..c1e18d3 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -949,7 +949,7 @@ void CGLDevice::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int glDisableClientState(GL_COLOR_ARRAY); } -unsigned int CGLDevice::CreateStaticObject(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) +unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { unsigned int id = 0; if (m_useVbo) @@ -983,7 +983,7 @@ unsigned int CGLDevice::CreateStaticObject(PrimitiveType primitiveType, const Ve return id; } -unsigned int CGLDevice::CreateStaticObject(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) +unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) { unsigned int id = 0; if (m_useVbo) @@ -1017,7 +1017,7 @@ unsigned int CGLDevice::CreateStaticObject(PrimitiveType primitiveType, const Ve return id; } -unsigned int CGLDevice::CreateStaticObject(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) +unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) { unsigned int id = 0; if (m_useVbo) @@ -1051,11 +1051,92 @@ unsigned int CGLDevice::CreateStaticObject(PrimitiveType primitiveType, const Ve return id; } -void CGLDevice::DrawStaticObject(unsigned int objectId) +void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { if (m_useVbo) { - auto it = m_vboObjects.find(objectId); + auto it = m_vboObjects.find(bufferId); + if (it == m_vboObjects.end()) + return; + + VboObjectInfo& info = (*it).second; + info.primitiveType = primitiveType; + info.vertexType = VERTEX_TYPE_NORMAL; + info.vertexCount = vertexCount; + + glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); + glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + else + { + glNewList(bufferId, GL_COMPILE); + + DrawPrimitive(primitiveType, vertices, vertexCount); + + glEndList(); + } +} + +void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) +{ + if (m_useVbo) + { + auto it = m_vboObjects.find(bufferId); + if (it == m_vboObjects.end()) + return; + + VboObjectInfo& info = (*it).second; + info.primitiveType = primitiveType; + info.vertexType = VERTEX_TYPE_TEX2; + info.vertexCount = vertexCount; + + glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); + glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + else + { + glNewList(bufferId, GL_COMPILE); + + DrawPrimitive(primitiveType, vertices, vertexCount); + + glEndList(); + } +} + +void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) +{ + if (m_useVbo) + { + auto it = m_vboObjects.find(bufferId); + if (it == m_vboObjects.end()) + return; + + VboObjectInfo& info = (*it).second; + info.primitiveType = primitiveType; + info.vertexType = VERTEX_TYPE_COL; + info.vertexCount = vertexCount; + + glBindBuffer(GL_ARRAY_BUFFER, info.bufferId); + glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + else + { + glNewList(bufferId, GL_COMPILE); + + DrawPrimitive(primitiveType, vertices, vertexCount); + + glEndList(); + } +} + +void CGLDevice::DrawStaticBuffer(unsigned int bufferId) +{ + if (m_useVbo) + { + auto it = m_vboObjects.find(bufferId); if (it == m_vboObjects.end()) return; @@ -1127,15 +1208,15 @@ void CGLDevice::DrawStaticObject(unsigned int objectId) } else { - glCallList(objectId); + glCallList(bufferId); } } -void CGLDevice::DestroyStaticObject(unsigned int objectId) +void CGLDevice::DestroyStaticBuffer(unsigned int bufferId) { if (m_useVbo) { - auto it = m_vboObjects.find(objectId); + auto it = m_vboObjects.find(bufferId); if (it == m_vboObjects.end()) return; @@ -1145,7 +1226,7 @@ void CGLDevice::DestroyStaticObject(unsigned int objectId) } else { - glDeleteLists(objectId, 1); + glDeleteLists(bufferId, 1); } } diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h index adae41b..dd43f2c 100644 --- a/src/graphics/opengl/gldevice.h +++ b/src/graphics/opengl/gldevice.h @@ -129,11 +129,14 @@ public: Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)); virtual void DrawPrimitive(PrimitiveType type, const VertexCol *vertices , int vertexCount); - virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); - virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount); - virtual unsigned int CreateStaticObject(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount); - virtual void DrawStaticObject(unsigned int objectId); - virtual void DestroyStaticObject(unsigned int objectId); + virtual unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + virtual unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount); + virtual unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount); + virtual void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); + virtual void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount); + virtual void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount); + virtual void DrawStaticBuffer(unsigned int bufferId); + virtual void DestroyStaticBuffer(unsigned int bufferId); virtual int ComputeSphereVisibility(const Math::Vector ¢er, float radius); -- cgit v1.2.3-1-g7c22 From 3582f107a5e77bc12fc61e4fd99c572a5985254b Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Thu, 27 Dec 2012 14:18:16 +0100 Subject: Fixes and refactoring --- src/graphics/engine/engine.cpp | 313 ++++++++++++--------------------------- src/graphics/engine/engine.h | 46 +++--- src/graphics/opengl/gldevice.cpp | 2 +- 3 files changed, 122 insertions(+), 239 deletions(-) (limited to 'src/graphics') 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( m_baseObjects[baseObjRank].next.size() ); i++) + for (int i = 0; i < static_cast( 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( 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( 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( 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( 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( 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( m_baseObjects.size() ); i++) + int baseObjRank = 0; + for ( ; baseObjRank < static_cast( 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( m_baseObjects.size() )) + if (baseObjRank == static_cast( 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( m_baseObjects.size() )); + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); + + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; + + if (! p1.used) + return; - for (int l2 = 0; l2 < static_cast( m_baseObjects[baseObjRank].next.size() ); l2++) + for (int l2 = 0; l2 < static_cast( 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( p2.next.size() ); l3++) { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (! p3.used) - continue; for (int l4 = 0; l4 < static_cast( 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 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 { for (int i = 0; i < static_cast( 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( 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( 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( m_objects.size() ); i++) + int objRank = 0; + for ( ; objRank < static_cast( 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( m_objects.size() )) + if (objRank == static_cast( 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( m_baseObjects.size() )); - for (int l2 = 0; l2 < static_cast( m_baseObjects[baseObjRank].next.size() ); l2++) + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; + + for (int l2 = 0; l2 < static_cast( 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( 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( 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( m_baseObjects.size() )); - int total = m_baseObjects[baseObjRank].totalTriangles; + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; + + int total = p1.totalTriangles; int expectedCount = static_cast(percent * total); triangles.reserve(Math::Min(maxCount, expectedCount)); int actualCount = 0; - for (int l2 = 0; l2 < static_cast( m_baseObjects[baseObjRank].next.size() ); l2++) + for (int l2 = 0; l2 < static_cast( 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( 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( 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( 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( m_baseObjects[baseObjRank].next.size() ); l2++) + for (int l2 = 0; l2 < static_cast( 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( 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( m_baseObjects.size() )); - + EngineBaseObject& p1 = m_baseObjects[baseObjRank]; for (int l2 = 0; l2 < static_cast( 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( 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( 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( p1.next.size() ); l2++) { EngineBaseObjTexTier& p2 = p1.next[l2]; - if (! p2.used) - continue; for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (! p3.used) - continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { EngineBaseObjDataTier& p4 = p3.next[l4]; - if (! p4.used) - continue; for (int i = 0; i < static_cast( p4.vertices.size() ); i++) { @@ -1664,20 +1582,14 @@ void CEngine::UpdateStaticBuffers() for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) { EngineBaseObjTexTier& p2 = p1.next[l2]; - if (! p2.used) - continue; for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (! p3.used) - continue; for (int l4 = 0; l4 < static_cast( 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(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( p1.next.size() ); l2++) { EngineBaseObjTexTier& p2 = p1.next[l2]; - if (! p2.used) - continue; for (int l3 = 0; l3 < static_cast( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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( 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 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 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(nullptr) + offsetof(Vertex, normal)); - glActiveTexture(GL_TEXTURE0); + glClientActiveTexture(GL_TEXTURE0); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, texCoord)); } -- cgit v1.2.3-1-g7c22 From 45bee618f91ae13f48e082b5b44c8c796564d2b5 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Thu, 27 Dec 2012 16:32:46 +0100 Subject: Fixed unicode rendering bug --- src/graphics/engine/text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 66c73a9..101e01a 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -677,7 +677,7 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::P return; int width = 1; - if (ch.c1 < 32) { // FIXME add support for chars with code 9 10 23 + if (ch.c1 > 0 && ch.c1 < 32) { // FIXME add support for chars with code 9 10 23 ch.c1 = ' '; ch.c2 = 0; ch.c3 = 0; -- cgit v1.2.3-1-g7c22 From 2ebe1fbcb68957bf1d374ffc5dc818dd706c72a7 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 28 Dec 2012 13:23:49 +0100 Subject: Fixed spider and worm model loading --- src/graphics/engine/engine.cpp | 44 +++++++++++++++++++++++++++++++++++++++++- src/graphics/engine/engine.h | 6 +++--- 2 files changed, 46 insertions(+), 4 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index ea0c093..f7e300e 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -703,7 +703,7 @@ void CEngine::DeleteObject(int objRank) void CEngine::SetObjectBaseRank(int objRank, int baseObjRank) { - assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); + assert(objRank == -1 || (objRank >= 0 && objRank < static_cast( m_objects.size() ))); m_objects[objRank].baseObjRank = baseObjRank; } @@ -770,6 +770,9 @@ void CEngine::GetObjectBBox(int objRank, Math::Vector& min, Math::Vector& max) assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + return; + assert(baseObjRank >= 0 && baseObjRank < static_cast(m_baseObjects.size())); min = m_baseObjects[baseObjRank].bboxMin; @@ -782,6 +785,9 @@ int CEngine::GetObjectTotalTriangles(int objRank) assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + return 0; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); return m_baseObjects[baseObjRank].totalTriangles; @@ -794,6 +800,9 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + return nullptr; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; @@ -834,6 +843,9 @@ int CEngine::GetPartialTriangles(int objRank, float min, float max, float percen assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + return 0; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; @@ -981,6 +993,9 @@ void CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name) assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + return; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; @@ -1344,6 +1359,9 @@ bool CEngine::GetBBox2D(int objRank, Math::Point &min, Math::Point &max) max.y = -1000000.0f; int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + return false; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; @@ -1613,6 +1631,9 @@ bool CEngine::DetectBBox(int objRank, Math::Point mouse) assert(objRank >= 0 && objRank < static_cast(m_objects.size())); int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + return false; + assert(baseObjRank >= 0 && baseObjRank < static_cast(m_baseObjects.size())); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; @@ -1667,6 +1688,9 @@ int CEngine::DetectObject(Math::Point mouse) continue; int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + continue; + assert(baseObjRank >= 0 && baseObjRank < static_cast(m_baseObjects.size())); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; @@ -1777,6 +1801,9 @@ bool CEngine::IsVisible(int objRank) assert(objRank >= 0 && objRank < static_cast(m_objects.size())); int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + return false; + assert(baseObjRank >= 0 && baseObjRank < static_cast(m_baseObjects.size())); float radius = m_baseObjects[baseObjRank].radius; @@ -2172,6 +2199,9 @@ bool CEngine::LoadAllTextures() terrain = true; int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + continue; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; @@ -2988,6 +3018,9 @@ void CEngine::Draw3DScene() continue; int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + continue; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; @@ -3051,6 +3084,9 @@ void CEngine::Draw3DScene() continue; int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + continue; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; @@ -3117,6 +3153,9 @@ void CEngine::Draw3DScene() continue; int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + continue; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; @@ -3267,6 +3306,9 @@ void CEngine::DrawInterface() continue; int baseObjRank = m_objects[objRank].baseObjRank; + if (baseObjRank == -1) + continue; + assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 899abc0..c9391db 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -621,9 +621,9 @@ struct EngineMouse * object equals to allocating space for EngineObject structure which holds object parameters. * * 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. + * must reference a valid base engine object or an empty base engine object (with rank = -1). + * This many-to-one association allows to share same geometric data (e.g. from same model) + * across objects. * * Base engine object data is stored in a 4-tier tree which splits the data describing triangles. * -- cgit v1.2.3-1-g7c22 From 2c0c5ddda16dd38fed39438d1e43d8e3589e8d93 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Thu, 3 Jan 2013 23:50:17 +0100 Subject: Fixed stupid debug code Terrain VBOs should work now --- src/graphics/opengl/gldevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/graphics') diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index 024a523..9460e07 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -1181,7 +1181,7 @@ void CGLDevice::DrawStaticBuffer(unsigned int bufferId) } GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType); - glDrawArrays(GL_TRIANGLES, 0, (*it).second.vertexCount); + glDrawArrays(mode, 0, (*it).second.vertexCount); if ((*it).second.vertexType == VERTEX_TYPE_NORMAL) { -- cgit v1.2.3-1-g7c22 From d1942e1216768d41bc747a79287962a76a3aeb75 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 4 Jan 2013 00:29:19 +0100 Subject: Correct font scaling with resolution --- src/graphics/engine/engine.cpp | 2 ++ src/graphics/engine/text.cpp | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index f7e300e..7c90a8d 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -281,6 +281,8 @@ void CEngine::Destroy() void CEngine::ResetAfterDeviceChanged() { + m_size = m_app->GetVideoConfig().size;; + m_text->FlushCache(); // TODO reload textures, reset device state, etc. diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 101e01a..da1a290 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -46,7 +46,7 @@ struct CachedFont }; - +const Math::IntPoint REFERENCE_SIZE(800, 600); CText::CText(CInstanceManager *iMan, CEngine* engine) @@ -147,6 +147,10 @@ void CText::FlushCache() f->cache.clear(); } } + + m_lastFontType = FONT_COLOBOT; + m_lastFontSize = 0; + m_lastCachedFont = nullptr; } void CText::DrawText(const std::string &text, std::map &format, @@ -723,8 +727,8 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::P CachedFont* CText::GetOrOpenFont(FontType font, float size) { - // TODO: sizing - int pointSize = static_cast(size); + Math::IntPoint windowSize = m_engine->GetWindowSize(); + int pointSize = static_cast(size * (windowSize.Length() / REFERENCE_SIZE.Length())); if (m_lastCachedFont != nullptr) { -- cgit v1.2.3-1-g7c22 From 8818a8e5db86f140230d789427373e1771747f5d Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sat, 5 Jan 2013 23:03:06 +0100 Subject: Corrected OpenGL extension detection - corrected multitexture and VBO detection - GLEW is now a required library - minor CMakeLists refactoring --- src/graphics/core/device.h | 5 +- src/graphics/opengl/gldevice.cpp | 204 +++++++++++++++++++++------------------ src/graphics/opengl/gldevice.h | 6 +- 3 files changed, 116 insertions(+), 99 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h index 618d21a..41d7796 100644 --- a/src/graphics/core/device.h +++ b/src/graphics/core/device.h @@ -104,8 +104,7 @@ enum RenderState RENDER_STATE_DEPTH_TEST, RENDER_STATE_DEPTH_WRITE, RENDER_STATE_ALPHA_TEST, - RENDER_STATE_CULLING, - RENDER_STATE_DITHERING + RENDER_STATE_CULLING }; /** @@ -287,7 +286,7 @@ public: virtual void DestroyAllTextures() = 0; //! Returns the maximum number of multitexture stages - virtual int GetMaxTextureCount() = 0; + virtual int GetMaxTextureStageCount() = 0; //! Sets the texture at given texture stage virtual void SetTexture(int index, const Texture &texture) = 0; //! Sets the texture image by ID at given texture stage diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index 9460e07..c535609 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -24,22 +24,9 @@ #include "math/geometry.h" -#if defined(USE_GLEW) - -// When using GLEW, only glew.h is needed +// Using GLEW so only glew.h is needed #include -#else - -// Should define prototypes of used extensions as OpenGL functions -#define GL_GLEXT_PROTOTYPES - -#include -#include -#include - -#endif // if defined(GLEW) - #include #include @@ -74,7 +61,8 @@ CGLDevice::CGLDevice(const GLDeviceConfig &config) m_config = config; m_lighting = false; m_lastVboId = 0; - m_useVbo = false; + m_multitextureAvailable = false; + m_vboAvailable = false; } @@ -93,7 +81,6 @@ bool CGLDevice::Create() { GetLogger()->Info("Creating CDevice\n"); -#if defined(USE_GLEW) static bool glewInited = false; if (!glewInited) @@ -106,26 +93,16 @@ bool CGLDevice::Create() return false; } - if ( (! GLEW_ARB_multitexture) || (! GLEW_EXT_texture_env_combine) ) - { - GetLogger()->Error("GLEW reports required extensions not supported\n"); - return false; - } + m_multitextureAvailable = glewIsSupported("GL_ARB_multitexture GL_ARB_texture_env_combine"); + if (!m_multitextureAvailable) + GetLogger()->Error("GLEW reports multitexturing not supported - graphics quality will be degraded!\n"); - if (GLEW_ARB_vertex_buffer_object) - { + m_vboAvailable = glewIsSupported("GL_ARB_vertex_buffer_object"); + if (m_vboAvailable) GetLogger()->Info("Detected ARB_vertex_buffer_object extension - using VBOs\n"); - m_useVbo = true; - } else - { GetLogger()->Info("No ARB_vertex_buffer_object extension present - using display lists\n"); - } } -#endif - - /* NOTE: when not using GLEW, extension testing is not performed, as it is assumed that - glext.h is up-to-date and the OpenGL shared library has the required functions present. */ // This is mostly done in all modern hardware by default // DirectX doesn't even allow the option to turn off perspective correction anymore @@ -135,6 +112,9 @@ bool CGLDevice::Create() // To avoid problems with scaling & lighting glEnable(GL_RESCALE_NORMAL); + // Minimal depth bias to avoid Z-fighting + SetDepthBias(0.001f); + // Set just to be sure glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glMatrixMode(GL_PROJECTION); @@ -186,14 +166,14 @@ void CGLDevice::ConfigChanged(const GLDeviceConfig& newConfig) Create(); } -void CGLDevice::SetUseVbo(bool useVbo) +void CGLDevice::SetUseVbo(bool vboAvailable) { - m_useVbo = useVbo; + m_vboAvailable = vboAvailable; } bool CGLDevice::GetUseVbo() { - return m_useVbo; + return m_vboAvailable; } void CGLDevice::BeginScene() @@ -610,7 +590,7 @@ void CGLDevice::DestroyAllTextures() m_allTextures.clear(); } -int CGLDevice::GetMaxTextureCount() +int CGLDevice::GetMaxTextureStageCount() { return m_currentTextures.size(); } @@ -621,17 +601,21 @@ int CGLDevice::GetMaxTextureCount() The setting is remembered, even if texturing is disabled at the moment. */ void CGLDevice::SetTexture(int index, const Texture &texture) { - assert(index >= 0); - assert(index < static_cast( m_currentTextures.size() )); + assert(index >= 0 && index < static_cast( m_currentTextures.size() )); bool same = m_currentTextures[index].id == texture.id; m_currentTextures[index] = texture; // remember the new value + if (!m_multitextureAvailable && index != 0) + return; + if (same) return; // nothing to do - glActiveTexture(GL_TEXTURE0 + index); + if (m_multitextureAvailable) + glActiveTexture(GL_TEXTURE0 + index); + glBindTexture(GL_TEXTURE_2D, texture.id); // Params need to be updated for the new bound texture @@ -640,15 +624,19 @@ void CGLDevice::SetTexture(int index, const Texture &texture) void CGLDevice::SetTexture(int index, unsigned int textureId) { - assert(index >= 0); - assert(index < static_cast( m_currentTextures.size() )); + assert(index >= 0 && index < static_cast( m_currentTextures.size() )); if (m_currentTextures[index].id == textureId) return; // nothing to do m_currentTextures[index].id = textureId; - glActiveTexture(GL_TEXTURE0 + index); + if (!m_multitextureAvailable && index != 0) + return; + + if (m_multitextureAvailable) + glActiveTexture(GL_TEXTURE0 + index); + glBindTexture(GL_TEXTURE_2D, textureId); // Params need to be updated for the new bound texture @@ -659,16 +647,14 @@ void CGLDevice::SetTexture(int index, unsigned int textureId) Returns the previously assigned texture or invalid texture if the given stage is not enabled. */ Texture CGLDevice::GetTexture(int index) { - assert(index >= 0); - assert(index < static_cast( m_currentTextures.size() )); + assert(index >= 0 && index < static_cast( m_currentTextures.size() )); return m_currentTextures[index]; } void CGLDevice::SetTextureEnabled(int index, bool enabled) { - assert(index >= 0); - assert(index < static_cast( m_currentTextures.size() )); + assert(index >= 0 && index < static_cast( m_currentTextures.size() )); bool same = m_texturesEnabled[index] == enabled; @@ -677,7 +663,12 @@ void CGLDevice::SetTextureEnabled(int index, bool enabled) if (same) return; // nothing to do - glActiveTexture(GL_TEXTURE0 + index); + if (!m_multitextureAvailable && index != 0) + return; + + if (m_multitextureAvailable) + glActiveTexture(GL_TEXTURE0 + index); + if (enabled) glEnable(GL_TEXTURE_2D); else @@ -686,8 +677,7 @@ void CGLDevice::SetTextureEnabled(int index, bool enabled) bool CGLDevice::GetTextureEnabled(int index) { - assert(index >= 0); - assert(index < static_cast( m_currentTextures.size() )); + assert(index >= 0 && index < static_cast( m_currentTextures.size() )); return m_texturesEnabled[index]; } @@ -698,17 +688,36 @@ bool CGLDevice::GetTextureEnabled(int index) The settings are remembered, even if texturing is disabled at the moment. */ void CGLDevice::SetTextureStageParams(int index, const TextureStageParams ¶ms) { - assert(index >= 0); - assert(index < static_cast( m_currentTextures.size() )); + assert(index >= 0 && index < static_cast( m_currentTextures.size() )); // Remember the settings m_textureStageParams[index] = params; + if (!m_multitextureAvailable && index != 0) + return; + // Don't actually do anything if texture not set if (! m_currentTextures[index].Valid()) return; - glActiveTexture(GL_TEXTURE0 + index); + if (m_multitextureAvailable) + glActiveTexture(GL_TEXTURE0 + index); + + if (params.wrapS == TEX_WRAP_CLAMP) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + else if (params.wrapS == TEX_WRAP_REPEAT) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + else assert(false); + + if (params.wrapT == TEX_WRAP_CLAMP) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + else if (params.wrapT == TEX_WRAP_REPEAT) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + else assert(false); + + // Texture env setting is silly without multitexturing + if (!m_multitextureAvailable) + return; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, params.factor.Array()); @@ -812,26 +821,12 @@ after_tex_color: glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_CONSTANT); else assert(false); - -after_tex_operations: - - if (params.wrapS == TEX_WRAP_CLAMP) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - else if (params.wrapS == TEX_WRAP_REPEAT) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - else assert(false); - - if (params.wrapT == TEX_WRAP_CLAMP) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - else if (params.wrapT == TEX_WRAP_REPEAT) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - else assert(false); +after_tex_operations: ; } void CGLDevice::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wrapT) { - assert(index >= 0); - assert(index < static_cast( m_currentTextures.size() )); + assert(index >= 0 && index < static_cast( m_currentTextures.size() )); // Remember the settings m_textureStageParams[index].wrapS = wrapS; @@ -841,7 +836,11 @@ void CGLDevice::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wr if (! m_currentTextures[index].Valid()) return; - glActiveTexture(GL_TEXTURE0 + index); + if (!m_multitextureAvailable && index != 0) + return; + + if (m_multitextureAvailable) + glActiveTexture(GL_TEXTURE0 + index); if (wrapS == TEX_WRAP_CLAMP) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); @@ -858,8 +857,7 @@ void CGLDevice::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wr TextureStageParams CGLDevice::GetTextureStageParams(int index) { - assert(index >= 0); - assert(index < static_cast( m_currentTextures.size() )); + assert(index >= 0 && index < static_cast( m_currentTextures.size() )); return m_textureStageParams[index]; } @@ -890,7 +888,9 @@ void CGLDevice::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int ve glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].normal)); - glClientActiveTexture(GL_TEXTURE0); + if (m_multitextureAvailable) + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast(&vs[0].texCoord)); @@ -914,13 +914,18 @@ void CGLDevice::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, in glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].normal)); - glClientActiveTexture(GL_TEXTURE0); + if (m_multitextureAvailable) + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord)); - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord2)); + if (m_multitextureAvailable) + { + glClientActiveTexture(GL_TEXTURE1); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast(&vs[0].texCoord2)); + } glColor4fv(color.Array()); @@ -929,8 +934,11 @@ void CGLDevice::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, in glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + if (m_multitextureAvailable) + { + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } } void CGLDevice::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount) @@ -952,7 +960,7 @@ void CGLDevice::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { unsigned int id = 0; - if (m_useVbo) + if (m_vboAvailable) { id = ++m_lastVboId; @@ -986,7 +994,7 @@ unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const Ve unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) { unsigned int id = 0; - if (m_useVbo) + if (m_vboAvailable) { id = ++m_lastVboId; @@ -1020,7 +1028,7 @@ unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const Ve unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) { unsigned int id = 0; - if (m_useVbo) + if (m_vboAvailable) { id = ++m_lastVboId; @@ -1053,7 +1061,7 @@ unsigned int CGLDevice::CreateStaticBuffer(PrimitiveType primitiveType, const Ve void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) { - if (m_useVbo) + if (m_vboAvailable) { auto it = m_vboObjects.find(bufferId); if (it == m_vboObjects.end()) @@ -1080,7 +1088,7 @@ void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiv void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) { - if (m_useVbo) + if (m_vboAvailable) { auto it = m_vboObjects.find(bufferId); if (it == m_vboObjects.end()) @@ -1107,7 +1115,7 @@ void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiv void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) { - if (m_useVbo) + if (m_vboAvailable) { auto it = m_vboObjects.find(bufferId); if (it == m_vboObjects.end()) @@ -1134,7 +1142,7 @@ void CGLDevice::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiv void CGLDevice::DrawStaticBuffer(unsigned int bufferId) { - if (m_useVbo) + if (m_vboAvailable) { auto it = m_vboObjects.find(bufferId); if (it == m_vboObjects.end()) @@ -1151,7 +1159,9 @@ void CGLDevice::DrawStaticBuffer(unsigned int bufferId) glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, normal)); - glClientActiveTexture(GL_TEXTURE0); + if (m_multitextureAvailable) + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast(nullptr) + offsetof(Vertex, texCoord)); } @@ -1163,13 +1173,18 @@ void CGLDevice::DrawStaticBuffer(unsigned int bufferId) glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, normal)); - glClientActiveTexture(GL_TEXTURE0); + if (m_multitextureAvailable) + glClientActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord)); - glClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord2)); + if (m_multitextureAvailable) + { + glClientActiveTexture(GL_TEXTURE1); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast(nullptr) + offsetof(VertexTex2, texCoord2)); + } } else if ((*it).second.vertexType == VERTEX_TYPE_COL) { @@ -1194,8 +1209,11 @@ void CGLDevice::DrawStaticBuffer(unsigned int bufferId) glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1 - glClientActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + if (m_multitextureAvailable) + { + glClientActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } } else if ((*it).second.vertexType == VERTEX_TYPE_COL) { @@ -1214,7 +1232,7 @@ void CGLDevice::DrawStaticBuffer(unsigned int bufferId) void CGLDevice::DestroyStaticBuffer(unsigned int bufferId) { - if (m_useVbo) + if (m_vboAvailable) { auto it = m_vboObjects.find(bufferId); if (it == m_vboObjects.end()) @@ -1355,7 +1373,6 @@ void CGLDevice::SetRenderState(RenderState state, bool enabled) case RENDER_STATE_DEPTH_TEST: flag = GL_DEPTH_TEST; break; case RENDER_STATE_ALPHA_TEST: flag = GL_ALPHA_TEST; break; case RENDER_STATE_CULLING: flag = GL_CULL_FACE; break; - case RENDER_STATE_DITHERING: flag = GL_DITHER; break; default: assert(false); break; } @@ -1380,7 +1397,6 @@ bool CGLDevice::GetRenderState(RenderState state) case RENDER_STATE_DEPTH_TEST: flag = GL_DEPTH_TEST; break; case RENDER_STATE_ALPHA_TEST: flag = GL_ALPHA_TEST; break; case RENDER_STATE_CULLING: flag = GL_CULL_FACE; break; - case RENDER_STATE_DITHERING: flag = GL_DITHER; break; default: assert(false); break; } diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h index dd43f2c..7137671 100644 --- a/src/graphics/opengl/gldevice.h +++ b/src/graphics/opengl/gldevice.h @@ -111,7 +111,7 @@ public: virtual void DestroyTexture(const Texture &texture); virtual void DestroyAllTextures(); - virtual int GetMaxTextureCount(); + virtual int GetMaxTextureStageCount(); virtual void SetTexture(int index, const Texture &texture); virtual void SetTexture(int index, unsigned int textureId); virtual Texture GetTexture(int index); @@ -229,8 +229,10 @@ private: int vertexCount; }; + //! Whether to use multitexturing + bool m_multitextureAvailable; //! Whether to use VBOs or display lists - bool m_useVbo; + bool m_vboAvailable; //! Map of saved VBO objects std::map m_vboObjects; //! Last ID of VBO object -- cgit v1.2.3-1-g7c22 From ff5c89085415a370911793d5764dfb694fc43b7d Mon Sep 17 00:00:00 2001 From: Marcin Zawadzki Date: Sat, 5 Jan 2013 23:03:26 +0100 Subject: Small fix in detecting language. Fixes needed to compile code using clang --- src/graphics/engine/test/CMakeLists.txt | 1 - src/graphics/opengl/test/CMakeLists.txt | 1 - 2 files changed, 2 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/test/CMakeLists.txt b/src/graphics/engine/test/CMakeLists.txt index 46509f4..c837ae5 100644 --- a/src/graphics/engine/test/CMakeLists.txt +++ b/src/graphics/engine/test/CMakeLists.txt @@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 2.8) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE debug) endif(NOT CMAKE_BUILD_TYPE) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wold-style-cast -std=gnu++0x") set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") set(MODELFILE_TEST_SOURCES diff --git a/src/graphics/opengl/test/CMakeLists.txt b/src/graphics/opengl/test/CMakeLists.txt index 154fec8..79e0ba5 100644 --- a/src/graphics/opengl/test/CMakeLists.txt +++ b/src/graphics/opengl/test/CMakeLists.txt @@ -8,7 +8,6 @@ find_package(PNG REQUIRED) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE debug) endif(NOT CMAKE_BUILD_TYPE) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wold-style-cast -std=gnu++0x") set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") set(ADD_LIBS "") -- cgit v1.2.3-1-g7c22 From edb1c0cbd62bfe7c620d7c8399f49acb98994b85 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sun, 6 Jan 2013 23:13:05 +0100 Subject: GLEW fix for some graphics drivers --- src/graphics/opengl/gldevice.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index c535609..80fa9a1 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -87,6 +87,8 @@ bool CGLDevice::Create() { glewInited = true; + glewExperimental = GL_TRUE; + if (glewInit() != GLEW_OK) { GetLogger()->Error("GLEW initialization failed\n"); @@ -95,7 +97,7 @@ bool CGLDevice::Create() m_multitextureAvailable = glewIsSupported("GL_ARB_multitexture GL_ARB_texture_env_combine"); if (!m_multitextureAvailable) - GetLogger()->Error("GLEW reports multitexturing not supported - graphics quality will be degraded!\n"); + GetLogger()->Warn("GLEW reports multitexturing not supported - graphics quality will be degraded!\n"); m_vboAvailable = glewIsSupported("GL_ARB_vertex_buffer_object"); if (m_vboAvailable) @@ -415,7 +417,9 @@ Texture CGLDevice::CreateTexture(ImageData *data, const TextureCreateParams &par result.size.y = data->surface->h; // Use & enable 1st texture stage - glActiveTexture(GL_TEXTURE0); + if (m_multitextureAvailable) + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_2D); glGenTextures(1, &result.id); -- cgit v1.2.3-1-g7c22 From 1285712aa22382a1a0d943aa29b310ecf6ebd365 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Tue, 8 Jan 2013 22:12:09 +0100 Subject: CMakeLists enhancements - compiler detection (clang and gcc version check) - compile flags only for src/ subdir - system and local include paths - fix for clang compilation --- src/graphics/engine/modelmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/modelmanager.cpp b/src/graphics/engine/modelmanager.cpp index afaa718..5b17769 100644 --- a/src/graphics/engine/modelmanager.cpp +++ b/src/graphics/engine/modelmanager.cpp @@ -8,9 +8,9 @@ #include -namespace Gfx { +template<> Gfx::CModelManager* CSingleton::mInstance = nullptr; -template<> CModelManager* CSingleton::mInstance = nullptr; +namespace Gfx { CModelManager::CModelManager(CEngine* engine) { -- cgit v1.2.3-1-g7c22 From a937a7b6ec081ab546505e5ab1fcd9b3723a6f4b Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sun, 27 Jan 2013 11:43:53 +0100 Subject: Changed model min/max to LOD levels --- src/graphics/engine/engine.cpp | 199 +++++++++------------------- src/graphics/engine/engine.h | 41 +++--- src/graphics/engine/modelfile.cpp | 146 ++++++++++++-------- src/graphics/engine/modelfile.h | 35 +++-- src/graphics/engine/modelmanager.cpp | 24 +--- src/graphics/engine/pyro.cpp | 38 ++++-- src/graphics/engine/terrain.cpp | 13 +- src/graphics/engine/terrain.h | 2 +- src/graphics/engine/test/modelfile_test.cpp | 17 +-- 9 files changed, 226 insertions(+), 289 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 7c90a8d..71b5e7d 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -109,13 +109,9 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_lookatPt = Math::Vector(0.0f, 0.0f, 1.0f); m_drawWorld = true; m_drawFront = false; - m_limitLOD[0] = 100.0f; - m_limitLOD[1] = 200.0f; m_particleDensity = 1.0f; - m_clippingDistance = 1.0f; m_lastClippingDistance = m_clippingDistance = 1.0f; m_objectDetail = 1.0f; - m_lastObjectDetail = m_objectDetail; m_terrainVision = 1000.0f; m_gadgetQuantity = 1.0f; m_textureQuality = 1; @@ -130,7 +126,6 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_editIndentValue = 4; m_tracePrecision = 1.0f; - m_alphaMode = 1; m_updateGeometry = false; m_updateStaticBuffers = false; @@ -208,7 +203,7 @@ CText* CEngine::GetText() bool CEngine::Create() { - m_size = m_lastSize = m_app->GetVideoConfig().size; + m_size = m_app->GetVideoConfig().size; m_lightMan = new CLightManager(m_iMan, this); m_text = new CText(m_iMan, this); @@ -416,11 +411,6 @@ Math::IntPoint CEngine::GetWindowSize() return m_size; } -Math::IntPoint CEngine::GetLastWindowSize() -{ - return m_lastSize; -} - Math::Point CEngine::WindowToInterfaceCoords(Math::IntPoint pos) { return Math::Point( static_cast(pos.x) / static_cast(m_size.x), @@ -473,15 +463,15 @@ EngineBaseObjTexTier& CEngine::AddLevel2(EngineBaseObject& p1, const std::string return p1.next.back(); } -EngineBaseObjLODTier& CEngine::AddLevel3(EngineBaseObjTexTier& p2, float min, float max) +EngineBaseObjLODTier& CEngine::AddLevel3(EngineBaseObjTexTier& p2, LODLevel lodLevel) { for (int i = 0; i < static_cast( p2.next.size() ); i++) { - if ( (p2.next[i].min == min) && (p2.next[i].max == max) ) + if (p2.next[i].lodLevel == lodLevel) return p2.next[i]; } - p2.next.push_back(EngineBaseObjLODTier(min, max)); + p2.next.push_back(EngineBaseObjLODTier(lodLevel)); return p2.next.back(); } @@ -570,17 +560,13 @@ void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector EngineTriangleType triangleType, const Material& material, int state, std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate) + LODLevel lodLevel, bool globalUpdate) { assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); - m_lastSize = m_size; - m_lastObjectDetail = m_objectDetail; - m_lastClippingDistance = m_clippingDistance; - EngineBaseObject& p1 = m_baseObjects[baseObjRank]; EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name); - EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max); + EngineBaseObjLODTier& p3 = AddLevel3(p2, lodLevel); EngineBaseObjDataTier& p4 = AddLevel4(p3, triangleType, material, state); p4.vertices.insert(p4.vertices.end(), vertices.begin(), vertices.end()); @@ -615,13 +601,13 @@ void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer, std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate) + LODLevel lodLevel, bool globalUpdate) { assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name); - EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max); + EngineBaseObjLODTier& p3 = AddLevel3(p2, lodLevel); p3.next.push_back(buffer); @@ -797,7 +783,7 @@ int CEngine::GetObjectTotalTriangles(int objRank) EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& material, int state, std::string tex1Name, - std::string tex2Name, float min, float max) + std::string tex2Name, int lodLevelMask) { assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); @@ -820,7 +806,7 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (p3.min != min || p3.max != max) + if ((p3.lodLevel & lodLevelMask) == 0) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) @@ -839,7 +825,7 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater return nullptr; } -int CEngine::GetPartialTriangles(int objRank, float min, float max, float percent, int maxCount, +int CEngine::GetPartialTriangles(int objRank, int lodLevelMask, float percent, int maxCount, std::vector& triangles) { assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); @@ -866,7 +852,7 @@ int CEngine::GetPartialTriangles(int objRank, float min, float max, float percen { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (p3.min != min || p3.max != max) + if ((p3.lodLevel & lodLevelMask) == 0) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) @@ -928,68 +914,6 @@ int CEngine::GetPartialTriangles(int objRank, float min, float max, float percen return actualCount; } -void CEngine::ChangeLOD() -{ - float oldLimit[2] = - { - GetLimitLOD(0, true), - GetLimitLOD(1, true) - }; - - float newLimit[2] = - { - GetLimitLOD(0, false), - GetLimitLOD(1, false) - }; - - float oldTerrain = m_terrainVision * m_lastClippingDistance; - float newTerrain = m_terrainVision * m_clippingDistance; - - for (int baseObjRank = 0; baseObjRank < static_cast( m_baseObjects.size() ); baseObjRank++) - { - EngineBaseObject& p1 = m_baseObjects[baseObjRank]; - - if (! p1.used) - continue; - - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) - { - EngineBaseObjTexTier& p2 = p1.next[l2]; - - for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) - { - EngineBaseObjLODTier& p3 = p2.next[l3]; - - if ( Math::IsEqual(p3.min, 0.0f ) && - Math::IsEqual(p3.max, oldLimit[0]) ) - { - p3.max = newLimit[0]; - } - else if ( Math::IsEqual(p3.min, oldLimit[0]) && - Math::IsEqual(p3.max, oldLimit[1]) ) - { - p3.min = newLimit[0]; - p3.max = newLimit[1]; - } - else if ( Math::IsEqual(p3.min, oldLimit[1]) && - Math::IsEqual(p3.max, 1000000.0f ) ) - { - p3.min = newLimit[1]; - } - else if ( Math::IsEqual(p3.min, 0.0f ) && - Math::IsEqual(p3.max, oldTerrain) ) - { - p3.max = newTerrain; - } - } - } - } - - m_lastSize = m_size; - m_lastObjectDetail = m_objectDetail; - m_lastClippingDistance = m_clippingDistance; -} - void CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name) { assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); @@ -1016,12 +940,12 @@ void CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name) void CEngine::ChangeTextureMapping(int objRank, const Material& mat, int state, const std::string& tex1Name, const std::string& tex2Name, - float min, float max, EngineTextureMapping mode, + int lodLevelMask, EngineTextureMapping mode, float au, float bu, float av, float bv) { assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, min, max); + EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, lodLevelMask); if (p4 == nullptr) return; @@ -1078,12 +1002,12 @@ void CEngine::ChangeTextureMapping(int objRank, const Material& mat, int state, void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, const std::string& tex1Name, const std::string& tex2Name, - float min, float max, EngineTextureMapping mode, + int lodLevelMask, EngineTextureMapping mode, float pos, float factor, float tl, float ts, float tt) { assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, min, max); + EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, lodLevelMask); if (p4 == nullptr) return; @@ -1707,8 +1631,8 @@ int CEngine::DetectObject(Math::Point mouse) { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (p3.min != 0.0f) - continue; // LOD B or C? + if (p3.lodLevel != LOD_Constant && p3.lodLevel != LOD_High) + continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { @@ -1820,6 +1744,43 @@ bool CEngine::IsVisible(int objRank) return false; } +bool CEngine::IsWithinLODLimit(float distance, LODLevel lodLevel) +{ + float min = 0.0f, max = 0.0f; + + if (lodLevel == LOD_Constant) + { + min = 0.0f; + max = m_terrainVision * m_clippingDistance; + } + else + { + if (lodLevel == LOD_High) + { + min = 0.0f; + max = 100.0f; + } + else if (lodLevel == LOD_Medium) + { + min = 100.0f; + max = 200.0f; + } + else if (lodLevel == LOD_Low) + { + min = 100.0f; + max = 1000000.0f; + } + + min *= m_size.x / 640.0f; + min *= m_objectDetail*2.0f; + + max *= m_size.x / 640.0f; + max *= m_objectDetail*2.0f; + } + + return distance >= min && distance < max; +} + bool CEngine::TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p3D) { assert(objRank >= 0 && objRank < static_cast(m_objects.size())); @@ -1856,15 +1817,6 @@ void CEngine::SetState(int state, const Color& color) m_lastState = state; m_lastColor = color; - if (m_alphaMode != 1 && (state & ENG_RSTATE_ALPHA)) - { - state &= ~ENG_RSTATE_ALPHA; - - if (m_alphaMode == 2) - state |= ENG_RSTATE_TTEXTURE_BLACK; - } - - if (state & ENG_RSTATE_TTEXTURE_BLACK) // transparent black texture? { m_device->SetRenderState(RENDER_STATE_FOG, false); @@ -2447,33 +2399,6 @@ void CEngine::SetTexture(const Texture& tex, int stage) m_device->SetTexture(stage, tex); } -void CEngine::SetLimitLOD(int rank, float limit) -{ - m_limitLOD[rank] = limit; -} - -float CEngine::GetLimitLOD(int rank, bool last) -{ - float limit = 0.0f; - - if (last) - { - limit = m_limitLOD[rank]; - limit *= m_lastSize.x/640.0f; // limit further if large window! - limit += m_limitLOD[0]*(m_lastObjectDetail*2.0f); - } - else - { - limit = m_limitLOD[rank]; - limit *= m_size.x/640.0f; // limit further if large window! - limit += m_limitLOD[0]*(m_objectDetail*2.0f); - } - - if (limit < 0.0f) limit = 0.0f; - - return limit; -} - void CEngine::SetTerrainVision(float vision) { m_terrainVision = vision; @@ -2709,6 +2634,7 @@ void CEngine::SetClippingDistance(float value) { if (value < 0.5f) value = 0.5f; if (value > 2.0f) value = 2.0f; + m_lastClippingDistance = m_clippingDistance; m_clippingDistance = value; } @@ -2920,7 +2846,6 @@ void CEngine::ApplyChange() m_deepView[1] /= m_lastClippingDistance; SetFocus(m_focus); - ChangeLOD(); m_deepView[0] *= m_clippingDistance; m_deepView[1] *= m_clippingDistance; @@ -3040,8 +2965,7 @@ void CEngine::Draw3DScene() { EngineBaseObjLODTier& p3 = p2.next[l3]; - if ( m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max ) + if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel)) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) @@ -3108,8 +3032,7 @@ void CEngine::Draw3DScene() { EngineBaseObjLODTier& p3 = p2.next[l3]; - if ( m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max ) + if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel)) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) @@ -3177,8 +3100,7 @@ void CEngine::Draw3DScene() { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max) + if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel)) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) @@ -3330,8 +3252,7 @@ void CEngine::DrawInterface() { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max) + if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel)) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index c9391db..e5c75bc 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -32,6 +32,8 @@ #include "graphics/core/texture.h" #include "graphics/core/vertex.h" +#include "graphics/engine/modelfile.h" + #include "math/intpoint.h" #include "math/matrix.h" #include "math/point.h" @@ -204,12 +206,11 @@ struct EngineBaseObjDataTier */ struct EngineBaseObjLODTier { - float min; - float max; + LODLevel lodLevel; std::vector next; - inline EngineBaseObjLODTier(float min = 0.0f, float max = 0.0f) - : min(min), max(max) {} + inline EngineBaseObjLODTier(LODLevel lodLevel = LOD_Constant) + : lodLevel(lodLevel) {} }; /** @@ -777,12 +778,12 @@ public: EngineTriangleType triangleType, const Material& material, int state, std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate); + LODLevel lodLevel, bool globalUpdate); //! Adds a tier 4 engine object directly void AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer, std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate); + LODLevel lodLevel, bool globalUpdate); // Objects @@ -827,29 +828,26 @@ public: //! Returns the first found tier 4 engine object for the given params or nullptr if not found EngineBaseObjDataTier* FindTriangles(int objRank, const Material& material, - int state, std::string tex1Name, std::string tex2Name, - float min, float max); + int state, std::string tex1Name, std::string tex2Name, + int lodLevelMask); //! Returns a partial list of triangles for given object - int GetPartialTriangles(int objRank, float min, float max, float percent, int maxCount, + int GetPartialTriangles(int objRank, int lodLevelMask, float percent, int maxCount, std::vector& triangles); - //! Updates LOD after parameter or resolution change - void ChangeLOD(); - //! 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, const Material& mat, int state, const std::string& tex1Name, const std::string& tex2Name, - float min, float max, EngineTextureMapping mode, + int lodLevelMask, EngineTextureMapping mode, float au, float bu, float av, float bv); //! Changes texture mapping for robot tracks void TrackTextureMapping(int objRank, const Material& mat, int state, const std::string& tex1Name, const std::string& tex2Name, - float min, float max, EngineTextureMapping mode, + int lodLevelMask, EngineTextureMapping mode, float pos, float factor, float tl, float ts, float tt); //! Detects the target object that is selected with the mouse @@ -947,12 +945,6 @@ public: //! Deletes the given texture, unloading it and removing from cache void DeleteTexture(const Texture& tex); - //@{ - //! Border management (distance limits) depends of the resolution (LOD = level-of-detail) - void SetLimitLOD(int rank, float limit); - float GetLimitLOD(int rank, bool last=false); - //@} - //! Defines of the distance field of vision void SetTerrainVision(float vision); @@ -1219,7 +1211,7 @@ protected: //! Creates a new tier 2 object (texture) 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); + EngineBaseObjLODTier& AddLevel3(EngineBaseObjTexTier &p2, LODLevel lodLevel); //! Creates a new tier 4 object (data) EngineBaseObjDataTier& AddLevel4(EngineBaseObjLODTier &p3, EngineTriangleType type, const Material& mat, int state); @@ -1230,6 +1222,9 @@ protected: //! Tests whether the given object is visible bool IsVisible(int objRank); + //! Checks whether the given distance is within LOD min & max limit + bool IsWithinLODLimit(float distance, LODLevel lodLevel); + //! Detects whether an object is affected by the mouse bool DetectBBox(int objRank, Math::Point mouse); @@ -1304,8 +1299,6 @@ protected: //! Current size of viewport window Math::IntPoint m_size; - //! Previous size of viewport window - Math::IntPoint m_lastSize; //! Base objects (also level 1 tier list) std::vector m_baseObjects; @@ -1356,12 +1349,10 @@ protected: Texture m_foregroundTex; bool m_drawWorld; bool m_drawFront; - float m_limitLOD[2]; float m_particleDensity; float m_clippingDistance; float m_lastClippingDistance; float m_objectDetail; - float m_lastObjectDetail; float m_terrainVision; float m_gadgetQuantity; int m_textureQuality; diff --git a/src/graphics/engine/modelfile.cpp b/src/graphics/engine/modelfile.cpp index a942b08..c9d41f3 100644 --- a/src/graphics/engine/modelfile.cpp +++ b/src/graphics/engine/modelfile.cpp @@ -495,8 +495,7 @@ bool CModelFile::ReadModel(std::istream& stream) triangle.material = t.material; triangle.tex1Name = std::string(t.texName); - triangle.min = t.min; - triangle.max = t.max; + triangle.lodLevel = MinMaxToLodLevel(t.min, t.max); m_triangles.push_back(triangle); } @@ -539,8 +538,7 @@ bool CModelFile::ReadModel(std::istream& stream) triangle.material = t.material; triangle.tex1Name = std::string(t.texName); - triangle.min = t.min; - triangle.max = t.max; + triangle.lodLevel = MinMaxToLodLevel(t.min, t.max); triangle.state = t.state; m_triangles.push_back(triangle); @@ -584,8 +582,7 @@ bool CModelFile::ReadModel(std::istream& stream) triangle.material = t.material; triangle.tex1Name = std::string(t.texName); - triangle.min = t.min; - triangle.max = t.max; + triangle.lodLevel = MinMaxToLodLevel(t.min, t.max); triangle.state = t.state; triangle.variableTex2 = t.texNum2 == 1; @@ -634,7 +631,7 @@ bool CModelFile::ReadModel(std::istream& stream) GetLogger()->Trace(" tex1: %s tex2: %s\n", m_triangles[i].tex1Name.c_str(), m_triangles[i].variableTex2 ? "(variable)" : m_triangles[i].tex2Name.c_str()); - GetLogger()->Trace(" min: %.2f max: %.2f\n", m_triangles[i].min, m_triangles[i].max); + GetLogger()->Trace(" lod level: %d\n", m_triangles[i].lodLevel); GetLogger()->Trace(" state: %ld\n", m_triangles[i].state); } @@ -685,8 +682,7 @@ bool CModelFile::WriteModel(std::ostream& stream) t.material = m_triangles[i].material; strncpy(t.texName, m_triangles[i].tex1Name.c_str(), 20); - t.min = m_triangles[i].min; - t.max = m_triangles[i].max; + LODLevelToMinMax(m_triangles[i].lodLevel, t.min, t.max); t.state = m_triangles[i].state; int no = 0; @@ -722,6 +718,46 @@ bool CModelFile::WriteModel(std::ostream& stream) return true; } +LODLevel CModelFile::MinMaxToLodLevel(float min, float max) +{ + if (min == 0.0f && max == 100.0f) + return LOD_High; + else if (min == 100.0f && max == 200.0f) + return LOD_Medium; + else if (min == 200.0f && max == 1000000.0f) + return LOD_Low; + else if (min == 0.0f && max == 1000000.0f) + return LOD_Constant; + + return LOD_Constant; +} + +void CModelFile::LODLevelToMinMax(LODLevel lodLevel, float& min, float& max) +{ + switch (lodLevel) + { + case LOD_High: + min = 0.0f; + max = 100.0f; + break; + + case LOD_Medium: + min = 100.0f; + max = 200.0f; + break; + + case LOD_Low: + min = 200.0f; + max = 1000000.0f; + break; + + case LOD_Constant: + min = 0.0f; + max = 1000000.0f; + break; + } +} + /******************************************************* New formats @@ -768,17 +804,15 @@ struct NewModelTriangle1 std::string tex2Name; //! If true, 2nd texture will be taken from current engine setting bool variableTex2; - //! Min LOD threshold - float min; - //! Max LOD threshold - float max; + //! LOD level + int lodLevel; //! Rendering state to be set int state; NewModelTriangle1() { variableTex2 = true; - min = max = 0.0f; + lodLevel = 0; state = 0; } }; @@ -834,8 +868,7 @@ bool CModelFile::ReadTextModel(std::istream& stream) ReadLineValue(stream, "tex1", t.tex1Name) && ReadLineValue(stream, "tex2", t.tex2Name) && ReadLineValue(stream, "var_tex2", varTex2Ch) && - ReadLineValue(stream, "min", t.min) && - ReadLineValue(stream, "max", t.max) && + ReadLineValue(stream, "lod_level", t.lodLevel) && ReadLineValue(stream, "state", t.state); if (!triOk || stream.fail()) @@ -855,10 +888,17 @@ bool CModelFile::ReadTextModel(std::istream& stream) triangle.tex1Name = t.tex1Name; triangle.tex2Name = t.tex2Name; triangle.variableTex2 = t.variableTex2; - triangle.min = t.min; - triangle.max = t.max; triangle.state = t.state; + switch (t.lodLevel) + { + case 0: triangle.lodLevel = LOD_Constant; break; + case 1: triangle.lodLevel = LOD_Low; break; + case 2: triangle.lodLevel = LOD_Medium; break; + case 3: triangle.lodLevel = LOD_High; break; + default: break; + } + m_triangles.push_back(triangle); continue; @@ -886,7 +926,7 @@ bool CModelFile::ReadTextModel(std::istream& stream) GetLogger()->Trace(" mat: d: %s a: %s s: %s\n", d.c_str(), a.c_str(), s.c_str()); GetLogger()->Trace(" tex1: %s tex2: %s\n", m_triangles[i].tex1Name.c_str(), m_triangles[i].tex2Name.c_str()); - GetLogger()->Trace(" min: %.2f max: %.2f\n", m_triangles[i].min, m_triangles[i].max); + GetLogger()->Trace(" lod level: %d\n", m_triangles[i].lodLevel); GetLogger()->Trace(" state: %ld\n", m_triangles[i].state); } @@ -938,10 +978,16 @@ bool CModelFile::WriteTextModel(std::ostream& stream) t.tex1Name = m_triangles[i].tex1Name; t.tex2Name = m_triangles[i].tex2Name; t.variableTex2 = m_triangles[i].variableTex2; - t.min = m_triangles[i].min; - t.max = m_triangles[i].max; t.state = m_triangles[i].state; + switch (m_triangles[i].lodLevel) + { + case LOD_Constant: t.lodLevel = 0; break; + case LOD_Low: t.lodLevel = 1; break; + case LOD_Medium: t.lodLevel = 2; break; + case LOD_High: t.lodLevel = 3; break; + } + stream << "p1 "; WriteTextVertexTex2(t.p1, stream); stream << "p2 "; @@ -954,8 +1000,7 @@ bool CModelFile::WriteTextModel(std::ostream& stream) stream << "tex1 " << t.tex1Name << std::endl; stream << "tex2 " << t.tex2Name << std::endl; stream << "var_tex2 " << (t.variableTex2 ? 'Y' : 'N') << std::endl; - stream << "min " << t.min << std::endl; - stream << "max " << t.max << std::endl; + stream << "lod_level " << t.lodLevel << std::endl; stream << "state " << t.state << std::endl; stream << std::endl; @@ -1012,9 +1057,8 @@ bool CModelFile::ReadBinaryModel(std::istream& stream) t.tex1Name = IOUtils::ReadBinaryString<1>(stream); t.tex2Name = IOUtils::ReadBinaryString<1>(stream); t.variableTex2 = IOUtils::ReadBinaryBool(stream); - t.min = IOUtils::ReadBinaryFloat(stream); - t.max = IOUtils::ReadBinaryFloat(stream); - t.state = IOUtils::ReadBinary<4, unsigned int>(stream); + t.lodLevel = IOUtils::ReadBinary<4, int>(stream); + t.state = IOUtils::ReadBinary<4, int>(stream); if (stream.fail()) { @@ -1030,10 +1074,17 @@ bool CModelFile::ReadBinaryModel(std::istream& stream) triangle.tex1Name = t.tex1Name; triangle.tex2Name = t.tex2Name; triangle.variableTex2 = t.variableTex2; - triangle.min = t.min; - triangle.max = t.max; triangle.state = t.state; + switch (t.lodLevel) + { + case 0: triangle.lodLevel = LOD_Constant; break; + case 1: triangle.lodLevel = LOD_Low; break; + case 2: triangle.lodLevel = LOD_Medium; break; + case 3: triangle.lodLevel = LOD_High; break; + default: break; + } + m_triangles.push_back(triangle); } } @@ -1059,7 +1110,7 @@ bool CModelFile::ReadBinaryModel(std::istream& stream) GetLogger()->Trace(" mat: d: %s a: %s s: %s\n", d.c_str(), a.c_str(), s.c_str()); GetLogger()->Trace(" tex1: %s tex2: %s\n", m_triangles[i].tex1Name.c_str(), m_triangles[i].tex2Name.c_str()); - GetLogger()->Trace(" min: %.2f max: %.2f\n", m_triangles[i].min, m_triangles[i].max); + GetLogger()->Trace(" lod level: %d\n", m_triangles[i].lodLevel); GetLogger()->Trace(" state: %ld\n", m_triangles[i].state); } @@ -1106,10 +1157,16 @@ bool CModelFile::WriteBinaryModel(std::ostream& stream) t.tex1Name = m_triangles[i].tex1Name; t.tex2Name = m_triangles[i].tex2Name; t.variableTex2 = m_triangles[i].variableTex2; - t.min = m_triangles[i].min; - t.max = m_triangles[i].max; t.state = m_triangles[i].state; + switch (m_triangles[i].lodLevel) + { + case LOD_Constant: t.lodLevel = 0; break; + case LOD_Low: t.lodLevel = 1; break; + case LOD_Medium: t.lodLevel = 2; break; + case LOD_High: t.lodLevel = 3; break; + } + WriteBinaryVertexTex2(t.p1, stream); WriteBinaryVertexTex2(t.p2, stream); WriteBinaryVertexTex2(t.p3, stream); @@ -1117,9 +1174,8 @@ bool CModelFile::WriteBinaryModel(std::ostream& stream) IOUtils::WriteBinaryString<1>(t.tex1Name, stream); IOUtils::WriteBinaryString<1>(t.tex2Name, stream); IOUtils::WriteBinaryBool(t.variableTex2, stream); - IOUtils::WriteBinaryFloat(t.min, stream); - IOUtils::WriteBinaryFloat(t.max, stream); - IOUtils::WriteBinary<4, unsigned int>(t.state, stream); + IOUtils::WriteBinary<4, int>(t.lodLevel, stream); + IOUtils::WriteBinary<4, int>(t.state, stream); if (stream.fail()) { @@ -1132,10 +1188,6 @@ bool CModelFile::WriteBinaryModel(std::ostream& stream) } -/******************************************************* - Other stuff - *******************************************************/ - const std::vector& CModelFile::GetTriangles() { return m_triangles; @@ -1146,23 +1198,5 @@ int CModelFile::GetTriangleCount() return m_triangles.size(); } -void CModelFile::CreateTriangle(Math::Vector p1, Math::Vector p2, Math::Vector p3, float min, float max) -{ - ModelTriangle triangle; - - Math::Vector n = Math::NormalToPlane(p3, p2, p1); - triangle.p1 = VertexTex2(p1, n); - triangle.p2 = VertexTex2(p2, n); - triangle.p3 = VertexTex2(p3, n); - - triangle.material.diffuse = Color(1.0f, 1.0f, 1.0f, 0.0f); - triangle.material.ambient = Color(0.5f, 0.5f, 0.5f, 0.0f); - - triangle.min = min; - triangle.max = max; - - m_triangles.push_back(triangle); -} - } // namespace Gfx diff --git a/src/graphics/engine/modelfile.h b/src/graphics/engine/modelfile.h index b2b5d87..3a702cb 100644 --- a/src/graphics/engine/modelfile.h +++ b/src/graphics/engine/modelfile.h @@ -39,9 +39,23 @@ namespace Gfx { /** - \struct ModelTriangle - \brief Triangle of a 3D model - */ + * \enum LODLevel + * \brief Level-of-detail + * + * A quantified replacement for older values of min/max. + */ +enum LODLevel +{ + LOD_Constant = -1, //!< triangle is always visible, no matter at what distance + LOD_Low = 1, //!< triangle is visible at farthest distance (lowest quality) + LOD_Medium = 2, //!< triangle is visible at medium distance (medium quality) + LOD_High = 4 //!< triangle is visible at closest distance (highest quality) +}; + +/** + * \struct ModelTriangle + * \brief Triangle of a 3D model + */ struct ModelTriangle { //! 1st vertex @@ -58,17 +72,15 @@ struct ModelTriangle std::string tex2Name; //! If true, 2nd texture will be taken from current engine setting bool variableTex2; - //! Min LOD threshold - float min; - //! Max LOD threshold - float max; + //! LOD level + LODLevel lodLevel; //! Rendering state to be set int state; ModelTriangle() { variableTex2 = true; - min = max = 0.0f; + lodLevel = LOD_Constant; state = 0; } }; @@ -126,8 +138,11 @@ public: const std::vector& GetTriangles(); protected: - //! Adds a triangle to the list - void CreateTriangle(Math::Vector p1, Math::Vector p2, Math::Vector p3, float min, float max); + //@{ + //! @deprecated min, max conversions + LODLevel MinMaxToLodLevel(float min, float max); + void LODLevelToMinMax(LODLevel lodLevel, float& min, float& max); + //@} protected: //! Model triangles diff --git a/src/graphics/engine/modelmanager.cpp b/src/graphics/engine/modelmanager.cpp index 5b17769..051922f 100644 --- a/src/graphics/engine/modelmanager.cpp +++ b/src/graphics/engine/modelmanager.cpp @@ -47,30 +47,8 @@ bool CModelManager::LoadModel(const std::string& fileName, bool mirrored) std::vector vs(3, VertexTex2()); - float limit[2]; - limit[0] = m_engine->GetLimitLOD(0); // frontier AB as config - limit[1] = m_engine->GetLimitLOD(1); // frontier BC as config - for (int i = 0; i < static_cast( modelInfo.triangles.size() ); i++) { - float min = modelInfo.triangles[i].min; - float max = modelInfo.triangles[i].max; - - // Standard frontiers -> config - if (min == 0.0f && max == 100.0f) // resolution A ? - { - max = limit[0]; - } - else if (min == 100.0f && max == 200.0f) // resolution B ? - { - min = limit[0]; - max = limit[1]; - } - else if (min == 200.0f && max == 1000000.0f) // resolution C ? - { - min = limit[1]; - } - int state = modelInfo.triangles[i].state; std::string tex2Name = modelInfo.triangles[i].tex2Name; @@ -96,7 +74,7 @@ bool CModelManager::LoadModel(const std::string& fileName, bool mirrored) m_engine->AddBaseObjTriangles(modelInfo.baseObjRank, vs, ENG_TRIANGLE_TYPE_TRIANGLES, modelInfo.triangles[i].material, state, modelInfo.triangles[i].tex1Name, tex2Name, - min, max, false); + modelInfo.triangles[i].lodLevel, false); } return true; diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index 978471b..e374d6c 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -1397,27 +1397,39 @@ void CPyro::CreateTriangle(CObject* obj, ObjectType oType, int part) int objRank = obj->GetObjectRank(part); if (objRank == -1) return; - float min = 0.0f; - float max = m_engine->GetLimitLOD(0); + int total = m_engine->GetObjectTotalTriangles(objRank); + float percent = 0.10f; if (total < 50) percent = 0.25f; if (total < 20) percent = 0.50f; if (m_type == PT_EGG) percent = 0.30f; - if ( oType == OBJECT_POWER || - oType == OBJECT_ATOMIC || - oType == OBJECT_URANIUM || - oType == OBJECT_TNT || - oType == OBJECT_BOMB ) percent = 0.75f; - if ( oType == OBJECT_MOBILEtg ) percent = 0.50f; - if ( oType == OBJECT_TEEN28 ) percent = 0.75f; - if ( oType == OBJECT_MOTHER ) max = 1000000.0f; - if ( oType == OBJECT_TEEN28 ) max = 1000000.0f; - if ( oType == OBJECT_TEEN31 ) max = 1000000.0f; + if (oType == OBJECT_POWER || + oType == OBJECT_ATOMIC || + oType == OBJECT_URANIUM || + oType == OBJECT_TNT || + oType == OBJECT_BOMB || + oType == OBJECT_TEEN28) + { + percent = 0.75f; + } + else if (oType == OBJECT_MOBILEtg) + { + percent = 0.50f; + } + + LODLevel lodLevel = LOD_High; + + if (oType == OBJECT_MOTHER || + oType == OBJECT_TEEN28 || + oType == OBJECT_TEEN31) + { + lodLevel = LOD_Constant; + } std::vector buffer; - total = m_engine->GetPartialTriangles(objRank, min, max, percent, 100, buffer); + total = m_engine->GetPartialTriangles(objRank, lodLevel, percent, 100, buffer); for (int i = 0; i < total; i++) { diff --git a/src/graphics/engine/terrain.cpp b/src/graphics/engine/terrain.cpp index a66b4b0..0be75bc 100644 --- a/src/graphics/engine/terrain.cpp +++ b/src/graphics/engine/terrain.cpp @@ -487,8 +487,7 @@ VertexTex2 CTerrain::GetVertex(int x, int y, int step) +-------------------> x \endverbatim */ bool CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, - const Material &mat, - float min, float max) + const Material &mat) { int baseObjRank = m_engine->GetObjectBaseRank(objRank); if (baseObjRank == -1) @@ -640,7 +639,7 @@ bool CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, buffer.vertices.push_back(p2); } - m_engine->AddBaseObjQuick(baseObjRank, buffer, texName1, texName2, min, max, true); + m_engine->AddBaseObjQuick(baseObjRank, buffer, texName1, texName2, LOD_Constant, true); } } } @@ -1170,15 +1169,9 @@ bool CTerrain::CreateSquare(int x, int y) m_objRanks[x+y*m_mosaicCount] = objRank; - float min = 0.0f; - float max = m_vision; - max *= m_engine->GetClippingDistance(); for (int step = 0; step < m_depth; step++) { - CreateMosaic(x, y, 1 << step, objRank, mat, min, max); - min = max; - max *= 2; - if (step == m_depth-1) max = Math::HUGE_NUM; + CreateMosaic(x, y, 1 << step, objRank, mat); } return true; diff --git a/src/graphics/engine/terrain.h b/src/graphics/engine/terrain.h index e17144e..91ddc76 100644 --- a/src/graphics/engine/terrain.h +++ b/src/graphics/engine/terrain.h @@ -330,7 +330,7 @@ protected: //! Calculates a vertex of the terrain VertexTex2 GetVertex(int x, int y, int step); //! Creates all objects of a mosaic - bool CreateMosaic(int ox, int oy, int step, int objRank, const Material& mat, float min, float max); + bool CreateMosaic(int ox, int oy, int step, int objRank, const Material& mat); //! Creates all objects in a mesh square ground bool CreateSquare(int x, int y); diff --git a/src/graphics/engine/test/modelfile_test.cpp b/src/graphics/engine/test/modelfile_test.cpp index 43cd43b..e7078a9 100644 --- a/src/graphics/engine/test/modelfile_test.cpp +++ b/src/graphics/engine/test/modelfile_test.cpp @@ -40,8 +40,7 @@ const char* const TEXT_MODEL = "tex1 lemt.png\n" "tex2\n" "var_tex2 N\n" -"min 200\n" -"max 1e+06\n" +"lod_level 0\n" "state 1024\n" "\n" "p1 c -19 -1 4 n -1 0 0 t1 0.248047 0.123047 t2 0.905224 0.52067\n" @@ -51,8 +50,7 @@ const char* const TEXT_MODEL = "tex1 derrick.png\n" "tex2\n" "var_tex2 Y\n" -"min 200\n" -"max 1e+06\n" +"lod_level 1\n" "state 0\n" ""; @@ -81,8 +79,7 @@ void Init() TRIANGLE_1.material.specular = Gfx::Color(0, 0, 0, 0); TRIANGLE_1.tex1Name = "lemt.png"; TRIANGLE_1.variableTex2 = false; - TRIANGLE_1.min = 200.0f; - TRIANGLE_1.max = 1e+06f; + TRIANGLE_1.lodLevel = Gfx::LOD_Constant; TRIANGLE_1.state = 1024; TRIANGLE_2.p1 = Gfx::VertexTex2(Math::Vector(-19, -1, 4), @@ -102,8 +99,7 @@ void Init() TRIANGLE_2.material.specular = Gfx::Color(0, 0, 0, 0); TRIANGLE_2.tex1Name = "derrick.png"; TRIANGLE_2.variableTex2 = true; - TRIANGLE_2.min = 200.0f; - TRIANGLE_2.max = 1e+06f; + TRIANGLE_2.lodLevel = Gfx::LOD_Low; TRIANGLE_2.state = 0; } @@ -171,10 +167,7 @@ bool CompareTriangles(const Gfx::ModelTriangle& t1, const Gfx::ModelTriangle& t2 if (t1.variableTex2 != t2.variableTex2) return false; - if (!Math::IsEqual(t1.min, t2.min)) - return false; - - if (!Math::IsEqual(t1.max, t2.max)) + if (t1.lodLevel != t2.lodLevel) return false; if (t1.state != t2.state) -- cgit v1.2.3-1-g7c22 From 209c6412ae149cc7c503fd7da384f344a830423c Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sun, 3 Feb 2013 20:03:36 +0100 Subject: Refactoring in tests infrastructure * all tests are now in /test/ subdirectory * unit tests concatenated to one executable (TODO: ui, common) * preparation for test environments (OpenGL and others) * removed old TestCBot --- src/graphics/opengl/test/CMakeLists.txt | 90 ------ src/graphics/opengl/test/README.txt | 9 - src/graphics/opengl/test/light_test.cpp | 462 ---------------------------- src/graphics/opengl/test/model_test.cpp | 377 ----------------------- src/graphics/opengl/test/tex1.png | Bin 151263 -> 0 bytes src/graphics/opengl/test/tex2.png | Bin 57503 -> 0 bytes src/graphics/opengl/test/texture_test.cpp | 192 ------------ src/graphics/opengl/test/transform_test.cpp | 339 -------------------- 8 files changed, 1469 deletions(-) delete mode 100644 src/graphics/opengl/test/CMakeLists.txt delete mode 100644 src/graphics/opengl/test/README.txt delete mode 100644 src/graphics/opengl/test/light_test.cpp delete mode 100644 src/graphics/opengl/test/model_test.cpp delete mode 100644 src/graphics/opengl/test/tex1.png delete mode 100644 src/graphics/opengl/test/tex2.png delete mode 100644 src/graphics/opengl/test/texture_test.cpp delete mode 100644 src/graphics/opengl/test/transform_test.cpp (limited to 'src/graphics') diff --git a/src/graphics/opengl/test/CMakeLists.txt b/src/graphics/opengl/test/CMakeLists.txt deleted file mode 100644 index 79e0ba5..0000000 --- a/src/graphics/opengl/test/CMakeLists.txt +++ /dev/null @@ -1,90 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -find_package(OpenGL REQUIRED) -find_package(SDL REQUIRED) -find_package(SDL_image REQUIRED) -find_package(PNG REQUIRED) - -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE debug) -endif(NOT CMAKE_BUILD_TYPE) -set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") - -set(ADD_LIBS "") - -if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") - set(PLATFORM_WINDOWS 1) - set(PLATFORM_LINUX 0) - set(PLATFORM_OTHER 0) -elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - set(PLATFORM_WINDOWS 0) - set(PLATFORM_LINUX 1) - set(PLATFORM_OTHER 0) - set(ADD_LIBS "-lrt") -else() - set(PLATFORM_WINDOWS 0) - set(PLATFORM_LINUX 0) - set(PLATFORM_OTHER 1) -endif() - -configure_file(../../../common/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/common/config.h) - - -set(TEXTURE_SOURCES -../gldevice.cpp -../../../common/logger.cpp -../../../common/image.cpp -texture_test.cpp -) - -set(MODEL_SOURCES -../gldevice.cpp -../../engine/modelfile.cpp -../../../common/logger.cpp -../../../common/image.cpp -../../../common/iman.cpp -../../../common/stringutils.cpp -../../../app/system.cpp -model_test.cpp -) - -set(TRANSFORM_SOURCES -../gldevice.cpp -../../../common/logger.cpp -../../../common/image.cpp -../../../common/iman.cpp -../../../app/system.cpp -transform_test.cpp -) - -set(LIGHT_SOURCES -../gldevice.cpp -../../../common/logger.cpp -../../../common/image.cpp -../../../common/iman.cpp -../../../app/system.cpp -light_test.cpp -) - -include_directories(../../../ ${CMAKE_CURRENT_BINARY_DIR}) - -set(LIBS -${SDL_LIBRARY} -${SDLIMAGE_LIBRARY} -${OPENGL_LIBRARY} -${PNG_LIBRARIES} -${ADD_LIBS} -) - -add_executable(texture_test ${TEXTURE_SOURCES}) -target_link_libraries(texture_test ${LIBS}) - -# Temporarily disabling because of dependencies on CEngine et al. -#add_executable(model_test ${MODEL_SOURCES}) -#target_link_libraries(model_test ${LIBS}) - -add_executable(transform_test ${TRANSFORM_SOURCES}) -target_link_libraries(transform_test ${LIBS}) - -add_executable(light_test ${LIGHT_SOURCES}) -target_link_libraries(light_test ${LIBS}) diff --git a/src/graphics/opengl/test/README.txt b/src/graphics/opengl/test/README.txt deleted file mode 100644 index c618415..0000000 --- a/src/graphics/opengl/test/README.txt +++ /dev/null @@ -1,9 +0,0 @@ -Test programs for OpenGL engine: - - texture_test -> multitexturing test with 2 textures (included as files: ./tex1.png, ./tex2.png) - - model_test -> simple model viewer to test model loading - usage: ./model_test {dxf|mod} model_file - second argument is the loaded format (DXF or Colobot .mod files) - requires ./tex folder (or symlink) with Colobot textures - viewer is controlled from keyboard - the bindings can be found in code - - transform_test -> simple "walk around" test for world & view transformations - - light test -> test for lighting diff --git a/src/graphics/opengl/test/light_test.cpp b/src/graphics/opengl/test/light_test.cpp deleted file mode 100644 index b19ba4b..0000000 --- a/src/graphics/opengl/test/light_test.cpp +++ /dev/null @@ -1,462 +0,0 @@ -#include "app/system.h" -#include "common/logger.h" -#include "common/image.h" -#include "common/iman.h" -#include "graphics/opengl/gldevice.h" -#include "math/geometry.h" - -#include -#include -#include - -#include -#include - -enum KeySlots -{ - K_Forward, - K_Back, - K_Left, - K_Right, - K_Up, - K_Down, - K_Count -}; -bool KEYMAP[K_Count] = { false }; - -Math::Point MOUSE_POS_BASE; - -Math::Vector TRANSLATION(0.0f, 2.0f, 0.0f); -Math::Vector ROTATION, ROTATION_BASE; - -float CUBE_ORBIT = 0.0f; - -const int FRAME_DELAY = 5000; - -SystemTimeStamp *PREV_TIME = NULL, *CURR_TIME = NULL; - -void Init(Gfx::CGLDevice *device) -{ - device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, true); - device->SetShadeModel(Gfx::SHADE_SMOOTH); -} - -void Render(Gfx::CGLDevice *device) -{ - device->BeginScene(); - - /* Unlit part of scene */ - - device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false); - device->SetRenderState(Gfx::RENDER_STATE_CULLING, false); // Double-sided drawing - - Math::Matrix persp; - Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.0f), 0.1f, 50.0f); - device->SetTransform(Gfx::TRANSFORM_PROJECTION, persp); - - - Math::Matrix viewMat; - Math::Matrix mat; - - viewMat.LoadIdentity(); - - Math::LoadRotationXMatrix(mat, -ROTATION.x); - viewMat = Math::MultiplyMatrices(viewMat, mat); - - Math::LoadRotationYMatrix(mat, -ROTATION.y); - viewMat = Math::MultiplyMatrices(viewMat, mat); - - Math::LoadTranslationMatrix(mat, -TRANSLATION); - viewMat = Math::MultiplyMatrices(viewMat, mat); - - device->SetTransform(Gfx::TRANSFORM_VIEW, viewMat); - - Math::Matrix worldMat; - worldMat.LoadIdentity(); - device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat); - - Gfx::VertexCol line[2] = { Gfx::VertexCol() }; - - for (int x = -40; x <= 40; ++x) - { - line[0].color = Gfx::Color(0.7f + x / 120.0f, 0.0f, 0.0f); - line[0].coord.z = -40; - line[0].coord.x = x; - line[1].color = Gfx::Color(0.7f + x / 120.0f, 0.0f, 0.0f); - line[1].coord.z = 40; - line[1].coord.x = x; - device->DrawPrimitive(Gfx::PRIMITIVE_LINES, line, 2); - } - - for (int z = -40; z <= 40; ++z) - { - line[0].color = Gfx::Color(0.0f, 0.7f + z / 120.0f, 0.0f); - line[0].coord.z = z; - line[0].coord.x = -40; - line[1].color = Gfx::Color(0.0f, 0.7f + z / 120.0f, 0.0f); - line[1].coord.z = z; - line[1].coord.x = 40; - device->DrawPrimitive(Gfx::PRIMITIVE_LINES, line, 2); - } - - - Gfx::VertexCol quad[6] = { Gfx::VertexCol() }; - - quad[0].coord = Math::Vector(-1.0f, -1.0f, 0.0f); - quad[1].coord = Math::Vector( 1.0f, -1.0f, 0.0f); - quad[2].coord = Math::Vector(-1.0f, 1.0f, 0.0f); - quad[3].coord = Math::Vector( 1.0f, 1.0f, 0.0f); - - for (int i = 0; i < 6; ++i) - quad[i].color = Gfx::Color(1.0f, 1.0f, 0.0f); - - Math::LoadTranslationMatrix(worldMat, Math::Vector(40.0f, 2.0f, 40.0f)); - device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat); - - device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4); - - for (int i = 0; i < 6; ++i) - quad[i].color = Gfx::Color(0.0f, 1.0f, 1.0f); - - Math::LoadTranslationMatrix(worldMat, Math::Vector(-40.0f, 2.0f, -40.0f)); - device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat); - - int planes = device->ComputeSphereVisibility(Math::Vector(0.0f, 0.0f, 0.0f), 1.0f); - printf("Planes:"); - if (planes == 0) - printf(" (none)"); - - if (planes & Gfx::FRUSTUM_PLANE_LEFT) - printf(" LEFT"); - - if (planes & Gfx::FRUSTUM_PLANE_RIGHT) - printf(" RIGHT"); - - if (planes & Gfx::FRUSTUM_PLANE_BOTTOM) - printf(" BOTTOM"); - - if (planes & Gfx::FRUSTUM_PLANE_TOP) - printf(" TOP"); - - if (planes & Gfx::FRUSTUM_PLANE_FRONT) - printf(" FRONT"); - - if (planes & Gfx::FRUSTUM_PLANE_BACK) - printf(" BACK"); - - printf("\n"); - - device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4); - - for (int i = 0; i < 6; ++i) - quad[i].color = Gfx::Color(1.0f, 0.0f, 1.0f); - - Math::LoadTranslationMatrix(worldMat, Math::Vector(10.0f, 4.5f, 5.0f)); - device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat); - - device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4); - - /* Moving lit cube */ - device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, true); - device->SetRenderState(Gfx::RENDER_STATE_CULLING, true); // Culling (CCW faces) - - device->SetGlobalAmbient(Gfx::Color(0.4f, 0.4f, 0.4f)); - - Gfx::Light light1; - light1.type = Gfx::LIGHT_POINT; - light1.position = Math::Vector(10.0f, 4.5f, 5.0f); - light1.ambient = Gfx::Color(0.2f, 0.2f, 0.2f); - light1.diffuse = Gfx::Color(1.0f, 0.1f, 0.1f); - light1.specular = Gfx::Color(0.0f, 0.0f, 0.0f); - device->SetLight(0, light1); - device->SetLightEnabled(0, true); - - /*Gfx::Light light2; - device->SetLight(1, light2); - device->SetLightEnabled(1, true);*/ - - Gfx::Material material; - material.ambient = Gfx::Color(0.3f, 0.3f, 0.3f); - material.diffuse = Gfx::Color(0.8f, 0.7f, 0.6f); - material.specular = Gfx::Color(0.0f, 0.0f, 0.0f); - device->SetMaterial(material); - - const Gfx::Vertex cube[6][4] = - { - { - // Front - Gfx::Vertex(Math::Vector(-1.0f, -1.0f, -1.0f), Math::Vector( 0.0f, 0.0f, -1.0f)), - Gfx::Vertex(Math::Vector( 1.0f, -1.0f, -1.0f), Math::Vector( 0.0f, 0.0f, -1.0f)), - Gfx::Vertex(Math::Vector(-1.0f, 1.0f, -1.0f), Math::Vector( 0.0f, 0.0f, -1.0f)), - Gfx::Vertex(Math::Vector( 1.0f, 1.0f, -1.0f), Math::Vector( 0.0f, 0.0f, -1.0f)) - }, - - { - // Back - Gfx::Vertex(Math::Vector( 1.0f, -1.0f, 1.0f), Math::Vector( 0.0f, 0.0f, 1.0f)), - Gfx::Vertex(Math::Vector(-1.0f, -1.0f, 1.0f), Math::Vector( 0.0f, 0.0f, 1.0f)), - Gfx::Vertex(Math::Vector( 1.0f, 1.0f, 1.0f), Math::Vector( 0.0f, 0.0f, 1.0f)), - Gfx::Vertex(Math::Vector(-1.0f, 1.0f, 1.0f), Math::Vector( 0.0f, 0.0f, 1.0f)) - }, - - { - // Top - Gfx::Vertex(Math::Vector(-1.0f, 1.0f, -1.0f), Math::Vector( 0.0f, 1.0f, 0.0f)), - Gfx::Vertex(Math::Vector( 1.0f, 1.0f, -1.0f), Math::Vector( 0.0f, 1.0f, 0.0f)), - Gfx::Vertex(Math::Vector(-1.0f, 1.0f, 1.0f), Math::Vector( 0.0f, 1.0f, 0.0f)), - Gfx::Vertex(Math::Vector( 1.0f, 1.0f, 1.0f), Math::Vector( 0.0f, 1.0f, 0.0f)) - }, - - { - // Bottom - Gfx::Vertex(Math::Vector(-1.0f, -1.0f, 1.0f), Math::Vector( 0.0f, -1.0f, 0.0f)), - Gfx::Vertex(Math::Vector( 1.0f, -1.0f, 1.0f), Math::Vector( 0.0f, -1.0f, 0.0f)), - Gfx::Vertex(Math::Vector(-1.0f, -1.0f, -1.0f), Math::Vector( 0.0f, -1.0f, 0.0f)), - Gfx::Vertex(Math::Vector( 1.0f, -1.0f, -1.0f), Math::Vector( 0.0f, -1.0f, 0.0f)) - }, - - { - // Left - Gfx::Vertex(Math::Vector(-1.0f, -1.0f, 1.0f), Math::Vector(-1.0f, 0.0f, 0.0f)), - Gfx::Vertex(Math::Vector(-1.0f, -1.0f, -1.0f), Math::Vector(-1.0f, 0.0f, 0.0f)), - Gfx::Vertex(Math::Vector(-1.0f, 1.0f, 1.0f), Math::Vector(-1.0f, 0.0f, 0.0f)), - Gfx::Vertex(Math::Vector(-1.0f, 1.0f, -1.0f), Math::Vector(-1.0f, 0.0f, 0.0f)) - }, - - { - // Right - Gfx::Vertex(Math::Vector( 1.0f, -1.0f, -1.0f), Math::Vector( 1.0f, 0.0f, 0.0f)), - Gfx::Vertex(Math::Vector( 1.0f, -1.0f, 1.0f), Math::Vector( 1.0f, 0.0f, 0.0f)), - Gfx::Vertex(Math::Vector( 1.0f, 1.0f, -1.0f), Math::Vector( 1.0f, 0.0f, 0.0f)), - Gfx::Vertex(Math::Vector( 1.0f, 1.0f, 1.0f), Math::Vector( 1.0f, 0.0f, 0.0f)) - } - }; - - Math::Matrix cubeTrans; - Math::LoadTranslationMatrix(cubeTrans, Math::Vector(10.0f, 2.0f, 5.0f)); - Math::Matrix cubeRot; - Math::LoadRotationMatrix(cubeRot, Math::Vector(0.0f, 1.0f, 0.0f), CUBE_ORBIT); - Math::Matrix cubeRotInv; - Math::LoadRotationMatrix(cubeRotInv, Math::Vector(0.0f, 1.0f, 0.0f), -CUBE_ORBIT); - Math::Matrix cubeTransRad; - Math::LoadTranslationMatrix(cubeTransRad, Math::Vector(0.0f, 0.0f, 6.0f)); - worldMat = Math::MultiplyMatrices(cubeTransRad, cubeRotInv); - worldMat = Math::MultiplyMatrices(cubeRot, worldMat); - worldMat = Math::MultiplyMatrices(cubeTrans, worldMat); - device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat); - - for (int i = 0; i < 6; ++i) - device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, cube[i], 4); - - device->EndScene(); -} - -void Update() -{ - const float TRANS_SPEED = 6.0f; // units / sec - - GetCurrentTimeStamp(CURR_TIME); - float timeDiff = TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC); - CopyTimeStamp(PREV_TIME, CURR_TIME); - - CUBE_ORBIT += timeDiff * (Math::PI / 4.0f); - - Math::Vector incTrans; - - if (KEYMAP[K_Forward]) - incTrans.z = +TRANS_SPEED * timeDiff; - if (KEYMAP[K_Back]) - incTrans.z = -TRANS_SPEED * timeDiff; - if (KEYMAP[K_Right]) - incTrans.x = +TRANS_SPEED * timeDiff; - if (KEYMAP[K_Left]) - incTrans.x = -TRANS_SPEED * timeDiff; - if (KEYMAP[K_Up]) - incTrans.y = +TRANS_SPEED * timeDiff; - if (KEYMAP[K_Down]) - incTrans.y = -TRANS_SPEED * timeDiff; - - Math::Point rotTrans = Math::RotatePoint(-ROTATION.y, Math::Point(incTrans.x, incTrans.z)); - incTrans.x = rotTrans.x; - incTrans.z = rotTrans.y; - TRANSLATION += incTrans; -} - -void KeyboardDown(SDLKey key) -{ - switch (key) - { - case SDLK_w: - KEYMAP[K_Forward] = true; - break; - case SDLK_s: - KEYMAP[K_Back] = true; - break; - case SDLK_d: - KEYMAP[K_Right] = true; - break; - case SDLK_a: - KEYMAP[K_Left] = true; - break; - case SDLK_z: - KEYMAP[K_Down] = true; - break; - case SDLK_x: - KEYMAP[K_Up] = true; - break; - default: - break; - } -} - -void KeyboardUp(SDLKey key) -{ - switch (key) - { - case SDLK_w: - KEYMAP[K_Forward] = false; - break; - case SDLK_s: - KEYMAP[K_Back] = false; - break; - case SDLK_d: - KEYMAP[K_Right] = false; - break; - case SDLK_a: - KEYMAP[K_Left] = false; - break; - case SDLK_z: - KEYMAP[K_Down] = false; - break; - case SDLK_x: - KEYMAP[K_Up] = false; - break; - default: - break; - } -} - -void MouseMove(int x, int y) -{ - Math::Point currentPos(static_cast(x), static_cast(y)); - - static bool first = true; - if (first || (x < 10) || (y < 10) || (x > 790) || (y > 590)) - { - SDL_WarpMouse(400, 300); - MOUSE_POS_BASE.x = 400; - MOUSE_POS_BASE.y = 300; - ROTATION_BASE = ROTATION; - first = false; - return; - } - - ROTATION.y = ROTATION_BASE.y + (static_cast (x - MOUSE_POS_BASE.x) / 800.0f) * Math::PI; - ROTATION.x = ROTATION_BASE.x + (static_cast (y - MOUSE_POS_BASE.y) / 600.0f) * Math::PI; -} - -int main(int argc, char *argv[]) -{ - CLogger logger; - - PREV_TIME = CreateTimeStamp(); - CURR_TIME = CreateTimeStamp(); - - GetCurrentTimeStamp(PREV_TIME); - GetCurrentTimeStamp(CURR_TIME); - - CInstanceManager iMan; - - // Without any error checking, for simplicity - - SDL_Init(SDL_INIT_VIDEO); - - IMG_Init(IMG_INIT_PNG); - - const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); - - Uint32 videoFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE; - - if (videoInfo->hw_available) - videoFlags |= SDL_HWSURFACE; - else - videoFlags |= SDL_SWSURFACE; - - if (videoInfo->blit_hw) - videoFlags |= SDL_HWACCEL; - - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8); - - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - SDL_Surface *surface = SDL_SetVideoMode(800, 600, 32, videoFlags); - - - SDL_WM_SetCaption("Light Test", "Light Test"); - - //SDL_WM_GrabInput(SDL_GRAB_ON); - SDL_ShowCursor(SDL_DISABLE); - - Gfx::CGLDevice *device = new Gfx::CGLDevice(Gfx::GLDeviceConfig()); - device->Create(); - - Init(device); - - bool done = false; - while (! done) - { - Render(device); - Update(); - - SDL_GL_SwapBuffers(); - - SDL_Event event; - while (SDL_PollEvent(&event)) - { - if (event.type == SDL_QUIT) - { - break; - done = true; - } - else if (event.type == SDL_KEYDOWN) - { - if (event.key.keysym.sym == SDLK_q) - { - done = true; - break; - } - else - KeyboardDown(event.key.keysym.sym); - } - else if (event.type == SDL_KEYUP) - KeyboardUp(event.key.keysym.sym); - else if (event.type == SDL_MOUSEMOTION) - MouseMove(event.motion.x, event.motion.y); - } - - usleep(FRAME_DELAY); - } - - //SDL_WM_GrabInput(SDL_GRAB_OFF); - SDL_ShowCursor(SDL_ENABLE); - - device->Destroy(); - delete device; - - SDL_FreeSurface(surface); - - IMG_Quit(); - - SDL_Quit(); - - DestroyTimeStamp(PREV_TIME); - DestroyTimeStamp(CURR_TIME); - - return 0; -} diff --git a/src/graphics/opengl/test/model_test.cpp b/src/graphics/opengl/test/model_test.cpp deleted file mode 100644 index e951e6e..0000000 --- a/src/graphics/opengl/test/model_test.cpp +++ /dev/null @@ -1,377 +0,0 @@ -#include "app/system.h" -#include "common/logger.h" -#include "common/image.h" -#include "common/iman.h" -#include "graphics/engine/modelfile.h" -#include "graphics/opengl/gldevice.h" -#include "math/geometry.h" - -#include -#include -#include - -#include -#include - -enum KeySlots -{ - K_RotXUp, - K_RotXDown, - K_RotYLeft, - K_RotYRight, - K_Forward, - K_Back, - K_Left, - K_Right, - K_Up, - K_Down, - K_Count -}; -bool KEYMAP[K_Count] = { false }; - -Math::Vector TRANSLATION(0.0f, 0.0f, 30.0f); -Math::Vector ROTATION; - -const int FRAME_DELAY = 5000; - -std::map TEXS; - -SystemTimeStamp *PREV_TIME = NULL, *CURR_TIME = NULL; - -Gfx::Texture GetTexture(const std::string &name) -{ - std::map::iterator it = TEXS.find(name); - if (it == TEXS.end()) - return Gfx::Texture(); - - return (*it).second; -} - -void LoadTexture(Gfx::CGLDevice *device, const std::string &name) -{ - if (name.empty()) - return; - - Gfx::Texture tex = GetTexture(name); - - if (tex.Valid()) - return; - - CImage img; - if (! img.Load(std::string("tex/") + name)) - { - std::string err = img.GetError(); - GetLogger()->Error("Texture not loaded, error: %s!\n", err.c_str()); - } - else - { - Gfx::TextureCreateParams texCreateParams; - texCreateParams.mipmap = true; - if (img.GetData()->surface->format->Amask == 0) - texCreateParams.format = Gfx::TEX_IMG_BGR; - else - texCreateParams.format = Gfx::TEX_IMG_BGRA; - texCreateParams.minFilter = Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR; - texCreateParams.magFilter = Gfx::TEX_MAG_FILTER_LINEAR; - - tex = device->CreateTexture(&img, texCreateParams); - } - - TEXS[name] = tex; -} - -void Init(Gfx::CGLDevice *device, Gfx::CModelFile *model) -{ - std::vector &triangles = model->GetTriangles(); - - for (int i = 0; i < static_cast( triangles.size() ); ++i) - { - LoadTexture(device, triangles[i].tex1Name); - LoadTexture(device, triangles[i].tex2Name); - } - - device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); - device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, true); - device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, true); - device->SetShadeModel(Gfx::SHADE_SMOOTH); - - Gfx::Light light; - light.type = Gfx::LIGHT_DIRECTIONAL; - light.ambient = Gfx::Color(0.4f, 0.4f, 0.4f, 0.0f); - light.diffuse = Gfx::Color(0.8f, 0.8f, 0.8f, 0.0f); - light.specular = Gfx::Color(0.2f, 0.2f, 0.2f, 0.0f); - light.position = Math::Vector(0.0f, 0.0f, -1.0f); - light.direction = Math::Vector(0.0f, 0.0f, 1.0f); - - device->SetGlobalAmbient(Gfx::Color(0.5f, 0.5f, 0.5f, 0.0f)); - device->SetLight(0, light); - device->SetLightEnabled(0, true); -} - -void Render(Gfx::CGLDevice *device, Gfx::CModelFile *modelFile) -{ - device->BeginScene(); - - Math::Matrix persp; - Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.0f), 0.1f, 100.0f); - device->SetTransform(Gfx::TRANSFORM_PROJECTION, persp); - - Math::Matrix id; - id.LoadIdentity(); - device->SetTransform(Gfx::TRANSFORM_WORLD, id); - - Math::Matrix viewMat; - Math::LoadTranslationMatrix(viewMat, TRANSLATION); - Math::Matrix rot; - Math::LoadRotationXZYMatrix(rot, ROTATION); - viewMat = Math::MultiplyMatrices(viewMat, rot); - device->SetTransform(Gfx::TRANSFORM_VIEW, viewMat); - - std::vector &triangles = modelFile->GetTriangles(); - - Gfx::VertexTex2 tri[3]; - - for (int i = 0; i < static_cast( triangles.size() ); ++i) - { - device->SetTexture(0, GetTexture(triangles[i].tex1Name)); - device->SetTexture(1, GetTexture(triangles[i].tex2Name)); - device->SetTextureEnabled(0, true); - device->SetTextureEnabled(1, true); - - device->SetMaterial(triangles[i].material); - - tri[0] = triangles[i].p1; - tri[1] = triangles[i].p2; - tri[2] = triangles[i].p3; - - device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, tri, 3); - } - - device->EndScene(); -} - -void Update() -{ - const float ROT_SPEED = 80.0f * Math::DEG_TO_RAD; // rad / sec - const float TRANS_SPEED = 3.0f; // units / sec - - GetCurrentTimeStamp(CURR_TIME); - float timeDiff = TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC); - CopyTimeStamp(PREV_TIME, CURR_TIME); - - if (KEYMAP[K_RotYLeft]) - ROTATION.y -= ROT_SPEED * timeDiff; - if (KEYMAP[K_RotYRight]) - ROTATION.y += ROT_SPEED * timeDiff; - if (KEYMAP[K_RotXDown]) - ROTATION.x -= ROT_SPEED * timeDiff; - if (KEYMAP[K_RotXUp]) - ROTATION.x += ROT_SPEED * timeDiff; - - if (KEYMAP[K_Forward]) - TRANSLATION.z -= TRANS_SPEED * timeDiff; - if (KEYMAP[K_Back]) - TRANSLATION.z += TRANS_SPEED * timeDiff; - if (KEYMAP[K_Left]) - TRANSLATION.x += TRANS_SPEED * timeDiff; - if (KEYMAP[K_Right]) - TRANSLATION.x -= TRANS_SPEED * timeDiff; - if (KEYMAP[K_Up]) - TRANSLATION.y += TRANS_SPEED * timeDiff; - if (KEYMAP[K_Down]) - TRANSLATION.y -= TRANS_SPEED * timeDiff; -} - -void KeyboardDown(SDLKey key) -{ - switch (key) - { - case SDLK_LEFT: - KEYMAP[K_RotYLeft] = true; - break; - case SDLK_RIGHT: - KEYMAP[K_RotYRight] = true; - break; - case SDLK_UP: - KEYMAP[K_RotXUp] = true; - break; - case SDLK_DOWN: - KEYMAP[K_RotXDown] = true; - break; - case SDLK_w: - KEYMAP[K_Forward] = true; - break; - case SDLK_s: - KEYMAP[K_Back] = true; - break; - case SDLK_a: - KEYMAP[K_Left] = true; - break; - case SDLK_d: - KEYMAP[K_Right] = true; - break; - case SDLK_z: - KEYMAP[K_Down] = true; - break; - case SDLK_x: - KEYMAP[K_Up] = true; - break; - default: - break; - } -} - -void KeyboardUp(SDLKey key) -{ - switch (key) - { - case SDLK_LEFT: - KEYMAP[K_RotYLeft] = false; - break; - case SDLK_RIGHT: - KEYMAP[K_RotYRight] = false; - break; - case SDLK_UP: - KEYMAP[K_RotXUp] = false; - break; - case SDLK_DOWN: - KEYMAP[K_RotXDown] = false; - break; - case SDLK_w: - KEYMAP[K_Forward] = false; - break; - case SDLK_s: - KEYMAP[K_Back] = false; - break; - case SDLK_a: - KEYMAP[K_Left] = false; - break; - case SDLK_d: - KEYMAP[K_Right] = false; - break; - case SDLK_z: - KEYMAP[K_Down] = false; - break; - case SDLK_x: - KEYMAP[K_Up] = false; - break; - default: - break; - } -} - -int main(int argc, char *argv[]) -{ - CLogger logger; - - PREV_TIME = CreateTimeStamp(); - CURR_TIME = CreateTimeStamp(); - - GetCurrentTimeStamp(PREV_TIME); - GetCurrentTimeStamp(CURR_TIME); - - if (argc != 3) - { - std::cerr << "Usage: " << argv[0] << "{mod|dxf} model_file" << std::endl; - return 1; - } - - CInstanceManager iMan; - - Gfx::CModelFile *modelFile = new Gfx::CModelFile(&iMan); - if (std::string(argv[1]) == "mod") - { - if (! modelFile->ReadModel(argv[2], false, false)) - { - std::cerr << "Error reading MOD: " << modelFile->GetError() << std::endl; - return 1; - } - } - else if (std::string(argv[1]) == "dxf") - { - if (! modelFile->ReadDXF(argv[2], 0.0f, 0.0f)) - { - std::cerr << "Error reading DXF: " << modelFile->GetError() << std::endl; - return 1; - } - } - else - { - std::cerr << "Usage: " << argv[0] << "{mod|dxf} model_file" << std::endl; - return 1; - } - - // Without any error checking, for simplicity - - SDL_Init(SDL_INIT_VIDEO); - - IMG_Init(IMG_INIT_PNG); - - const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); - - Uint32 videoFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE; - - if (videoInfo->hw_available) - videoFlags |= SDL_HWSURFACE; - else - videoFlags |= SDL_SWSURFACE; - - if (videoInfo->blit_hw) - videoFlags |= SDL_HWACCEL; - - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8); - - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - SDL_Surface *surface = SDL_SetVideoMode(800, 600, 32, videoFlags); - - - SDL_WM_SetCaption("Model Test", "Model Test"); - - Gfx::CGLDevice *device = new Gfx::CGLDevice(Gfx::GLDeviceConfig()); - device->Create(); - - Init(device, modelFile); - - bool done = false; - while (! done) - { - Render(device, modelFile); - Update(); - - SDL_GL_SwapBuffers(); - - SDL_Event event; - SDL_PollEvent(&event); - if (event.type == SDL_QUIT) - done = true; - else if (event.type == SDL_KEYDOWN) - KeyboardDown(event.key.keysym.sym); - else if (event.type == SDL_KEYUP) - KeyboardUp(event.key.keysym.sym); - - usleep(FRAME_DELAY); - } - - delete modelFile; - - device->Destroy(); - delete device; - - SDL_FreeSurface(surface); - - IMG_Quit(); - - SDL_Quit(); - - DestroyTimeStamp(PREV_TIME); - DestroyTimeStamp(CURR_TIME); - - return 0; -} diff --git a/src/graphics/opengl/test/tex1.png b/src/graphics/opengl/test/tex1.png deleted file mode 100644 index 46c68a0..0000000 Binary files a/src/graphics/opengl/test/tex1.png and /dev/null differ diff --git a/src/graphics/opengl/test/tex2.png b/src/graphics/opengl/test/tex2.png deleted file mode 100644 index ebdae0d..0000000 Binary files a/src/graphics/opengl/test/tex2.png and /dev/null differ diff --git a/src/graphics/opengl/test/texture_test.cpp b/src/graphics/opengl/test/texture_test.cpp deleted file mode 100644 index d771927..0000000 --- a/src/graphics/opengl/test/texture_test.cpp +++ /dev/null @@ -1,192 +0,0 @@ -#include "common/logger.h" -#include "common/image.h" -#include "graphics/opengl/gldevice.h" -#include "math/geometry.h" - -#include -#include -#include - - -void Init(Gfx::CGLDevice *device) -{ - device->SetShadeModel(Gfx::SHADE_SMOOTH); - - device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false); - - device->SetTextureEnabled(0, true); - device->SetTextureEnabled(1, true); - - CImage img1; - if (! img1.Load("tex1.png")) - { - std::string err = img1.GetError(); - GetLogger()->Error("texture 1 not loaded, error: %d!\n", err.c_str()); - } - CImage img2; - if (! img2.Load("tex2.png")) - { - std::string err = img2.GetError(); - GetLogger()->Error("texture 2 not loaded, error: %d!\n", err.c_str()); - } - - Gfx::TextureCreateParams tex1CreateParams; - tex1CreateParams.mipmap = true; - tex1CreateParams.format = Gfx::TEX_IMG_RGBA; - tex1CreateParams.minFilter = Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR; - tex1CreateParams.magFilter = Gfx::TEX_MAG_FILTER_LINEAR; - - Gfx::TextureCreateParams tex2CreateParams; - tex2CreateParams.mipmap = true; - tex2CreateParams.format = Gfx::TEX_IMG_RGBA; - tex2CreateParams.minFilter = Gfx::TEX_MIN_FILTER_NEAREST_MIPMAP_NEAREST; - tex2CreateParams.magFilter = Gfx::TEX_MAG_FILTER_NEAREST; - - Gfx::Texture tex1 = device->CreateTexture(&img1, tex1CreateParams); - Gfx::Texture tex2 = device->CreateTexture(&img2, tex2CreateParams); - - device->SetTexture(0, tex1); - device->SetTexture(1, tex2); -} - -void Render(Gfx::CGLDevice *device) -{ - device->BeginScene(); - - Math::Matrix ortho; - Math::LoadOrthoProjectionMatrix(ortho, -10, 10, -10, 10); - device->SetTransform(Gfx::TRANSFORM_PROJECTION, ortho); - - Math::Matrix id; - id.LoadIdentity(); - - device->SetTransform(Gfx::TRANSFORM_WORLD, id); - device->SetTransform(Gfx::TRANSFORM_VIEW, id); - - static Gfx::VertexTex2 quad[] = - { - Gfx::VertexTex2(Math::Vector(-2.0f, 2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 0.0f), Math::Point(0.0f, 0.0f)), - Gfx::VertexTex2(Math::Vector( 2.0f, 2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 0.0f), Math::Point(1.0f, 0.0f)), - Gfx::VertexTex2(Math::Vector( 2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 1.0f), Math::Point(1.0f, 1.0f)), - - Gfx::VertexTex2(Math::Vector( 2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(1.0f, 1.0f), Math::Point(1.0f, 1.0f)), - Gfx::VertexTex2(Math::Vector(-2.0f, -2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 1.0f), Math::Point(0.0f, 1.0f)), - Gfx::VertexTex2(Math::Vector(-2.0f, 2.0f, 0.0f), Math::Vector(), Math::Point(0.0f, 0.0f), Math::Point(0.0f, 0.0f)), - }; - - Gfx::TextureStageParams tex1StageParams; - tex1StageParams.colorOperation = Gfx::TEX_MIX_OPER_DEFAULT; - tex1StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT; - device->SetTextureStageParams(0, tex1StageParams); - - Gfx::TextureStageParams tex2StageParams; - tex2StageParams.colorOperation = Gfx::TEX_MIX_OPER_DEFAULT; - tex2StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT; - device->SetTextureStageParams(1, tex2StageParams); - - Math::Matrix t; - Math::LoadTranslationMatrix(t, Math::Vector(-4.0f, 4.0f, 0.0f)); - device->SetTransform(Gfx::TRANSFORM_VIEW, t); - - device->SetTextureEnabled(0, true); - device->SetTextureEnabled(1, false); - - device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6); - - Math::LoadTranslationMatrix(t, Math::Vector( 4.0f, 4.0f, 0.0f)); - device->SetTransform(Gfx::TRANSFORM_VIEW, t); - - device->SetTextureEnabled(0, false); - device->SetTextureEnabled(1, true); - - device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6); - - Math::LoadTranslationMatrix(t, Math::Vector( 0.0f, -4.0f, 0.0f)); - device->SetTransform(Gfx::TRANSFORM_VIEW, t); - - device->SetTextureEnabled(0, true); - device->SetTextureEnabled(1, true); - - tex1StageParams.colorOperation = Gfx::TEX_MIX_OPER_DEFAULT; - tex1StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT; - device->SetTextureStageParams(0, tex1StageParams); - - tex2StageParams.colorOperation = Gfx::TEX_MIX_OPER_ADD; - tex2StageParams.colorArg1 = Gfx::TEX_MIX_ARG_COMPUTED_COLOR; - tex2StageParams.colorArg2 = Gfx::TEX_MIX_ARG_TEXTURE; - tex2StageParams.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT; - device->SetTextureStageParams(1, tex2StageParams); - - device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6); - - device->EndScene(); -} - -int main() -{ - CLogger(); - - // Without any error checking, for simplicity - - SDL_Init(SDL_INIT_VIDEO); - - IMG_Init(IMG_INIT_PNG); - - const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); - - Uint32 videoFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE; - - if (videoInfo->hw_available) - videoFlags |= SDL_HWSURFACE; - else - videoFlags |= SDL_SWSURFACE; - - if (videoInfo->blit_hw) - videoFlags |= SDL_HWACCEL; - - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8); - - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - SDL_Surface *surface = SDL_SetVideoMode(800, 600, 32, videoFlags); - - - SDL_WM_SetCaption("Texture Test", "Texture Test"); - - Gfx::CGLDevice *device = new Gfx::CGLDevice(Gfx::GLDeviceConfig()); - device->Create(); - - Init(device); - - bool done = false; - while (! done) - { - Render(device); - - SDL_GL_SwapBuffers(); - - SDL_Event event; - SDL_PollEvent(&event); - if (event.type == SDL_QUIT) - done = true; - - usleep(10000); - } - - device->Destroy(); - delete device; - - SDL_FreeSurface(surface); - - IMG_Quit(); - - SDL_Quit(); - - return 0; -} diff --git a/src/graphics/opengl/test/transform_test.cpp b/src/graphics/opengl/test/transform_test.cpp deleted file mode 100644 index cddd1b8..0000000 --- a/src/graphics/opengl/test/transform_test.cpp +++ /dev/null @@ -1,339 +0,0 @@ -#include "app/system.h" -#include "common/logger.h" -#include "common/image.h" -#include "common/iman.h" -#include "graphics/opengl/gldevice.h" -#include "math/geometry.h" - -#include -#include -#include - -#include -#include - -enum KeySlots -{ - K_Forward, - K_Back, - K_Left, - K_Right, - K_Up, - K_Down, - K_Count -}; -bool KEYMAP[K_Count] = { false }; - -Math::Point MOUSE_POS_BASE; - -Math::Vector TRANSLATION(0.0f, 2.0f, 0.0f); -Math::Vector ROTATION, ROTATION_BASE; - -const int FRAME_DELAY = 5000; - -SystemTimeStamp *PREV_TIME = NULL, *CURR_TIME = NULL; - -void Init(Gfx::CGLDevice *device) -{ - device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, true); - device->SetShadeModel(Gfx::SHADE_SMOOTH); -} - -void Render(Gfx::CGLDevice *device) -{ - device->BeginScene(); - - Math::Matrix persp; - Math::LoadProjectionMatrix(persp, Math::PI / 4.0f, (800.0f) / (600.0f), 0.1f, 100.0f); - device->SetTransform(Gfx::TRANSFORM_PROJECTION, persp); - - - Math::Matrix viewMat; - Math::Matrix mat; - - viewMat.LoadIdentity(); - - Math::LoadRotationXMatrix(mat, -ROTATION.x); - viewMat = Math::MultiplyMatrices(viewMat, mat); - - Math::LoadRotationYMatrix(mat, -ROTATION.y); - viewMat = Math::MultiplyMatrices(viewMat, mat); - - Math::LoadTranslationMatrix(mat, -TRANSLATION); - viewMat = Math::MultiplyMatrices(viewMat, mat); - - device->SetTransform(Gfx::TRANSFORM_VIEW, viewMat); - - - Math::Matrix worldMat; - worldMat.LoadIdentity(); - device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat); - - Gfx::VertexCol line[2] = { Gfx::VertexCol() }; - - for (int x = -40; x <= 40; ++x) - { - line[0].color = Gfx::Color(0.7f + x / 120.0f, 0.0f, 0.0f); - line[0].coord.z = -40; - line[0].coord.x = x; - line[1].color = Gfx::Color(0.7f + x / 120.0f, 0.0f, 0.0f); - line[1].coord.z = 40; - line[1].coord.x = x; - device->DrawPrimitive(Gfx::PRIMITIVE_LINES, line, 2); - } - - for (int z = -40; z <= 40; ++z) - { - line[0].color = Gfx::Color(0.0f, 0.7f + z / 120.0f, 0.0f); - line[0].coord.z = z; - line[0].coord.x = -40; - line[1].color = Gfx::Color(0.0f, 0.7f + z / 120.0f, 0.0f); - line[1].coord.z = z; - line[1].coord.x = 40; - device->DrawPrimitive(Gfx::PRIMITIVE_LINES, line, 2); - } - - - Gfx::VertexCol quad[6] = { Gfx::VertexCol() }; - - for (int i = 0; i < 6; ++i) - quad[i].color = Gfx::Color(1.0f, 1.0f, 0.0f); - - quad[0].coord = Math::Vector(-1.0f, -1.0f, 0.0f); - quad[1].coord = Math::Vector( 1.0f, -1.0f, 0.0f); - quad[2].coord = Math::Vector( 1.0f, 1.0f, 0.0f); - quad[3].coord = Math::Vector( 1.0f, 1.0f, 0.0f); - quad[4].coord = Math::Vector(-1.0f, 1.0f, 0.0f); - quad[5].coord = Math::Vector(-1.0f, -1.0f, 0.0f); - - Math::LoadTranslationMatrix(worldMat, Math::Vector(40.0f, 2.0f, 40.0f)); - device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat); - - device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6); - - for (int i = 0; i < 6; ++i) - quad[i].color = Gfx::Color(0.0f, 1.0f, 1.0f); - - Math::LoadTranslationMatrix(worldMat, Math::Vector(-40.0f, 2.0f, -40.0f)); - device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat); - - device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6); - - for (int i = 0; i < 6; ++i) - quad[i].color = Gfx::Color(1.0f, 0.0f, 1.0f); - - Math::LoadTranslationMatrix(worldMat, Math::Vector(0.0f, 10.0f, 0.0f)); - device->SetTransform(Gfx::TRANSFORM_WORLD, worldMat); - - device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, quad, 6); - - device->EndScene(); -} - -void Update() -{ - const float TRANS_SPEED = 6.0f; // units / sec - - GetCurrentTimeStamp(CURR_TIME); - float timeDiff = TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC); - CopyTimeStamp(PREV_TIME, CURR_TIME); - - Math::Vector incTrans; - - if (KEYMAP[K_Forward]) - incTrans.z = +TRANS_SPEED * timeDiff; - if (KEYMAP[K_Back]) - incTrans.z = -TRANS_SPEED * timeDiff; - if (KEYMAP[K_Right]) - incTrans.x = +TRANS_SPEED * timeDiff; - if (KEYMAP[K_Left]) - incTrans.x = -TRANS_SPEED * timeDiff; - if (KEYMAP[K_Up]) - incTrans.y = +TRANS_SPEED * timeDiff; - if (KEYMAP[K_Down]) - incTrans.y = -TRANS_SPEED * timeDiff; - - Math::Point rotTrans = Math::RotatePoint(-ROTATION.y, Math::Point(incTrans.x, incTrans.z)); - incTrans.x = rotTrans.x; - incTrans.z = rotTrans.y; - TRANSLATION += incTrans; -} - -void KeyboardDown(SDLKey key) -{ - switch (key) - { - case SDLK_w: - KEYMAP[K_Forward] = true; - break; - case SDLK_s: - KEYMAP[K_Back] = true; - break; - case SDLK_d: - KEYMAP[K_Right] = true; - break; - case SDLK_a: - KEYMAP[K_Left] = true; - break; - case SDLK_z: - KEYMAP[K_Down] = true; - break; - case SDLK_x: - KEYMAP[K_Up] = true; - break; - default: - break; - } -} - -void KeyboardUp(SDLKey key) -{ - switch (key) - { - case SDLK_w: - KEYMAP[K_Forward] = false; - break; - case SDLK_s: - KEYMAP[K_Back] = false; - break; - case SDLK_d: - KEYMAP[K_Right] = false; - break; - case SDLK_a: - KEYMAP[K_Left] = false; - break; - case SDLK_z: - KEYMAP[K_Down] = false; - break; - case SDLK_x: - KEYMAP[K_Up] = false; - break; - default: - break; - } -} - -void MouseMove(int x, int y) -{ - Math::Point currentPos(static_cast(x), static_cast(y)); - - static bool first = true; - if (first || (x < 10) || (y < 10) || (x > 790) || (y > 590)) - { - SDL_WarpMouse(400, 300); - MOUSE_POS_BASE.x = 400; - MOUSE_POS_BASE.y = 300; - ROTATION_BASE = ROTATION; - first = false; - return; - } - - ROTATION.y = ROTATION_BASE.y + (static_cast (x - MOUSE_POS_BASE.x) / 800.0f) * Math::PI; - ROTATION.x = ROTATION_BASE.x + (static_cast (y - MOUSE_POS_BASE.y) / 600.0f) * Math::PI; -} - -int main(int argc, char *argv[]) -{ - CLogger logger; - - PREV_TIME = CreateTimeStamp(); - CURR_TIME = CreateTimeStamp(); - - GetCurrentTimeStamp(PREV_TIME); - GetCurrentTimeStamp(CURR_TIME); - - CInstanceManager iMan; - - // Without any error checking, for simplicity - - SDL_Init(SDL_INIT_VIDEO); - - IMG_Init(IMG_INIT_PNG); - - const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); - - Uint32 videoFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE; - - if (videoInfo->hw_available) - videoFlags |= SDL_HWSURFACE; - else - videoFlags |= SDL_SWSURFACE; - - if (videoInfo->blit_hw) - videoFlags |= SDL_HWACCEL; - - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8); - - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - SDL_Surface *surface = SDL_SetVideoMode(800, 600, 32, videoFlags); - - - SDL_WM_SetCaption("Transform Test", "Transform Test"); - - //SDL_WM_GrabInput(SDL_GRAB_ON); - SDL_ShowCursor(SDL_DISABLE); - - Gfx::CGLDevice *device = new Gfx::CGLDevice(Gfx::GLDeviceConfig()); - device->Create(); - - Init(device); - - bool done = false; - while (! done) - { - Render(device); - Update(); - - SDL_GL_SwapBuffers(); - - SDL_Event event; - while (SDL_PollEvent(&event)) - { - if (event.type == SDL_QUIT) - { - break; - done = true; - } - else if (event.type == SDL_KEYDOWN) - { - if (event.key.keysym.sym == SDLK_q) - { - done = true; - break; - } - else - KeyboardDown(event.key.keysym.sym); - } - else if (event.type == SDL_KEYUP) - KeyboardUp(event.key.keysym.sym); - else if (event.type == SDL_MOUSEMOTION) - MouseMove(event.motion.x, event.motion.y); - } - - usleep(FRAME_DELAY); - } - - //SDL_WM_GrabInput(SDL_GRAB_OFF); - SDL_ShowCursor(SDL_ENABLE); - - device->Destroy(); - delete device; - - SDL_FreeSurface(surface); - - IMG_Quit(); - - SDL_Quit(); - - DestroyTimeStamp(PREV_TIME); - DestroyTimeStamp(CURR_TIME); - - return 0; -} -- cgit v1.2.3-1-g7c22 From 6f64770714c20a24a2edfd55777e05a047e61d0e Mon Sep 17 00:00:00 2001 From: erihel Date: Sat, 9 Feb 2013 21:00:07 +0100 Subject: * Fixes to ingame editor * Fixes to editor window. It's now possible to resize, move and press buttons --- src/graphics/engine/text.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index da1a290..dfe7a3c 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -682,11 +682,13 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::P int width = 1; if (ch.c1 > 0 && ch.c1 < 32) { // FIXME add support for chars with code 9 10 23 - ch.c1 = ' '; + if (ch.c1 == '\t') { + ch.c1 = ':'; + } else { + ch.c1 = ' '; + } ch.c2 = 0; ch.c3 = 0; - if (ch.c1 == '\t') - width = 4; } auto it = cf->cache.find(ch); -- cgit v1.2.3-1-g7c22 From 3f6a6a9eefc54452dc99a15f67bdfabc7e19788b Mon Sep 17 00:00:00 2001 From: erihel Date: Sat, 9 Feb 2013 23:49:38 +0100 Subject: * Syntax highlighting in cbot editor (needs to be tested) --- src/graphics/engine/text.cpp | 23 ++++++++++++----------- src/graphics/engine/text.h | 12 ++++++------ 2 files changed, 18 insertions(+), 17 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index dfe7a3c..48af081 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -153,7 +153,7 @@ void CText::FlushCache() m_lastCachedFont = nullptr; } -void CText::DrawText(const std::string &text, std::map &format, +void CText::DrawText(const std::string &text, std::vector::iterator format, float size, Math::Point pos, float width, TextAlign align, int eol, Color color) { @@ -197,7 +197,7 @@ void CText::DrawText(const std::string &text, FontType font, DrawString(text, font, size, pos, width, eol, color); } -void CText::SizeText(const std::string &text, std::map &format, +void CText::SizeText(const std::string &text, std::vector::iterator format, float size, Math::Point pos, TextAlign align, Math::Point &start, Math::Point &end) { @@ -281,7 +281,7 @@ float CText::GetHeight(FontType font, float size) float CText::GetStringWidth(const std::string &text, - std::map &format, float size) + std::vector::iterator format, float size) { float width = 0.0f; unsigned int index = 0; @@ -289,7 +289,7 @@ float CText::GetStringWidth(const std::string &text, while (index < text.length()) { FontType font = FONT_COLOBOT; - if (format.count(fmtIndex)) + //if (format.size() > fmtIndex) font = static_cast(format[fmtIndex] & FONT_MASK_FONT); UTF8Char ch; @@ -347,7 +347,7 @@ float CText::GetCharWidth(UTF8Char ch, FontType font, float size, float offset) } -int CText::Justify(const std::string &text, std::map &format, +int CText::Justify(const std::string &text, std::vector::iterator format, float size, float width) { float pos = 0.0f; @@ -357,7 +357,7 @@ int CText::Justify(const std::string &text, std::map while (index < text.length()) { FontType font = FONT_COLOBOT; - if (format.count(fmtIndex)) + //if (format.size() > fmtIndex) font = static_cast(format[fmtIndex] & FONT_MASK_FONT); UTF8Char ch; @@ -431,7 +431,7 @@ int CText::Justify(const std::string &text, FontType font, float size, float wid return index; } -int CText::Detect(const std::string &text, std::map &format, +int CText::Detect(const std::string &text, std::vector::iterator format, float size, float offset) { float pos = 0.0f; @@ -440,7 +440,7 @@ int CText::Detect(const std::string &text, std::map while (index < text.length()) { FontType font = FONT_COLOBOT; - if (format.count(fmtIndex)) + //if (format.size() > fmtIndex) font = static_cast(format[fmtIndex] & FONT_MASK_FONT); // TODO: if (font == FONT_BUTTON) @@ -504,7 +504,7 @@ int CText::Detect(const std::string &text, FontType font, float size, float offs return index; } -void CText::DrawString(const std::string &text, std::map &format, +void CText::DrawString(const std::string &text, std::vector::iterator format, float size, Math::Point pos, float width, int eol, Color color) { m_engine->SetState(ENG_RSTATE_TEXT); @@ -518,7 +518,7 @@ void CText::DrawString(const std::string &text, std::map fmtIndex) font = static_cast(format[fmtIndex] & FONT_MASK_FONT); // TODO: if (font == FONT_BUTTON) @@ -684,6 +684,7 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::P if (ch.c1 > 0 && ch.c1 < 32) { // FIXME add support for chars with code 9 10 23 if (ch.c1 == '\t') { ch.c1 = ':'; + width = 4; } else { ch.c1 = ' '; } @@ -708,7 +709,7 @@ void CText::DrawCharAndAdjustPos(UTF8Char ch, FontType font, float size, Math::P } Math::Point p1(pos.x, pos.y + tex.charSize.y - tex.texSize.y); - Math::Point p2(pos.x + tex.texSize.x * width, pos.y + tex.charSize.y); + Math::Point p2(pos.x + tex.texSize.x, pos.y + tex.charSize.y); Math::Vector n(0.0f, 0.0f, -1.0f); // normal diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h index 57fad43..e7578df 100644 --- a/src/graphics/engine/text.h +++ b/src/graphics/engine/text.h @@ -244,7 +244,7 @@ public: void FlushCache(); //! Draws text (multi-format) - void DrawText(const std::string &text, std::map &format, + void DrawText(const std::string &text, std::vector::iterator format, float size, Math::Point pos, float width, TextAlign align, int eol, Color color = Color(0.0f, 0.0f, 0.0f, 1.0f)); //! Draws text (one font) @@ -253,7 +253,7 @@ public: int eol, Color color = Color(0.0f, 0.0f, 0.0f, 1.0f)); //! Calculates dimensions for text (multi-format) - void SizeText(const std::string &text, std::map &format, + void SizeText(const std::string &text, std::vector::iterator format, float size, Math::Point pos, TextAlign align, Math::Point &start, Math::Point &end); //! Calculates dimensions for text (one font) @@ -270,20 +270,20 @@ public: //! Returns width of string (multi-format) TEST_VIRTUAL float GetStringWidth(const std::string &text, - std::map &format, float size); + std::vector::iterator format, float size); //! Returns width of string (single font) TEST_VIRTUAL float GetStringWidth(const std::string &text, FontType font, float size); //! Returns width of single character TEST_VIRTUAL float GetCharWidth(UTF8Char ch, FontType font, float size, float offset); //! Justifies a line of text (multi-format) - int Justify(const std::string &text, std::map &format, + int Justify(const std::string &text, std::vector::iterator format, float size, float width); //! Justifies a line of text (one font) int Justify(const std::string &text, FontType font, float size, float width); //! Returns the most suitable position to a given offset (multi-format) - int Detect(const std::string &text, std::map &format, + int Detect(const std::string &text, std::vector::iterator format, float size, float offset); //! Returns the most suitable position to a given offset (one font) int Detect(const std::string &text, FontType font, float size, float offset); @@ -292,7 +292,7 @@ protected: CachedFont* GetOrOpenFont(FontType type, float size); CharTexture CreateCharTexture(UTF8Char ch, CachedFont* font); - void DrawString(const std::string &text, std::map &format, + void DrawString(const std::string &text, std::vector::iterator format, float size, Math::Point pos, float width, int eol, Color color); void DrawString(const std::string &text, FontType font, float size, Math::Point pos, float width, int eol, Color color); -- cgit v1.2.3-1-g7c22 From d3106c73ff6239e184dc5a83609f7d08391e6148 Mon Sep 17 00:00:00 2001 From: adiblol Date: Mon, 11 Feb 2013 22:59:51 +0100 Subject: More camera distance from AlienQueen --- src/graphics/engine/camera.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/graphics') diff --git a/src/graphics/engine/camera.cpp b/src/graphics/engine/camera.cpp index d85194e..e5dd1e5 100644 --- a/src/graphics/engine/camera.cpp +++ b/src/graphics/engine/camera.cpp @@ -315,6 +315,7 @@ void CCamera::SetType(CameraType type) if ( oType == OBJECT_PARA ) m_backDist = 180.0f; if ( oType == OBJECT_SAFE ) m_backDist = 50.0f; if ( oType == OBJECT_HUSTON ) m_backDist = 120.0f; + if ( oType == OBJECT_MOTHER ) m_backDist = 55.0f; m_backMin = m_backDist/3.0f; if ( oType == OBJECT_HUMAN ) m_backMin = 10.0f; -- cgit v1.2.3-1-g7c22 From 34e758a9dae489f838360a6a8105b4008b91d62f Mon Sep 17 00:00:00 2001 From: PaweX Date: Wed, 13 Feb 2013 02:44:43 +0100 Subject: Additional parameter for function aim(x, y) --- src/graphics/engine/camera.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/camera.cpp b/src/graphics/engine/camera.cpp index e5dd1e5..8026302 100644 --- a/src/graphics/engine/camera.cpp +++ b/src/graphics/engine/camera.cpp @@ -328,8 +328,8 @@ void CCamera::SetType(CameraType type) if ( oType == OBJECT_HUSTON ) m_backMin = 80.0f; } - if ( type != CAM_TYPE_ONBOARD && m_cameraObj != 0 ) - m_cameraObj->SetGunGoalH(0.0f); // puts the cannon right + //if ( type != CAM_TYPE_ONBOARD && m_cameraObj != 0 ) + // m_cameraObj->SetGunGoalH(0.0f); // puts the cannon right if ( type == CAM_TYPE_ONBOARD ) m_focus = 1.50f; // Wide -- cgit v1.2.3-1-g7c22 From 001d37b257b126dd6ef1dced70f94ff3d2806d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Dziwi=C5=84ski?= Date: Sat, 16 Feb 2013 22:37:43 +0100 Subject: CInstanceManager refactoring * removed classes managed by CInstanceManager except for CObject, CPyro, CBrain and CPhysics because of dependencies * refactored instance searching to use existing singleton instances of CApplication, CEngine and CRobotMain and calling their getter functions --- src/graphics/engine/camera.cpp | 26 +++++++---- src/graphics/engine/camera.h | 6 +-- src/graphics/engine/cloud.cpp | 19 +++----- src/graphics/engine/cloud.h | 11 ++--- src/graphics/engine/engine.cpp | 89 ++++++++++++++++++++++++++---------- src/graphics/engine/engine.h | 31 +++++++++---- src/graphics/engine/lightman.cpp | 9 +--- src/graphics/engine/lightman.h | 3 +- src/graphics/engine/lightning.cpp | 22 +++++---- src/graphics/engine/lightning.h | 4 +- src/graphics/engine/modelfile.cpp | 1 - src/graphics/engine/modelmanager.cpp | 2 +- src/graphics/engine/particle.cpp | 29 ++++++------ src/graphics/engine/particle.h | 4 +- src/graphics/engine/planet.cpp | 8 +--- src/graphics/engine/planet.h | 5 +- src/graphics/engine/pyro.cpp | 34 ++++++++------ src/graphics/engine/pyro.h | 4 +- src/graphics/engine/terrain.cpp | 13 +++--- src/graphics/engine/terrain.h | 6 +-- src/graphics/engine/text.cpp | 11 ++--- src/graphics/engine/text.h | 6 +-- src/graphics/engine/water.cpp | 28 ++++++------ src/graphics/engine/water.h | 8 ++-- 24 files changed, 197 insertions(+), 182 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/camera.cpp b/src/graphics/engine/camera.cpp index 8026302..f65a59a 100644 --- a/src/graphics/engine/camera.cpp +++ b/src/graphics/engine/camera.cpp @@ -30,6 +30,7 @@ #include "math/geometry.h" #include "object/object.h" +#include "object/robotmain.h" #include "physics/physics.h" @@ -54,14 +55,13 @@ void SetTransparency(CObject* obj, float value) -CCamera::CCamera(CInstanceManager* iMan) +CCamera::CCamera() { - m_iMan = iMan; - m_iMan->AddInstance(CLASS_CAMERA, this); + m_engine = CEngine::GetInstancePointer(); + m_water = m_engine->GetWater(); - m_engine = static_cast ( m_iMan->SearchInstance(CLASS_ENGINE) ); - m_terrain = static_cast( m_iMan->SearchInstance(CLASS_TERRAIN) ); - m_water = static_cast ( m_iMan->SearchInstance(CLASS_WATER) ); + m_main = CRobotMain::GetInstancePointer(); + m_terrain = m_main->GetTerrain(); m_type = CAM_TYPE_FREE; m_smooth = CAM_SMOOTH_NORM; @@ -227,11 +227,13 @@ void CCamera::SetType(CameraType type) m_remotePan = 0.0f; m_remoteZoom = 0.0f; + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + if ( (m_type == CAM_TYPE_BACK) && m_transparency ) { for (int i = 0; i < 1000000; i++) { - CObject* obj = static_cast( m_iMan->SearchInstance(CLASS_OBJECT, i) ); + CObject* obj = static_cast( iMan->SearchInstance(CLASS_OBJECT, i) ); if (obj == NULL) break; @@ -881,9 +883,11 @@ bool CCamera::IsCollisionBack(Math::Vector &eye, Math::Vector lookat) m_transparency = false; + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + for (int i = 0 ;i < 1000000; i++) { - CObject *obj = static_cast( m_iMan->SearchInstance(CLASS_OBJECT, i) ); + CObject *obj = static_cast( iMan->SearchInstance(CLASS_OBJECT, i) ); if (obj == NULL) break; if (obj->GetTruck()) continue; // battery or cargo? @@ -958,9 +962,11 @@ bool CCamera::IsCollisionBack(Math::Vector &eye, Math::Vector lookat) bool CCamera::IsCollisionFix(Math::Vector &eye, Math::Vector lookat) { + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + for (int i = 0; i < 1000000; i++) { - CObject *obj = static_cast( m_iMan->SearchInstance(CLASS_OBJECT, i) ); + CObject *obj = static_cast( iMan->SearchInstance(CLASS_OBJECT, i) ); if (obj == NULL) break; if (obj == m_cameraObj) continue; @@ -1650,7 +1656,7 @@ Math::Vector CCamera::ExcludeObject(Math::Vector eye, Math::Vector lookat, /* for (int i = 0; i < 1000000; i++) { - CObject* obj = static_cast( m_iMan->SearchInstance(CLASS_OBJECT, i) ); + CObject* obj = static_cast( iMan->SearchInstance(CLASS_OBJECT, i) ); if (obj == NULL) break; diff --git a/src/graphics/engine/camera.h b/src/graphics/engine/camera.h index 20d252d..0ffc2c2 100644 --- a/src/graphics/engine/camera.h +++ b/src/graphics/engine/camera.h @@ -28,8 +28,8 @@ #include "graphics/engine/engine.h" -class CInstanceManager; class CObject; +class CRobotMain; // Graphics module namespace @@ -130,7 +130,7 @@ enum CameraOverEffect class CCamera { public: - CCamera(CInstanceManager* iMan); + CCamera(); ~CCamera(); //! Management of an event @@ -258,8 +258,8 @@ protected: void OverFrame(const Event &event); protected: - CInstanceManager* m_iMan; CEngine* m_engine; + CRobotMain* m_main; CTerrain* m_terrain; CWater* m_water; diff --git a/src/graphics/engine/cloud.cpp b/src/graphics/engine/cloud.cpp index 0df0d12..d9ebf5a 100644 --- a/src/graphics/engine/cloud.cpp +++ b/src/graphics/engine/cloud.cpp @@ -18,12 +18,12 @@ #include "graphics/engine/cloud.h" -#include "common/iman.h" - #include "graphics/core/device.h" #include "graphics/engine/engine.h" #include "graphics/engine/terrain.h" +#include "object/robotmain.h" + #include "math/geometry.h" @@ -37,11 +37,8 @@ const int CLOUD_LINE_PREALLOCATE_COUNT = 100; const int CLOUD_SIZE_EXPAND = 4; -CCloud::CCloud(CInstanceManager* iMan, CEngine* engine) +CCloud::CCloud(CEngine* engine) { - m_iMan = iMan; - m_iMan->AddInstance(CLASS_CLOUD, this); - m_engine = engine; m_terrain = nullptr; @@ -55,7 +52,6 @@ CCloud::CCloud(CInstanceManager* iMan, CEngine* engine) CCloud::~CCloud() { - m_iMan = nullptr; m_engine = nullptr; m_terrain = nullptr; } @@ -84,7 +80,7 @@ bool CCloud::EventFrame(const Event &event) } void CCloud::AdjustLevel(Math::Vector& pos, Math::Vector& eye, float deep, - Math::Point& uv1, Math::Point& uv2) + Math::Point& uv1, Math::Point& uv2) { uv1.x = (pos.x+20000.0f)/1280.0f; uv1.y = (pos.z+20000.0f)/1280.0f; @@ -211,8 +207,8 @@ void CCloud::CreateLine(int x, int y, int len) } void CCloud::Create(const std::string& fileName, - const Color& diffuse, const Color& ambient, - float level) + const Color& diffuse, const Color& ambient, + float level) { m_diffuse = diffuse; m_ambient = ambient; @@ -225,7 +221,7 @@ void CCloud::Create(const std::string& fileName, m_engine->LoadTexture(m_fileName); if (m_terrain == nullptr) - m_terrain = static_cast(m_iMan->SearchInstance(CLASS_TERRAIN)); + m_terrain = CRobotMain::GetInstancePointer()->GetTerrain(); m_wind = m_terrain->GetWind(); @@ -250,7 +246,6 @@ void CCloud::Flush() m_level = 0.0f; } - void CCloud::SetLevel(float level) { m_level = level; diff --git a/src/graphics/engine/cloud.h b/src/graphics/engine/cloud.h index 6f6985f..8f644f0 100644 --- a/src/graphics/engine/cloud.h +++ b/src/graphics/engine/cloud.h @@ -34,9 +34,6 @@ #include -class CInstanceManager; - - // Graphics module namespace namespace Gfx { @@ -79,12 +76,13 @@ struct CloudLine class CCloud { public: - CCloud(CInstanceManager* iMan, CEngine* engine); + CCloud(CEngine* engine); ~CCloud(); bool EventProcess(const Event& event); //! Removes all the clouds void Flush(); + //! Creates all areas of cloud void Create(const std::string& fileName, const Color& diffuse, const Color& ambient, float level); //! Draw the clouds @@ -112,9 +110,8 @@ protected: void CreateLine(int x, int y, int len); protected: - CInstanceManager* m_iMan; - CEngine* m_engine; - CTerrain* m_terrain; + CEngine* m_engine; + CTerrain* m_terrain; bool m_enabled; //! Overall level diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 71b5e7d..d24a3bd 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -20,7 +20,6 @@ #include "app/app.h" -#include "common/iman.h" #include "common/image.h" #include "common/key.h" #include "common/logger.h" @@ -43,20 +42,16 @@ #include "ui/interface.h" +template<> Gfx::CEngine* CSingleton::m_instance = nullptr; // Graphics module namespace namespace Gfx { -CEngine::CEngine(CInstanceManager *iMan, CApplication *app) +CEngine::CEngine(CApplication *app) { - m_iMan = iMan; m_app = app; m_device = nullptr; - m_iMan = iMan; - m_iMan->AddInstance(CLASS_ENGINE, this); - m_app = app; - m_lightMan = nullptr; m_text = nullptr; m_particle = nullptr; @@ -169,11 +164,17 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app) CEngine::~CEngine() { - m_iMan = nullptr; - m_app = nullptr; - m_device = nullptr; - m_sound = nullptr; - m_terrain = nullptr; + m_app = nullptr; + m_sound = nullptr; + m_device = nullptr; + m_text = nullptr; + m_lightMan = nullptr; + m_particle = nullptr; + m_water = nullptr; + m_cloud = nullptr; + m_lightning = nullptr; + m_planet = nullptr; + m_terrain = nullptr; DestroyTimeStamp(m_lastFrameTime); m_lastFrameTime = nullptr; @@ -191,27 +192,63 @@ CDevice* CEngine::GetDevice() return m_device; } -void CEngine::SetTerrain(CTerrain* terrain) +CText* CEngine::GetText() { - m_terrain = terrain; + return m_text; } -CText* CEngine::GetText() +CLightManager* CEngine::GetLightManager() { - return m_text; + return m_lightMan; +} + +CParticle* CEngine::GetParticle() +{ + return m_particle; +} + +CTerrain* CEngine::GetTerrain() +{ + return m_terrain; +} + +CWater* CEngine::GetWater() +{ + return m_water; } +CLightning* CEngine::GetLightning() +{ + return m_lightning; +} + +CPlanet* CEngine::GetPlanet() +{ + return m_planet; +} + +CCloud* CEngine::GetCloud() +{ + return m_cloud; +} + +void CEngine::SetTerrain(CTerrain* terrain) +{ + m_terrain = terrain; +} + + bool CEngine::Create() { m_size = m_app->GetVideoConfig().size; - m_lightMan = new CLightManager(m_iMan, this); - m_text = new CText(m_iMan, this); - m_particle = new CParticle(m_iMan, this); - m_water = new CWater(m_iMan, this); - m_cloud = new CCloud(m_iMan, this); - m_lightning = new CLightning(m_iMan, this); - m_planet = new CPlanet(m_iMan, this); + m_lightMan = new CLightManager(this); + m_text = new CText(this); + m_particle = new CParticle(this); + m_water = new CWater(this); + m_cloud = new CCloud(this); + m_lightning = new CLightning(this); + m_planet = new CPlanet(this); m_lightMan->SetDevice(m_device); m_particle->SetDevice(m_device); @@ -2046,7 +2083,7 @@ void CEngine::SetViewParams(const Math::Vector& eyePt, const Math::Vector& looka Math::LoadViewMatrix(m_matView, eyePt, lookatPt, upVec); if (m_sound == nullptr) - m_sound = static_cast( m_iMan->SearchInstance(CLASS_SOUND) ); + m_sound = m_app->GetSound(); if (m_sound != nullptr) m_sound->SetListener(eyePt, lookatPt); @@ -3184,9 +3221,11 @@ void CEngine::DrawInterface() SetState(Gfx::ENG_RSTATE_NORMAL); // Draw the entire interface - Ui::CInterface* interface = static_cast( m_iMan->SearchInstance(CLASS_INTERFACE) ); + Ui::CInterface* interface = CRobotMain::GetInstancePointer()->GetInterface(); if (interface != nullptr) + { interface->Draw(); + } m_interfaceMode = false; m_lastState = -1; diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index e5c75bc..0647fbd 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -26,6 +26,7 @@ #include "app/system.h" #include "common/event.h" +#include "common/singleton.h" #include "graphics/core/color.h" #include "graphics/core/material.h" @@ -47,7 +48,6 @@ class CApplication; -class CInstanceManager; class CObject; class CSoundInterface; class CImage; @@ -671,22 +671,36 @@ struct EngineMouse * which is what OpenGL actually wants. The old method is kept for now, with mapping between texture names * and texture structs but it will also be subject to refactoring in the future. */ -class CEngine +class CEngine : public CSingleton { public: - CEngine(CInstanceManager* iMan, CApplication* app); + CEngine(CApplication* app); ~CEngine(); //! Sets the device to be used void SetDevice(CDevice* device); //! Returns the current device - CDevice* GetDevice(); - - //! Sets the terrain object - void SetTerrain(CTerrain* terrain); + CDevice* GetDevice(); //! Returns the text rendering engine CText* GetText(); + //! Returns the light manager + CLightManager* GetLightManager(); + //! Returns the particle manager + CParticle* GetParticle(); + //! Returns the terrain manager + CTerrain* GetTerrain(); + //! Returns the water manager + CWater* GetWater(); + //! Returns the lighting manager + CLightning* GetLightning(); + //! Returns the planet manager + CPlanet* GetPlanet(); + //! Returns the fog manager + CCloud* GetCloud(); + + //! Sets the terrain object + void SetTerrain(CTerrain* terrain); //! Performs the initialization; must be called after device was set @@ -735,8 +749,6 @@ public: //! Returns current size of viewport window Math::IntPoint GetWindowSize(); - //! Returns the last size of viewport window - Math::IntPoint GetLastWindowSize(); //@{ //! Conversion functions between window and interface coordinates @@ -1251,7 +1263,6 @@ protected: void UpdateStaticBuffers(); protected: - CInstanceManager* m_iMan; CApplication* m_app; CSoundInterface* m_sound; CDevice* m_device; diff --git a/src/graphics/engine/lightman.cpp b/src/graphics/engine/lightman.cpp index 3055f08..4a8fd60 100644 --- a/src/graphics/engine/lightman.cpp +++ b/src/graphics/engine/lightman.cpp @@ -19,7 +19,6 @@ #include "graphics/engine/lightman.h" #include "common/logger.h" -#include "common/iman.h" #include "graphics/core/device.h" @@ -78,11 +77,8 @@ DynamicLight::DynamicLight() -CLightManager::CLightManager(CInstanceManager* iMan, CEngine* engine) +CLightManager::CLightManager(CEngine* engine) { - m_iMan = iMan; - m_iMan->AddInstance(CLASS_LIGHT, this); - m_device = nullptr; m_engine = engine; @@ -91,9 +87,6 @@ CLightManager::CLightManager(CInstanceManager* iMan, CEngine* engine) CLightManager::~CLightManager() { - m_iMan->DeleteInstance(CLASS_LIGHT, this); - - m_iMan = nullptr; m_device = nullptr; m_engine = nullptr; } diff --git a/src/graphics/engine/lightman.h b/src/graphics/engine/lightman.h index d83dfb3..07dfe6a 100644 --- a/src/graphics/engine/lightman.h +++ b/src/graphics/engine/lightman.h @@ -129,7 +129,7 @@ class CLightManager { public: //! Constructor - CLightManager(CInstanceManager *iMan, CEngine* engine); + CLightManager(CEngine* engine); //! Destructor virtual ~CLightManager(); @@ -189,7 +189,6 @@ public: void UpdateDeviceLights(EngineObjectType type); protected: - CInstanceManager* m_iMan; CEngine* m_engine; CDevice* m_device; diff --git a/src/graphics/engine/lightning.cpp b/src/graphics/engine/lightning.cpp index d256599..5fdae51 100644 --- a/src/graphics/engine/lightning.cpp +++ b/src/graphics/engine/lightning.cpp @@ -18,6 +18,8 @@ #include "graphics/engine/lightning.h" +#include "app/app.h" + #include "common/logger.h" #include "common/iman.h" @@ -25,22 +27,20 @@ #include "graphics/engine/camera.h" #include "graphics/engine/terrain.h" +#include "math/geometry.h" + #include "object/object.h" +#include "object/robotmain.h" #include "object/auto/autopara.h" -#include "math/geometry.h" - // Graphics module namespace namespace Gfx { -CLightning::CLightning(CInstanceManager* iMan, CEngine* engine) +CLightning::CLightning(CEngine* engine) { - m_iMan = iMan; - m_iMan->AddInstance(CLASS_BLITZ, this); - m_engine = engine; m_terrain = nullptr; m_camera = nullptr; @@ -187,13 +187,13 @@ bool CLightning::Create(float sleep, float delay, float magnetic) m_speed = 1.0f / m_sleep; if (m_terrain == nullptr) - m_terrain = static_cast(m_iMan->SearchInstance(CLASS_TERRAIN)); + m_terrain = CRobotMain::GetInstancePointer()->GetTerrain(); if (m_camera == nullptr) - m_camera = static_cast(m_iMan->SearchInstance(CLASS_CAMERA)); + m_camera = CRobotMain::GetInstancePointer()->GetCamera(); if (m_sound == nullptr) - m_sound = static_cast(m_iMan->SearchInstance(CLASS_SOUND)); + m_sound = CApplication::GetInstancePointer()->GetSound(); return false; } @@ -312,12 +312,14 @@ CObject* CLightning::SearchObject(Math::Vector pos) std::vector paraObjPos; paraObjPos.reserve(100); + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + // Seeking the object closest to the point of impact of lightning. CObject* bestObj = 0; float min = 100000.0f; for (int i = 0; i < 1000000; i++) { - CObject* obj = static_cast( m_iMan->SearchInstance(CLASS_OBJECT, i) ); + CObject* obj = static_cast( iMan->SearchInstance(CLASS_OBJECT, i) ); if (obj == nullptr) break; if (!obj->GetActif()) continue; // inactive object? diff --git a/src/graphics/engine/lightning.h b/src/graphics/engine/lightning.h index b21f681..7809a6c 100644 --- a/src/graphics/engine/lightning.h +++ b/src/graphics/engine/lightning.h @@ -28,7 +28,6 @@ #include "math/vector.h" -class CInstanceManager; class CObject; class CSoundInterface; @@ -53,7 +52,7 @@ const float LTNG_PROTECTION_RADIUS = 200.0f; class CLightning { public: - CLightning(CInstanceManager* iMan, CEngine* engine); + CLightning(CEngine* engine); ~CLightning(); //! Triggers lightning @@ -80,7 +79,6 @@ protected: CObject* SearchObject(Math::Vector pos); protected: - CInstanceManager* m_iMan; CEngine* m_engine; CTerrain* m_terrain; CCamera* m_camera; diff --git a/src/graphics/engine/modelfile.cpp b/src/graphics/engine/modelfile.cpp index c9d41f3..f6d7a7b 100644 --- a/src/graphics/engine/modelfile.cpp +++ b/src/graphics/engine/modelfile.cpp @@ -18,7 +18,6 @@ #include "graphics/engine/modelfile.h" -#include "common/iman.h" #include "common/ioutils.h" #include "common/logger.h" #include "common/stringutils.h" diff --git a/src/graphics/engine/modelmanager.cpp b/src/graphics/engine/modelmanager.cpp index 051922f..c23b79d 100644 --- a/src/graphics/engine/modelmanager.cpp +++ b/src/graphics/engine/modelmanager.cpp @@ -8,7 +8,7 @@ #include -template<> Gfx::CModelManager* CSingleton::mInstance = nullptr; +template<> Gfx::CModelManager* CSingleton::m_instance = nullptr; namespace Gfx { diff --git a/src/graphics/engine/particle.cpp b/src/graphics/engine/particle.cpp index 388c189..d15ee3b 100644 --- a/src/graphics/engine/particle.cpp +++ b/src/graphics/engine/particle.cpp @@ -18,6 +18,9 @@ #include "graphics/engine/particle.h" +#include "app/app.h" + +#include "common/iman.h" #include "common/logger.h" #include "graphics/core/device.h" @@ -117,11 +120,8 @@ float GetDecay(ObjectType type) -CParticle::CParticle(CInstanceManager *iMan, CEngine* engine) +CParticle::CParticle(CEngine* engine) { - m_iMan = iMan; - m_iMan->AddInstance(CLASS_PARTICULE, this); - m_device = nullptr; m_engine = engine; m_main = nullptr; @@ -138,7 +138,6 @@ CParticle::CParticle(CInstanceManager *iMan, CEngine* engine) CParticle::~CParticle() { - m_iMan->DeleteInstance(CLASS_PARTICULE, this); } void CParticle::SetDevice(CDevice* device) @@ -213,7 +212,7 @@ int CParticle::CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point float windSensitivity, int sheet) { if (m_main == nullptr) - m_main = static_cast(m_iMan->SearchInstance(CLASS_MAIN)); + m_main = CRobotMain::GetInstancePointer(); int t = -1; if ( type == PARTIEXPLOT || @@ -649,7 +648,7 @@ void CParticle::CreateWheelTrace(const Math::Vector &p1, const Math::Vector &p2, m_wheelTrace[i].startTime = m_absTime; if (m_terrain == nullptr) - m_terrain = static_cast(m_iMan->SearchInstance(CLASS_TERRAIN)); + m_terrain = m_main->GetTerrain(); m_terrain->AdjustToFloor(m_wheelTrace[i].pos[0]); m_wheelTrace[i].pos[0].y += 0.2f; // just above the ground @@ -808,15 +807,15 @@ void CParticle::SetFrameUpdate(int sheet, bool update) void CParticle::FrameParticle(float rTime) { if (m_main == nullptr) - m_main = static_cast(m_iMan->SearchInstance(CLASS_MAIN)); + m_main = CRobotMain::GetInstancePointer(); bool pause = (m_engine->GetPause() && !m_main->GetInfoLock()); if (m_terrain == nullptr) - m_terrain = static_cast(m_iMan->SearchInstance(CLASS_TERRAIN)); + m_terrain = m_main->GetTerrain(); if (m_water == nullptr) - m_water = static_cast(m_iMan->SearchInstance(CLASS_WATER)); + m_water = m_engine->GetWater(); if (!pause) { @@ -3654,11 +3653,13 @@ CObject* CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos, box2.y += min; box2.z += min; + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + CObject* best = 0; bool shield = false; for (int i = 0; i < 1000000; i++) { - CObject* obj = static_cast(m_iMan->SearchInstance(CLASS_OBJECT, i)); + CObject* obj = static_cast(iMan->SearchInstance(CLASS_OBJECT, i)); if (obj == 0) break; if (!obj->GetActif()) continue; // inactive? @@ -3782,9 +3783,11 @@ CObject* CParticle::SearchObjectRay(Math::Vector pos, Math::Vector goal, box2.y += min; box2.z += min; + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + for (int i = 0; i < 1000000; i++) { - CObject* obj = static_cast( m_iMan->SearchInstance(CLASS_OBJECT, i) ); + CObject* obj = static_cast( iMan->SearchInstance(CLASS_OBJECT, i) ); if (obj == nullptr) break; if (!obj->GetActif()) continue; // inactive? @@ -3822,7 +3825,7 @@ CObject* CParticle::SearchObjectRay(Math::Vector pos, Math::Vector goal, void CParticle::Play(Sound sound, Math::Vector pos, float amplitude) { if (m_sound == nullptr) - m_sound = static_cast(m_iMan->SearchInstance(CLASS_SOUND)); + m_sound = CApplication::GetInstancePointer()->GetSound(); m_sound->Play(sound, pos, amplitude); } diff --git a/src/graphics/engine/particle.h b/src/graphics/engine/particle.h index 90aec55..708a04d 100644 --- a/src/graphics/engine/particle.h +++ b/src/graphics/engine/particle.h @@ -28,7 +28,6 @@ #include "sound/sound.h" -class CInstanceManager; class CRobotMain; class CObject; class CSoundInterface; @@ -267,7 +266,7 @@ struct WheelTrace class CParticle { public: - CParticle(CInstanceManager* iMan, CEngine* engine); + CParticle(CEngine* engine); ~CParticle(); //! Sets the device to use @@ -371,7 +370,6 @@ protected: void TrackDraw(int i, ParticleType type); protected: - CInstanceManager* m_iMan; CEngine* m_engine; CDevice* m_device; CTerrain* m_terrain; diff --git a/src/graphics/engine/planet.cpp b/src/graphics/engine/planet.cpp index 3b9aa6c..49bcb4c 100644 --- a/src/graphics/engine/planet.cpp +++ b/src/graphics/engine/planet.cpp @@ -18,8 +18,6 @@ #include "graphics/engine/planet.h" -#include "common/iman.h" - #include "graphics/core/device.h" #include "graphics/engine/engine.h" @@ -31,11 +29,8 @@ namespace Gfx { const int PLANET_PREALLOCATE_COUNT = 10; -CPlanet::CPlanet(CInstanceManager* iMan, CEngine* engine) +CPlanet::CPlanet(CEngine* engine) { - m_iMan = iMan; - m_iMan->AddInstance(CLASS_PLANET, this); - m_planet[0].reserve(PLANET_PREALLOCATE_COUNT); m_planet[1].reserve(PLANET_PREALLOCATE_COUNT); @@ -46,7 +41,6 @@ CPlanet::CPlanet(CInstanceManager* iMan, CEngine* engine) CPlanet::~CPlanet() { - m_iMan = nullptr; } void CPlanet::Flush() diff --git a/src/graphics/engine/planet.h b/src/graphics/engine/planet.h index 1b16da0..3762e1d 100644 --- a/src/graphics/engine/planet.h +++ b/src/graphics/engine/planet.h @@ -30,8 +30,6 @@ #include -class CInstanceManager; - // Graphics module namespace namespace Gfx { @@ -82,7 +80,7 @@ struct Planet class CPlanet { public: - CPlanet(CInstanceManager* iMan, CEngine* engine); + CPlanet(CEngine* engine); ~CPlanet(); //! Removes all the planets @@ -110,7 +108,6 @@ protected: bool EventFrame(const Event &event); protected: - CInstanceManager* m_iMan; CEngine* m_engine; float m_time; diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index e374d6c..1d80fea 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -18,6 +18,9 @@ #include "graphics/engine/pyro.h" +#include "app/app.h" + +#include "common/iman.h" #include "common/logger.h" #include "graphics/engine/lightman.h" @@ -36,20 +39,19 @@ namespace Gfx { -CPyro::CPyro(CInstanceManager* iMan) +CPyro::CPyro() { - m_iMan = iMan; - m_iMan->AddInstance(CLASS_PYRO, this, 100); - - m_engine = static_cast(m_iMan->SearchInstance(CLASS_ENGINE)); - m_terrain = static_cast(m_iMan->SearchInstance(CLASS_TERRAIN)); - m_camera = static_cast(m_iMan->SearchInstance(CLASS_CAMERA)); - m_particle = static_cast(m_iMan->SearchInstance(CLASS_PARTICULE)); - m_lightMan = static_cast(m_iMan->SearchInstance(CLASS_LIGHT)); - m_displayText = static_cast(m_iMan->SearchInstance(CLASS_DISPLAYTEXT)); - m_main = static_cast(m_iMan->SearchInstance(CLASS_MAIN)); - m_sound = static_cast(m_iMan->SearchInstance(CLASS_SOUND)); - m_object = 0; + CInstanceManager::GetInstancePointer()->AddInstance(CLASS_PYRO, this, 100); + + m_engine = CEngine::GetInstancePointer(); + m_main = CRobotMain::GetInstancePointer(); + m_terrain = m_main->GetTerrain(); + m_camera = m_main->GetCamera(); + m_particle = m_engine->GetParticle(); + m_lightMan = m_engine->GetLightManager(); + m_displayText = m_main->GetDisplayText(); + m_sound = CApplication::GetInstancePointer()->GetSound(); + m_object = nullptr; m_progress = 0.0f; m_speed = 0.0f; @@ -60,7 +62,7 @@ CPyro::CPyro(CInstanceManager* iMan) CPyro::~CPyro() { - m_iMan->DeleteInstance(CLASS_PYRO, this); + CInstanceManager::GetInstancePointer()->DeleteInstance(CLASS_PYRO, this); } void CPyro::DeleteObject() @@ -2183,9 +2185,11 @@ CObject* CPyro::FallSearchBeeExplo() float iRadius; m_object->GetCrashSphere(0, iPos, iRadius); + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + for (int i = 0; i < 1000000; i++) { - CObject* pObj = static_cast(m_iMan->SearchInstance(CLASS_OBJECT, i)); + CObject* pObj = static_cast(iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; ObjectType oType = pObj->GetType(); diff --git a/src/graphics/engine/pyro.h b/src/graphics/engine/pyro.h index 0204070..9548a07 100644 --- a/src/graphics/engine/pyro.h +++ b/src/graphics/engine/pyro.h @@ -31,7 +31,6 @@ #include "object/object.h" -class CInstanceManager; class CObject; class CRobotMain; class CSoundInterface; @@ -111,7 +110,7 @@ struct PyroLightOper class CPyro { public: - CPyro(CInstanceManager* iMan); + CPyro(); ~CPyro(); //! Creates pyrotechnic effect @@ -174,7 +173,6 @@ protected: void LightOperFrame(float rTime); protected: - CInstanceManager* m_iMan; CEngine* m_engine; CTerrain* m_terrain; CCamera* m_camera; diff --git a/src/graphics/engine/terrain.cpp b/src/graphics/engine/terrain.cpp index 0be75bc..8f7ad26 100644 --- a/src/graphics/engine/terrain.cpp +++ b/src/graphics/engine/terrain.cpp @@ -19,11 +19,13 @@ #include "graphics/engine/terrain.h" #include "app/app.h" -#include "common/iman.h" + #include "common/image.h" #include "common/logger.h" + #include "graphics/engine/engine.h" #include "graphics/engine/water.h" + #include "math/geometry.h" #include @@ -35,13 +37,10 @@ namespace Gfx { -CTerrain::CTerrain(CInstanceManager* iMan) +CTerrain::CTerrain() { - m_iMan = iMan; - m_iMan->AddInstance(CLASS_TERRAIN, this); - - m_engine = static_cast( m_iMan->SearchInstance(CLASS_ENGINE) ); - m_water = static_cast( m_iMan->SearchInstance(CLASS_WATER) ); + m_engine = CEngine::GetInstancePointer(); + m_water = m_engine->GetWater(); m_mosaicCount = 20; m_brickCount = 1 << 4; diff --git a/src/graphics/engine/terrain.h b/src/graphics/engine/terrain.h index 91ddc76..1fa8dec 100644 --- a/src/graphics/engine/terrain.h +++ b/src/graphics/engine/terrain.h @@ -26,9 +26,6 @@ #include "graphics/engine/engine.h" -class CInstanceManager; - - // Graphics module namespace namespace Gfx { @@ -223,7 +220,7 @@ struct FlyingLimit class CTerrain { public: - CTerrain(CInstanceManager* iMan); + CTerrain(); ~CTerrain(); //! Generates a new flat terrain @@ -359,7 +356,6 @@ protected: void AdjustBuildingLevel(Math::Vector &p); protected: - CInstanceManager* m_iMan; CEngine* m_engine; CWater* m_water; diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 48af081..424b99b 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -19,10 +19,11 @@ #include "graphics/engine/text.h" #include "app/app.h" + #include "common/image.h" -#include "common/iman.h" #include "common/logger.h" #include "common/stringutils.h" + #include "math/func.h" #include @@ -49,11 +50,8 @@ struct CachedFont const Math::IntPoint REFERENCE_SIZE(800, 600); -CText::CText(CInstanceManager *iMan, CEngine* engine) +CText::CText(CEngine* engine) { - m_iMan = iMan; - m_iMan->AddInstance(CLASS_TEXT, this); - m_device = nullptr; m_engine = engine; @@ -66,9 +64,6 @@ CText::CText(CInstanceManager *iMan, CEngine* engine) CText::~CText() { - m_iMan->DeleteInstance(CLASS_TEXT, this); - - m_iMan = nullptr; m_device = nullptr; m_engine = nullptr; } diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h index e7578df..d8e2aff 100644 --- a/src/graphics/engine/text.h +++ b/src/graphics/engine/text.h @@ -31,9 +31,6 @@ #include -class CInstanceManager; - - // Graphics module namespace namespace Gfx { @@ -226,7 +223,7 @@ struct MultisizeFont class CText { public: - CText(CInstanceManager *iMan, CEngine* engine); + CText(CEngine* engine); virtual ~CText(); //! Sets the device to be used @@ -301,7 +298,6 @@ protected: void StringToUTFCharList(const std::string &text, std::vector &chars); protected: - CInstanceManager* m_iMan; CEngine* m_engine; CDevice* m_device; diff --git a/src/graphics/engine/water.cpp b/src/graphics/engine/water.cpp index 6c822b3..d90652b 100644 --- a/src/graphics/engine/water.cpp +++ b/src/graphics/engine/water.cpp @@ -18,7 +18,8 @@ #include "graphics/engine/water.h" -#include "common/iman.h" +#include "app/app.h" + #include "common/logger.h" #include "graphics/core/device.h" @@ -28,6 +29,7 @@ #include "math/geometry.h" #include "object/object.h" +#include "object/robotmain.h" #include "sound/sound.h" @@ -42,14 +44,11 @@ const int WATERLINE_PREALLOCATE_COUNT = 500; const int VAPOR_SIZE = 10; -CWater::CWater(CInstanceManager* iMan, CEngine* engine) +CWater::CWater(CEngine* engine) { - m_iMan = iMan; - m_iMan->AddInstance(CLASS_WATER, this); - m_engine = engine; m_terrain = nullptr; - m_particule = nullptr; + m_particle = nullptr; m_sound = nullptr; m_type[0] = WATER_NULL; @@ -67,10 +66,9 @@ CWater::CWater(CInstanceManager* iMan, CEngine* engine) CWater::~CWater() { - m_iMan = nullptr; m_engine = nullptr; m_terrain = nullptr; - m_particule = nullptr; + m_particle = nullptr; m_sound = nullptr; } @@ -99,8 +97,8 @@ bool CWater::EventFrame(const Event &event) void CWater::LavaFrame(float rTime) { - if (m_particule == nullptr) - m_particule = static_cast( m_iMan->SearchInstance(CLASS_PARTICULE) ); + if (m_particle == nullptr) + m_particle = m_engine->GetParticle(); for (int i = 0; i < static_cast( m_vapors.size() ); i++) VaporFrame(i, rTime); @@ -183,7 +181,7 @@ void CWater::VaporFrame(int i, float rTime) m_vapors[i].time += rTime; if (m_sound == nullptr) - m_sound = static_cast(m_iMan->SearchInstance(CLASS_SOUND)); + m_sound = CApplication::GetInstancePointer()->GetSound(); if (m_vapors[i].time <= m_vapors[i].delay) { @@ -206,7 +204,7 @@ void CWater::VaporFrame(int i, float rTime) Math::Point dim; dim.x = Math::Rand()*1.5f+1.5f; dim.y = dim.x; - m_particule->CreateParticle(pos, speed, dim, PARTIERROR, 2.0f, 10.0f); + m_particle->CreateParticle(pos, speed, dim, PARTIERROR, 2.0f, 10.0f); } } else if (m_vapors[i].type == PARTIFLAME) @@ -222,7 +220,7 @@ void CWater::VaporFrame(int i, float rTime) Math::Point dim; dim.x = Math::Rand()*2.0f+2.0f; dim.y = dim.x; - m_particule->CreateParticle(pos, speed, dim, PARTIFLAME); + m_particle->CreateParticle(pos, speed, dim, PARTIFLAME); } else { @@ -237,7 +235,7 @@ void CWater::VaporFrame(int i, float rTime) Math::Point dim; dim.x = Math::Rand()*1.0f+1.0f; dim.y = dim.x; - m_particule->CreateParticle(pos, speed, dim, PARTIVAPOR); + m_particle->CreateParticle(pos, speed, dim, PARTIVAPOR); } } } @@ -497,7 +495,7 @@ void CWater::Create(WaterType type1, WaterType type2, const std::string& fileNam m_engine->LoadTexture(m_fileName); if (m_terrain == nullptr) - m_terrain = static_cast(m_iMan->SearchInstance(CLASS_TERRAIN)); + m_terrain = CRobotMain::GetInstancePointer()->GetTerrain(); m_brickCount = m_terrain->GetBrickCount()*m_terrain->GetMosaicCount(); m_brickSize = m_terrain->GetBrickSize(); diff --git a/src/graphics/engine/water.h b/src/graphics/engine/water.h index 21d96d4..bb113e0 100644 --- a/src/graphics/engine/water.h +++ b/src/graphics/engine/water.h @@ -28,7 +28,6 @@ #include "graphics/engine/particle.h" -class CInstanceManager; class CSoundInterface; @@ -117,8 +116,8 @@ enum WaterType class CWater { public: - CWater(CInstanceManager* iMan, CEngine* engine); - ~CWater(); + CWater(CEngine* engine); + virtual ~CWater(); void SetDevice(CDevice* device); bool EventProcess(const Event &event); @@ -168,11 +167,10 @@ protected: void VaporFrame(int i, float rTime); protected: - CInstanceManager* m_iMan; CEngine* m_engine; CDevice* m_device; CTerrain* m_terrain; - CParticle* m_particule; + CParticle* m_particle; CSoundInterface* m_sound; WaterType m_type[2]; -- cgit v1.2.3-1-g7c22 From ba2df2cb4201597c9dc01365641413dcbf6812d9 Mon Sep 17 00:00:00 2001 From: erihel Date: Sun, 24 Feb 2013 01:40:55 +0100 Subject: * Fix for satcom freeze --- src/graphics/engine/text.cpp | 35 +++++++++++++++++++++-------------- src/graphics/engine/text.h | 8 +++++++- 2 files changed, 28 insertions(+), 15 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 424b99b..9dea129 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -149,6 +149,7 @@ void CText::FlushCache() } void CText::DrawText(const std::string &text, std::vector::iterator format, + std::vector::iterator end, float size, Math::Point pos, float width, TextAlign align, int eol, Color color) { @@ -156,18 +157,18 @@ void CText::DrawText(const std::string &text, std::vector::iterato if (align == TEXT_ALIGN_CENTER) { - sw = GetStringWidth(text, format, size); + sw = GetStringWidth(text, format, end, size); if (sw > width) sw = width; pos.x -= sw / 2.0f; } else if (align == TEXT_ALIGN_RIGHT) { - sw = GetStringWidth(text, format, size); + sw = GetStringWidth(text, format, end, size); if (sw > width) sw = width; pos.x -= sw; } - DrawString(text, format, size, pos, width, eol, color); + DrawString(text, format, end, size, pos, width, eol, color); } void CText::DrawText(const std::string &text, FontType font, @@ -193,12 +194,13 @@ void CText::DrawText(const std::string &text, FontType font, } void CText::SizeText(const std::string &text, std::vector::iterator format, + std::vector::iterator endFormat, float size, Math::Point pos, TextAlign align, Math::Point &start, Math::Point &end) { start = end = pos; - float sw = GetStringWidth(text, format, size); + float sw = GetStringWidth(text, format, endFormat, size); end.x += sw; if (align == TEXT_ALIGN_CENTER) { @@ -276,7 +278,8 @@ float CText::GetHeight(FontType font, float size) float CText::GetStringWidth(const std::string &text, - std::vector::iterator format, float size) + std::vector::iterator format, + std::vector::iterator end, float size) { float width = 0.0f; unsigned int index = 0; @@ -284,8 +287,8 @@ float CText::GetStringWidth(const std::string &text, while (index < text.length()) { FontType font = FONT_COLOBOT; - //if (format.size() > fmtIndex) - font = static_cast(format[fmtIndex] & FONT_MASK_FONT); + if (format + fmtIndex != end) + font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); UTF8Char ch; @@ -343,6 +346,7 @@ float CText::GetCharWidth(UTF8Char ch, FontType font, float size, float offset) int CText::Justify(const std::string &text, std::vector::iterator format, + std::vector::iterator end, float size, float width) { float pos = 0.0f; @@ -352,8 +356,8 @@ int CText::Justify(const std::string &text, std::vector::iterator while (index < text.length()) { FontType font = FONT_COLOBOT; - //if (format.size() > fmtIndex) - font = static_cast(format[fmtIndex] & FONT_MASK_FONT); + if (format + fmtIndex != end) + font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); UTF8Char ch; @@ -427,6 +431,7 @@ int CText::Justify(const std::string &text, FontType font, float size, float wid } int CText::Detect(const std::string &text, std::vector::iterator format, + std::vector::iterator end, float size, float offset) { float pos = 0.0f; @@ -435,11 +440,12 @@ int CText::Detect(const std::string &text, std::vector::iterator f while (index < text.length()) { FontType font = FONT_COLOBOT; - //if (format.size() > fmtIndex) - font = static_cast(format[fmtIndex] & FONT_MASK_FONT); + + if (format + fmtIndex != end) + font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); // TODO: if (font == FONT_BUTTON) - if (font == FONT_BUTTON) continue; + //if (font == FONT_BUTTON) continue; UTF8Char ch; @@ -500,6 +506,7 @@ int CText::Detect(const std::string &text, FontType font, float size, float offs } void CText::DrawString(const std::string &text, std::vector::iterator format, + std::vector::iterator end, float size, Math::Point pos, float width, int eol, Color color) { m_engine->SetState(ENG_RSTATE_TEXT); @@ -513,8 +520,8 @@ void CText::DrawString(const std::string &text, std::vector::itera for (auto it = chars.begin(); it != chars.end(); ++it) { FontType font = FONT_COLOBOT; - //if (format.size() > fmtIndex) - font = static_cast(format[fmtIndex] & FONT_MASK_FONT); + if (format + fmtIndex != end) + font = static_cast(*(format + fmtIndex) & FONT_MASK_FONT); // TODO: if (font == FONT_BUTTON) if (font == FONT_BUTTON) continue; diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h index d8e2aff..6bcc59b 100644 --- a/src/graphics/engine/text.h +++ b/src/graphics/engine/text.h @@ -242,6 +242,7 @@ public: //! Draws text (multi-format) void DrawText(const std::string &text, std::vector::iterator format, + std::vector::iterator end, float size, Math::Point pos, float width, TextAlign align, int eol, Color color = Color(0.0f, 0.0f, 0.0f, 1.0f)); //! Draws text (one font) @@ -251,6 +252,7 @@ public: //! Calculates dimensions for text (multi-format) void SizeText(const std::string &text, std::vector::iterator format, + std::vector::iterator endFormat, float size, Math::Point pos, TextAlign align, Math::Point &start, Math::Point &end); //! Calculates dimensions for text (one font) @@ -267,7 +269,8 @@ public: //! Returns width of string (multi-format) TEST_VIRTUAL float GetStringWidth(const std::string &text, - std::vector::iterator format, float size); + std::vector::iterator format, + std::vector::iterator end, float size); //! Returns width of string (single font) TEST_VIRTUAL float GetStringWidth(const std::string &text, FontType font, float size); //! Returns width of single character @@ -275,12 +278,14 @@ public: //! Justifies a line of text (multi-format) int Justify(const std::string &text, std::vector::iterator format, + std::vector::iterator end, float size, float width); //! Justifies a line of text (one font) int Justify(const std::string &text, FontType font, float size, float width); //! Returns the most suitable position to a given offset (multi-format) int Detect(const std::string &text, std::vector::iterator format, + std::vector::iterator end, float size, float offset); //! Returns the most suitable position to a given offset (one font) int Detect(const std::string &text, FontType font, float size, float offset); @@ -290,6 +295,7 @@ protected: CharTexture CreateCharTexture(UTF8Char ch, CachedFont* font); void DrawString(const std::string &text, std::vector::iterator format, + std::vector::iterator end, float size, Math::Point pos, float width, int eol, Color color); void DrawString(const std::string &text, FontType font, float size, Math::Point pos, float width, int eol, Color color); -- cgit v1.2.3-1-g7c22 From b0d86ebe5a3c2330307a5c383f0136377338336c Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Mon, 25 Feb 2013 21:58:01 +0100 Subject: Better light sorting Should fix lighting issue (#62) --- src/graphics/engine/engine.h | 6 +-- src/graphics/engine/lightman.cpp | 79 +++++++++++++++++++--------------------- src/graphics/engine/lightman.h | 21 +++++++++-- 3 files changed, 58 insertions(+), 48 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 0647fbd..f9dfd45 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -729,7 +729,7 @@ public: //@{ //! Management of game pause mode void SetPause(bool pause); - bool GetPause(); + TEST_VIRTUAL bool GetPause(); //@} //@{ @@ -1170,9 +1170,9 @@ public: //! Returns the view matrix const Math::Matrix& GetMatView(); //! Returns the camera center point - Math::Vector GetEyePt(); + TEST_VIRTUAL Math::Vector GetEyePt(); //! Returns the camera target point - Math::Vector GetLookatPt(); + TEST_VIRTUAL Math::Vector GetLookatPt(); //! Returns the horizontal direction angle of view float GetEyeDirH(); //! Returns the vertical direction angle of view diff --git a/src/graphics/engine/lightman.cpp b/src/graphics/engine/lightman.cpp index 4a8fd60..628ebf5 100644 --- a/src/graphics/engine/lightman.cpp +++ b/src/graphics/engine/lightman.cpp @@ -26,6 +26,7 @@ #include +#include // Graphics module namespace @@ -386,39 +387,10 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type) for (int i = 0; i < static_cast( m_lightMap.size() ); ++i) m_lightMap[i] = -1; - // High priority - for (int i = 0; i < static_cast( m_dynLights.size() ); i++) - { - if (! m_dynLights[i].used) - continue; - if (! m_dynLights[i].enabled) - continue; - if (Math::IsZero(m_dynLights[i].intensity.current)) - continue; - if (m_dynLights[i].priority == LIGHT_PRI_LOW) - continue; - - bool enabled = true; - if (m_dynLights[i].includeType != ENG_OBJTYPE_NULL) - enabled = (m_dynLights[i].includeType == type); - - if (m_dynLights[i].excludeType != ENG_OBJTYPE_NULL) - enabled = (m_dynLights[i].excludeType != type); - - if (enabled) - { - for (int j = 0; j < static_cast( m_lightMap.size() ); ++j) - { - if (m_lightMap[j] == -1) - { - m_lightMap[j] = i; - break; - } - } - } - } + std::vector sortedLights = m_dynLights; + std::sort(sortedLights.begin(), sortedLights.end(), LightsComparator(m_engine->GetEyePt(), type)); - // Low priority + int lightMapIndex = 0; for (int i = 0; i < static_cast( m_dynLights.size() ); i++) { if (! m_dynLights[i].used) @@ -427,8 +399,6 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type) continue; if (m_dynLights[i].intensity.current == 0.0f) continue; - if (m_dynLights[i].priority == LIGHT_PRI_HIGH) - continue; bool enabled = true; if (m_dynLights[i].includeType != ENG_OBJTYPE_NULL) @@ -439,15 +409,12 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type) if (enabled) { - for (int j = 0; j < static_cast( m_lightMap.size() ); ++j) - { - if (m_lightMap[j] == -1) - { - m_lightMap[j] = i; - break; - } - } + m_lightMap[lightMapIndex] = i; + ++lightMapIndex; } + + if (lightMapIndex >= static_cast( m_lightMap.size() )) + break; } for (int i = 0; i < static_cast( m_lightMap.size() ); ++i) @@ -465,5 +432,33 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type) } } +// ----------- + +CLightManager::LightsComparator::LightsComparator(Math::Vector eyePos, EngineObjectType objectType) +{ + m_eyePos = eyePos; + m_objectType = objectType; +} + +float CLightManager::LightsComparator::GetLightWeight(const DynamicLight& dynLight) +{ + bool enabled = true; + if (!dynLight.used || !dynLight.enabled || dynLight.intensity.current == 0.0f) + enabled = false; + else if (dynLight.includeType != ENG_OBJTYPE_NULL) + enabled = dynLight.includeType == m_objectType; + else if (dynLight.excludeType != ENG_OBJTYPE_NULL) + enabled = dynLight.excludeType != m_objectType; + + return enabled ? ( (dynLight.light.position - m_eyePos).Length() * dynLight.priority ) : 10000.0f; +} + +bool CLightManager::LightsComparator::operator()(const DynamicLight& left, const DynamicLight& right) +{ + float leftWeight = GetLightWeight(left); + float rightWeight = GetLightWeight(right); + + return leftWeight >= rightWeight; +} } // namespace Gfx diff --git a/src/graphics/engine/lightman.h b/src/graphics/engine/lightman.h index 07dfe6a..ab66524 100644 --- a/src/graphics/engine/lightman.h +++ b/src/graphics/engine/lightman.h @@ -71,8 +71,8 @@ struct LightProgression */ enum LightPriority { - LIGHT_PRI_HIGH, - LIGHT_PRI_LOW + LIGHT_PRI_HIGH = 1, + LIGHT_PRI_LOW = 2 }; /** @@ -188,6 +188,21 @@ public: //! Enables or disables dynamic lights affecting the given object type void UpdateDeviceLights(EngineObjectType type); +protected: + class LightsComparator + { + public: + LightsComparator(Math::Vector eyePos, EngineObjectType objectType); + + bool operator()(const DynamicLight& left, const DynamicLight& right); + + private: + float GetLightWeight(const DynamicLight& dynLight); + + Math::Vector m_eyePos; + EngineObjectType m_objectType; + }; + protected: CEngine* m_engine; CDevice* m_device; @@ -196,7 +211,7 @@ protected: float m_time; //! List of dynamic lights std::vector m_dynLights; - //! Map of current light allotment: graphics light -> dynamic light + //! Map of current light allocation: graphics light -> dynamic light std::vector m_lightMap; }; -- cgit v1.2.3-1-g7c22 From 08c646bb929c7bc98b005521b6e0c14428f651d0 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Thu, 28 Feb 2013 21:26:09 +0100 Subject: Fixed stupid error, tweaked ambient light colors * fixed stupid error in light manager * tweaked ambient light colors to 0.1 of diffuse; colors should not be oversaturated now --- src/graphics/core/color.h | 10 ++++++++++ src/graphics/engine/lightman.cpp | 22 ++++++++++++---------- src/graphics/engine/pyro.cpp | 9 +++------ 3 files changed, 25 insertions(+), 16 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/core/color.h b/src/graphics/core/color.h index 7cbd175..5d059e5 100644 --- a/src/graphics/core/color.h +++ b/src/graphics/core/color.h @@ -76,6 +76,16 @@ struct Color { return ! this->operator==(other); } + + inline Color operator*(float scale) const + { + Color c = *this; + c.r *= scale; + c.g *= scale; + c.b *= scale; + c.a *= scale; + return c; + } }; /** diff --git a/src/graphics/engine/lightman.cpp b/src/graphics/engine/lightman.cpp index 628ebf5..eae622b 100644 --- a/src/graphics/engine/lightman.cpp +++ b/src/graphics/engine/lightman.cpp @@ -126,6 +126,7 @@ int CLightManager::CreateLight(LightPriority priority) m_dynLights[index].light.type = LIGHT_DIRECTIONAL; m_dynLights[index].light.diffuse = Color(0.5f, 0.5f, 0.5f); + m_dynLights[index].light.ambient = Color(0.0f, 0.0f, 0.0f); m_dynLights[index].light.position = Math::Vector(-100.0f, 100.0f, -100.0f); m_dynLights[index].light.direction = Math::Vector( 1.0f, -1.0f, 1.0f); @@ -391,21 +392,21 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type) std::sort(sortedLights.begin(), sortedLights.end(), LightsComparator(m_engine->GetEyePt(), type)); int lightMapIndex = 0; - for (int i = 0; i < static_cast( m_dynLights.size() ); i++) + for (int i = 0; i < static_cast( sortedLights.size() ); i++) { - if (! m_dynLights[i].used) + if (! sortedLights[i].used) continue; - if (! m_dynLights[i].enabled) + if (! sortedLights[i].enabled) continue; - if (m_dynLights[i].intensity.current == 0.0f) + if (sortedLights[i].intensity.current == 0.0f) continue; bool enabled = true; - if (m_dynLights[i].includeType != ENG_OBJTYPE_NULL) - enabled = (m_dynLights[i].includeType == type); + if (sortedLights[i].includeType != ENG_OBJTYPE_NULL) + enabled = (sortedLights[i].includeType == type); - if (m_dynLights[i].excludeType != ENG_OBJTYPE_NULL) - enabled = (m_dynLights[i].excludeType != type); + if (sortedLights[i].excludeType != ENG_OBJTYPE_NULL) + enabled = (sortedLights[i].excludeType != type); if (enabled) { @@ -422,7 +423,8 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type) int rank = m_lightMap[i]; if (rank != -1) { - m_device->SetLight(i, m_dynLights[rank].light); + sortedLights[rank].light.ambient = Gfx::Color(0.2f, 0.2f, 0.2f); + m_device->SetLight(i, sortedLights[rank].light); m_device->SetLightEnabled(i, true); } else @@ -458,7 +460,7 @@ bool CLightManager::LightsComparator::operator()(const DynamicLight& left, const float leftWeight = GetLightWeight(left); float rightWeight = GetLightWeight(right); - return leftWeight >= rightWeight; + return leftWeight <= rightWeight; } } // namespace Gfx diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index 1d80fea..cab28b6 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -1318,12 +1318,9 @@ void CPyro::CreateLight(Math::Vector pos, float height) Gfx::Light light; light.type = LIGHT_SPOT; - light.position.x = pos.x; - light.position.y = pos.y+height; - light.position.z = pos.z; - light.direction.x = 0.0f; - light.direction.y = -1.0f; // against the bottom - light.direction.z = 0.0f; + light.ambient = Gfx::Color(0.0f, 0.0f, 0.0f); + light.position = Math::Vector(pos.x, pos.y+height, pos.z); + light.direction = Math::Vector(0.0f, -1.0f, 0.0f); // against the bottom light.spotIntensity = 1.0f; light.attenuation0 = 1.0f; light.attenuation1 = 0.0f; -- cgit v1.2.3-1-g7c22 From f729686539b4e4628ab818e1a2bffbe1d48ed114 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Thu, 28 Feb 2013 22:56:44 +0100 Subject: Fixed segfault in light manager Also fixed minor memory leak --- src/graphics/engine/lightman.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/lightman.cpp b/src/graphics/engine/lightman.cpp index eae622b..16c84ea 100644 --- a/src/graphics/engine/lightman.cpp +++ b/src/graphics/engine/lightman.cpp @@ -389,7 +389,8 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type) m_lightMap[i] = -1; std::vector sortedLights = m_dynLights; - std::sort(sortedLights.begin(), sortedLights.end(), LightsComparator(m_engine->GetEyePt(), type)); + LightsComparator lightsComparator(m_engine->GetEyePt(), type); + std::sort(sortedLights.begin(), sortedLights.end(), lightsComparator); int lightMapIndex = 0; for (int i = 0; i < static_cast( sortedLights.size() ); i++) @@ -460,7 +461,7 @@ bool CLightManager::LightsComparator::operator()(const DynamicLight& left, const float leftWeight = GetLightWeight(left); float rightWeight = GetLightWeight(right); - return leftWeight <= rightWeight; + return leftWeight < rightWeight; } } // namespace Gfx -- cgit v1.2.3-1-g7c22 From bc859c4c597f106d40f07380bf255f180d565577 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sun, 10 Mar 2013 15:44:21 +0100 Subject: VBO override option; argv parsing using getopt * added -vbo option to override autodetection of OpenGL VBO extension * refactored argument parsing to use getopt() * fixed failing UTs --- src/graphics/opengl/gldevice.cpp | 25 +++++++++++++++++++++---- src/graphics/opengl/gldevice.h | 14 ++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index 80fa9a1..beeb85e 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -51,6 +51,8 @@ void GLDeviceConfig::LoadDefault() greenSize = 8; alphaSize = 8; depthSize = 24; + + vboMode = VBO_MODE_AUTO; } @@ -99,11 +101,26 @@ bool CGLDevice::Create() if (!m_multitextureAvailable) GetLogger()->Warn("GLEW reports multitexturing not supported - graphics quality will be degraded!\n"); - m_vboAvailable = glewIsSupported("GL_ARB_vertex_buffer_object"); - if (m_vboAvailable) - GetLogger()->Info("Detected ARB_vertex_buffer_object extension - using VBOs\n"); + if (m_config.vboMode == VBO_MODE_ENABLE) + { + GetLogger()->Info("VBO enabled by override - using VBOs\n"); + m_vboAvailable = true; + } + else if (m_config.vboMode == VBO_MODE_DISABLE) + { + GetLogger()->Info("VBO disabled by override - using display lists\n"); + m_vboAvailable = false; + } else - GetLogger()->Info("No ARB_vertex_buffer_object extension present - using display lists\n"); + { + GetLogger()->Info("Auto-detecting VBO support\n"); + m_vboAvailable = glewIsSupported("GL_ARB_vertex_buffer_object"); + + if (m_vboAvailable) + GetLogger()->Info("Detected ARB_vertex_buffer_object extension - using VBOs\n"); + else + GetLogger()->Info("No ARB_vertex_buffer_object extension present - using display lists\n"); + } } // This is mostly done in all modern hardware by default diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h index 7137671..fe3f2a1 100644 --- a/src/graphics/opengl/gldevice.h +++ b/src/graphics/opengl/gldevice.h @@ -33,6 +33,17 @@ // Graphics module namespace namespace Gfx { +/** + \enum VBOMode + \brief VBO autodetect/override + */ +enum VBOMode +{ + VBO_MODE_ENABLE, //! < override: enable + VBO_MODE_DISABLE, //! < override: disable + VBO_MODE_AUTO //! < autodetect +}; + /** \struct GLDeviceConfig \brief Additional config with OpenGL-specific settings */ @@ -52,6 +63,9 @@ struct GLDeviceConfig : public DeviceConfig //! Force hardware acceleration (video mode set will fail on lack of hw accel) bool hardwareAccel; + //! VBO override/autodetect + VBOMode vboMode; + //! Constructor calls LoadDefaults() GLDeviceConfig(); -- cgit v1.2.3-1-g7c22 From 4a30800cf16d403a7c25d78388e2822aa396ac86 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 22 Mar 2013 18:19:53 +0100 Subject: Fixes for compiling on MSYS * fixed SDL_main() and putenv() issues * disabled desktop subdir for MSYS * disabled building CBot_console for now --- src/graphics/engine/terrain.cpp | 2 +- src/graphics/engine/text.cpp | 4 ++-- src/graphics/opengl/gldevice.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/terrain.cpp b/src/graphics/engine/terrain.cpp index 8f7ad26..c2a7855 100644 --- a/src/graphics/engine/terrain.cpp +++ b/src/graphics/engine/terrain.cpp @@ -30,7 +30,7 @@ #include -#include +#include // Graphics module namespace diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 9dea129..308c813 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -26,8 +26,8 @@ #include "math/func.h" -#include -#include +#include +#include // Graphics module namespace diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index beeb85e..df64e34 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -27,7 +27,7 @@ // Using GLEW so only glew.h is needed #include -#include +#include #include -- cgit v1.2.3-1-g7c22 From 195d6cded05f7ef5bde695ee047b341a0265eab3 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sun, 24 Mar 2013 00:03:37 +0100 Subject: Fixed timer functions on win32 * changed win32 implementation to QueryPerformaceTimer system function * refactored system utils code * proper tests for time utils and update event creation in application * should fix issue #134 --- src/graphics/engine/engine.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/graphics') diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index d24a3bd..e2ef569 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -148,8 +148,8 @@ CEngine::CEngine(CApplication *app) m_mouseType = ENG_MOUSE_NORM; m_fpsCounter = 0; - m_lastFrameTime = CreateTimeStamp(); - m_currentFrameTime = CreateTimeStamp(); + m_lastFrameTime = GetSystemUtils()->CreateTimeStamp(); + m_currentFrameTime = GetSystemUtils()->CreateTimeStamp(); m_defaultTexParams.format = TEX_IMG_AUTO; m_defaultTexParams.mipmap = true; @@ -176,9 +176,9 @@ CEngine::~CEngine() m_planet = nullptr; m_terrain = nullptr; - DestroyTimeStamp(m_lastFrameTime); + GetSystemUtils()->DestroyTimeStamp(m_lastFrameTime); m_lastFrameTime = nullptr; - DestroyTimeStamp(m_currentFrameTime); + GetSystemUtils()->DestroyTimeStamp(m_currentFrameTime); m_currentFrameTime = nullptr; } @@ -279,8 +279,8 @@ bool CEngine::Create() params.mipmap = false; m_miceTexture = LoadTexture("mouse.png", params); - GetCurrentTimeStamp(m_currentFrameTime); - GetCurrentTimeStamp(m_lastFrameTime); + GetSystemUtils()->GetCurrentTimeStamp(m_currentFrameTime); + GetSystemUtils()->GetCurrentTimeStamp(m_lastFrameTime); return true; } @@ -336,11 +336,11 @@ void CEngine::FrameUpdate() { m_fpsCounter++; - GetCurrentTimeStamp(m_currentFrameTime); - float diff = TimeStampDiff(m_lastFrameTime, m_currentFrameTime, STU_SEC); + GetSystemUtils()->GetCurrentTimeStamp(m_currentFrameTime); + float diff = GetSystemUtils()->TimeStampDiff(m_lastFrameTime, m_currentFrameTime, STU_SEC); if (diff > 1.0f) { - CopyTimeStamp(m_lastFrameTime, m_currentFrameTime); + GetSystemUtils()->CopyTimeStamp(m_lastFrameTime, m_currentFrameTime); m_fps = m_fpsCounter / diff; m_fpsCounter = 0; -- cgit v1.2.3-1-g7c22