diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h index aa60de1a..875f613d 100644 --- a/src/graphics/core/device.h +++ b/src/graphics/core/device.h @@ -32,6 +32,7 @@ #include #include +#include class CImage; @@ -312,6 +313,92 @@ public: virtual void* GetPixelsData() = 0; }; +class CVertexBuffer +{ +protected: + PrimitiveType m_type; + std::vector m_data; + +public: + CVertexBuffer(PrimitiveType type, size_t size) + : m_type(type), m_data(size, Vertex3D{}) + { + + } + + virtual ~CVertexBuffer() + { + + } + + virtual void Update() = 0; + + PrimitiveType GetType() const + { + return m_type; + } + + void SetType(PrimitiveType type) + { + m_type = type; + } + + size_t Size() const + { + return m_data.size(); + } + + void Resize(size_t size) + { + m_data.resize(size); + } + + Vertex3D& operator[](size_t index) + { + return m_data[index]; + } + + const Vertex3D& operator[](size_t index) const + { + return m_data[index]; + } + + void SetData(const Vertex3D* data, size_t offset, size_t count) + { + std::copy(data, data + count, m_data.data() + offset); + } + + auto Data() + { + return m_data.data(); + } + + auto Data() const + { + return m_data.data(); + } + + auto begin() + { + return m_data.begin(); + } + + auto end() + { + return m_data.end(); + } + + auto begin() const + { + return m_data.begin(); + } + + auto end() const + { + return m_data.end(); + } +}; + /** * \class CDevice * \brief Abstract interface of graphics device @@ -431,6 +518,8 @@ public: virtual void DrawPrimitive(PrimitiveType type, const VertexCol *vertices , int vertexCount) = 0; //! Renders primitive using UI renderer virtual void DrawPrimitive(PrimitiveType type, const Vertex2D* vertices, int vertexCount) = 0; + //! Renders 3D primitive + virtual void DrawPrimitive(PrimitiveType type, const Vertex3D* vertices, int vertexCount) = 0; //! Renders primitives composed of lists of vertices with single texture virtual void DrawPrimitives(PrimitiveType type, const Vertex *vertices, @@ -444,17 +533,9 @@ public: virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices, int first[], int count[], int drawCount) = 0; - //! Creates a static buffer composed of given primitives with multitexturing - virtual unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* 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; - - //! Draws a static buffer - virtual void DrawStaticBuffer(unsigned int bufferId) = 0; - - //! Deletes a static buffer - virtual void DestroyStaticBuffer(unsigned int bufferId) = 0; + virtual CVertexBuffer* CreateVertexBuffer(PrimitiveType primitiveType, const Vertex3D* vertices, int vertexCount) = 0; + virtual void DrawVertexBuffer(CVertexBuffer*) = 0; + virtual void DestroyVertexBuffer(CVertexBuffer*) = 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 08bf9339..dbdc2ecd 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -689,8 +689,8 @@ void CEngine::DeleteBaseObject(int baseObjRank) for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { EngineBaseObjDataTier& p3 = p2.next[l3]; - m_device->DestroyStaticBuffer(p3.staticBufferId); - p3.staticBufferId = 0; + m_device->DestroyVertexBuffer(p3.buffer); + p3.buffer = nullptr; } } @@ -714,8 +714,8 @@ void CEngine::DeleteAllBaseObjects() for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { EngineBaseObjDataTier& p3 = p2.next[l3]; - m_device->DestroyStaticBuffer(p3.staticBufferId); - p3.staticBufferId = 0; + m_device->DestroyVertexBuffer(p3.buffer); + p3.buffer = nullptr; } } } @@ -742,7 +742,7 @@ void CEngine::CopyBaseObject(int sourceBaseObjRank, int destBaseObjRank) for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) { EngineBaseObjDataTier& p3 = p2.next[l3]; - p3.staticBufferId = 0; + p3.buffer = nullptr; } } } @@ -800,12 +800,12 @@ void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buff { for (int i = 0; i < static_cast( p3.vertices.size() ); i++) { - p1.bboxMin.x = Math::Min(p3.vertices[i].coord.x, p1.bboxMin.x); - p1.bboxMin.y = Math::Min(p3.vertices[i].coord.y, p1.bboxMin.y); - p1.bboxMin.z = Math::Min(p3.vertices[i].coord.z, p1.bboxMin.z); - p1.bboxMax.x = Math::Max(p3.vertices[i].coord.x, p1.bboxMax.x); - p1.bboxMax.y = Math::Max(p3.vertices[i].coord.y, p1.bboxMax.y); - p1.bboxMax.z = Math::Max(p3.vertices[i].coord.z, p1.bboxMax.z); + p1.bboxMin.x = Math::Min(p3.vertices[i].position.x, p1.bboxMin.x); + p1.bboxMin.y = Math::Min(p3.vertices[i].position.y, p1.bboxMin.y); + p1.bboxMin.z = Math::Min(p3.vertices[i].position.z, p1.bboxMin.z); + p1.bboxMax.x = Math::Max(p3.vertices[i].position.x, p1.bboxMax.x); + p1.bboxMax.y = Math::Max(p3.vertices[i].position.y, p1.bboxMax.y); + p1.bboxMax.z = Math::Max(p3.vertices[i].position.z, p1.bboxMax.z); } p1.boundingSphere = Math::BoundingSphereForBox(p1.bboxMin, p1.bboxMax); @@ -880,7 +880,7 @@ void CEngine::DebugObject(int objRank) l->Debug(" l3:\n"); l->Debug(" type: %d\n", p3.type); l->Debug(" state: %d\n", p3.state); - l->Debug(" staticBufferId: %u\n", p3.staticBufferId); + l->Debug(" staticBufferId: %u\n", p3.buffer); l->Debug(" updateStaticBuffer: %s\n", p3.updateStaticBuffer ? "true" : "false"); } } @@ -1191,45 +1191,45 @@ void CEngine::ChangeTextureMapping(int objRank, const Material& mat, int state, { for (int i = 0; i < nb; i++) { - p4->vertices[i].texCoord.x = p4->vertices[i].coord.z * au + bu; - p4->vertices[i].texCoord.y = p4->vertices[i].coord.y * av + bv; + p4->vertices[i].uv.x = p4->vertices[i].position.z * au + bu; + p4->vertices[i].uv.y = p4->vertices[i].position.y * av + bv; } } else if (mode == ENG_TEX_MAPPING_Y) { for (int i = 0; i < nb; i++) { - p4->vertices[i].texCoord.x = p4->vertices[i].coord.x * au + bu; - p4->vertices[i].texCoord.y = p4->vertices[i].coord.z * av + bv; + p4->vertices[i].uv.x = p4->vertices[i].position.x * au + bu; + p4->vertices[i].uv.y = p4->vertices[i].position.z * av + bv; } } else if (mode == ENG_TEX_MAPPING_Z) { for (int i = 0; i < nb; i++) { - p4->vertices[i].texCoord.x = p4->vertices[i].coord.x * au + bu; - p4->vertices[i].texCoord.y = p4->vertices[i].coord.y * av + bv; + p4->vertices[i].uv.x = p4->vertices[i].position.x * au + bu; + p4->vertices[i].uv.y = p4->vertices[i].position.y * av + bv; } } else if (mode == ENG_TEX_MAPPING_1X) { for (int i = 0; i < nb; i++) { - p4->vertices[i].texCoord.x = p4->vertices[i].coord.x * au + bu; + p4->vertices[i].uv.x = p4->vertices[i].position.x * au + bu; } } else if (mode == ENG_TEX_MAPPING_1Y) { for (int i = 0; i < nb; i++) { - p4->vertices[i].texCoord.y = p4->vertices[i].coord.y * au + bu; + p4->vertices[i].uv.y = p4->vertices[i].position.y * au + bu; } } else if (mode == ENG_TEX_MAPPING_1Z) { for (int i = 0; i < nb; i++) { - p4->vertices[i].texCoord.x = p4->vertices[i].coord.z * au + bu; + p4->vertices[i].uv.x = p4->vertices[i].position.z * au + bu; } } @@ -1251,7 +1251,7 @@ void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, if (tNum < 12 || tNum % 6 != 0) return; - std::vector& vs = p4->vertices; + std::vector& vs = p4->vertices; while (pos < 0.0f) pos += 1.0f; // never negative! @@ -1262,11 +1262,11 @@ void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, { 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)) + if (Math::IsEqual(vs[i].position.x, vs[j+6].position.x) && + Math::IsEqual(vs[i].position.y, vs[j+6].position.y)) { - current.x = vs[i].coord.x; // position end link - current.y = vs[i].coord.y; + current.x = vs[i].position.x; // position end link + current.y = vs[i].position.y; break; } } @@ -1284,8 +1284,8 @@ void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, 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)) + if (Math::IsEqual(vs[tBase + i].position.x, current.x, 0.0001f) && + Math::IsEqual(vs[tBase + i].position.y, current.y, 0.0001f)) { ie[e++] = i; } @@ -1296,8 +1296,8 @@ void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, } 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 + pe = ps + Math::Point(vs[tBase + is[0]].position.x - vs[tBase + ie[0]].position.x, + vs[tBase + is[0]].position.y - vs[tBase + ie[0]].position.y).Length() / factor; // end position on the periphery float pps = ps + pos; float ppe = pe + pos; @@ -1307,8 +1307,8 @@ void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, for (int i = 0; i < 3; i++) { - vs[tBase + is[i]].texCoord.x = ((pps * tl) + ts) / tt; - vs[tBase + ie[i]].texCoord.x = ((ppe * tl) + ts) / tt; + vs[tBase + is[i]].uv.x = ((pps * tl) + ts) / tt; + vs[tBase + ie[i]].uv.x = ((ppe * tl) + ts) / tt; } } @@ -1317,11 +1317,11 @@ void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, 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)) + if (!Math::IsEqual(vs[tBase + i+6].position.x, current.x, 0.0001f) || + !Math::IsEqual(vs[tBase + i+6].position.y, current.y, 0.0001f)) { - current.x = vs[tBase + i+6].coord.x; // end next link - current.y = vs[tBase + i+6].coord.y; + current.x = vs[tBase + i+6].position.x; // end next link + current.y = vs[tBase + i+6].position.y; break; } } @@ -1677,12 +1677,12 @@ void CEngine::UpdateGeometry() for (int i = 0; i < static_cast( p3.vertices.size() ); i++) { - p1.bboxMin.x = Math::Min(p3.vertices[i].coord.x, p1.bboxMin.x); - p1.bboxMin.y = Math::Min(p3.vertices[i].coord.y, p1.bboxMin.y); - p1.bboxMin.z = Math::Min(p3.vertices[i].coord.z, p1.bboxMin.z); - p1.bboxMax.x = Math::Max(p3.vertices[i].coord.x, p1.bboxMax.x); - p1.bboxMax.y = Math::Max(p3.vertices[i].coord.y, p1.bboxMax.y); - p1.bboxMax.z = Math::Max(p3.vertices[i].coord.z, p1.bboxMax.z); + p1.bboxMin.x = Math::Min(p3.vertices[i].position.x, p1.bboxMin.x); + p1.bboxMin.y = Math::Min(p3.vertices[i].position.y, p1.bboxMin.y); + p1.bboxMin.z = Math::Min(p3.vertices[i].position.z, p1.bboxMin.z); + p1.bboxMax.x = Math::Max(p3.vertices[i].position.x, p1.bboxMax.x); + p1.bboxMax.y = Math::Max(p3.vertices[i].position.y, p1.bboxMax.y); + p1.bboxMax.z = Math::Max(p3.vertices[i].position.z, p1.bboxMax.z); } } } @@ -1701,10 +1701,16 @@ void CEngine::UpdateStaticBuffer(EngineBaseObjDataTier& p4) else type = PRIMITIVE_TRIANGLE_STRIP; - if (p4.staticBufferId == 0) - p4.staticBufferId = m_device->CreateStaticBuffer(type, &p4.vertices[0], p4.vertices.size()); + if (p4.buffer == nullptr) + { + p4.buffer = m_device->CreateVertexBuffer(type, &p4.vertices[0], p4.vertices.size()); + } else - m_device->UpdateStaticBuffer(p4.staticBufferId, type, &p4.vertices[0], p4.vertices.size()); + { + p4.buffer->SetType(type); + p4.buffer->SetData(&p4.vertices[0], 0, p4.vertices.size()); + p4.buffer->Update(); + } p4.updateStaticBuffer = false; } @@ -1859,7 +1865,7 @@ int CEngine::DetectObject(Math::Point mouse, Math::Vector& targetPos, bool terra return nearest; } -bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRank, float& dist, Math::Vector& pos) +bool CEngine::DetectTriangle(Math::Point mouse, Vertex3D* triangle, int objRank, float& dist, Math::Vector& pos) { assert(objRank >= 0 && objRank < static_cast(m_objects.size())); @@ -1867,9 +1873,9 @@ bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRan for (int i = 0; i < 3; i++) { - p3D.x = triangle[i].coord.x; - p3D.y = triangle[i].coord.y; - p3D.z = triangle[i].coord.z; + p3D.x = triangle[i].position.x; + p3D.y = triangle[i].position.y; + p3D.z = triangle[i].position.z; if (! TransformPoint(p2D[i], objRank, p3D)) return false; @@ -1906,9 +1912,9 @@ bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRan if (! Math::IsInsideTriangle(a, b, c, mouse)) return false; - Math::Vector a2 = Math::Transform(m_objects[objRank].transform, triangle[0].coord); - Math::Vector b2 = Math::Transform(m_objects[objRank].transform, triangle[1].coord); - Math::Vector c2 = Math::Transform(m_objects[objRank].transform, triangle[2].coord); + Math::Vector a2 = Math::Transform(m_objects[objRank].transform, triangle[0].position); + Math::Vector b2 = Math::Transform(m_objects[objRank].transform, triangle[1].position); + Math::Vector c2 = Math::Transform(m_objects[objRank].transform, triangle[2].position); Math::Vector e = Math::Transform(m_matView.Inverse(), Math::Vector(0.0f, 0.0f, -1.0f)); Math::Vector f = Math::Transform(m_matView.Inverse(), Math::Vector( (mouse.x*2.0f-1.0f)*m_matProj.Inverse().Get(1,1), @@ -4086,9 +4092,9 @@ void CEngine::UseMSAA(bool enable) void CEngine::DrawObject(const EngineBaseObjDataTier& p4) { - if (p4.staticBufferId != 0) + if (p4.buffer != nullptr) { - m_device->DrawStaticBuffer(p4.staticBufferId); + m_device->DrawVertexBuffer(p4.buffer); if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) m_statisticTriangle += p4.vertices.size() / 3; @@ -4099,12 +4105,12 @@ void CEngine::DrawObject(const EngineBaseObjDataTier& p4) { if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) { - m_device->DrawPrimitive(PRIMITIVE_TRIANGLES, &p4.vertices[0], p4.vertices.size()); + m_device->DrawPrimitive(PRIMITIVE_TRIANGLES, p4.vertices.data(), p4.vertices.size()); m_statisticTriangle += p4.vertices.size() / 3; } else { - m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, &p4.vertices[0], p4.vertices.size() ); + m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, p4.vertices.data(), p4.vertices.size() ); m_statisticTriangle += p4.vertices.size() - 2; } } diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index b67124ac..9bf87f7a 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -71,6 +71,7 @@ class CPlanet; class CTerrain; class CPyroManager; class CModelMesh; +class CVertexBuffer; struct ModelShadowSpot; struct ModelTriangle; @@ -154,7 +155,7 @@ enum EngineTriangleType struct EngineTriangle { //! Triangle vertices - VertexTex2 triangle[3]; + Vertex3D triangle[3]; //! Material Material material; //! Render state @@ -196,8 +197,8 @@ struct EngineBaseObjDataTier EngineTriangleType type; Material material; int state; - std::vector vertices; - unsigned int staticBufferId; + std::vector vertices; + CVertexBuffer* buffer; bool updateStaticBuffer; inline EngineBaseObjDataTier(EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES, @@ -206,7 +207,7 @@ struct EngineBaseObjDataTier : type(type) , material(material) , state(state) - , staticBufferId(0) + , buffer(nullptr) , updateStaticBuffer(false) {} }; @@ -1264,7 +1265,7 @@ protected: bool GetBBox2D(int objRank, Math::Point& min, Math::Point& max); //! Detects whether the mouse is in a triangle. - bool DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRank, float& dist, Math::Vector& pos); + bool DetectTriangle(Math::Point mouse, Vertex3D* triangle, int objRank, float& dist, Math::Vector& pos); //! Transforms a 3D point (x, y, z) in 2D space (x, y, -) of the window /** The coordinated p2D.z gives the distance. */ diff --git a/src/graphics/engine/oldmodelmanager.cpp b/src/graphics/engine/oldmodelmanager.cpp index 7207cc7b..5864cf97 100644 --- a/src/graphics/engine/oldmodelmanager.cpp +++ b/src/graphics/engine/oldmodelmanager.cpp @@ -184,9 +184,9 @@ void COldModelManager::Mirror(std::vector& triangles) 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.position.z = -triangles[i].p1.position.z; + triangles[i].p2.position.z = -triangles[i].p2.position.z; + triangles[i].p3.position.z = -triangles[i].p3.position.z; triangles[i].p1.normal.z = -triangles[i].p1.normal.z; triangles[i].p2.normal.z = -triangles[i].p2.normal.z; diff --git a/src/graphics/engine/particle.cpp b/src/graphics/engine/particle.cpp index fa430488..7f2ea957 100644 --- a/src/graphics/engine/particle.cpp +++ b/src/graphics/engine/particle.cpp @@ -399,19 +399,19 @@ int CParticle::CreateFrag(Math::Vector pos, Math::Vector speed, m_totalInterface[t][sheet] ++; Math::Vector p1; - p1.x = m_triangle[i].triangle[0].coord.x; - p1.y = m_triangle[i].triangle[0].coord.y; - p1.z = m_triangle[i].triangle[0].coord.z; + p1.x = m_triangle[i].triangle[0].position.x; + p1.y = m_triangle[i].triangle[0].position.y; + p1.z = m_triangle[i].triangle[0].position.z; Math::Vector p2; - p2.x = m_triangle[i].triangle[1].coord.x; - p2.y = m_triangle[i].triangle[1].coord.y; - p2.z = m_triangle[i].triangle[1].coord.z; + p2.x = m_triangle[i].triangle[1].position.x; + p2.y = m_triangle[i].triangle[1].position.y; + p2.z = m_triangle[i].triangle[1].position.z; Math::Vector p3; - p3.x = m_triangle[i].triangle[2].coord.x; - p3.y = m_triangle[i].triangle[2].coord.y; - p3.z = m_triangle[i].triangle[2].coord.z; + p3.x = m_triangle[i].triangle[2].position.x; + p3.y = m_triangle[i].triangle[2].position.y; + p3.z = m_triangle[i].triangle[2].position.z; float l1 = Math::Distance(p1, p2); float l2 = Math::Distance(p2, p3); @@ -422,17 +422,17 @@ int CParticle::CreateFrag(Math::Vector pos, Math::Vector speed, p2 = Math::Vector( dx, dy, 0.0f); p3 = Math::Vector(-dx, -dy, 0.0f); - m_triangle[i].triangle[0].coord.x = p1.x; - m_triangle[i].triangle[0].coord.y = p1.y; - m_triangle[i].triangle[0].coord.z = p1.z; + m_triangle[i].triangle[0].position.x = p1.x; + m_triangle[i].triangle[0].position.y = p1.y; + m_triangle[i].triangle[0].position.z = p1.z; - m_triangle[i].triangle[1].coord.x = p2.x; - m_triangle[i].triangle[1].coord.y = p2.y; - m_triangle[i].triangle[1].coord.z = p2.z; + m_triangle[i].triangle[1].position.x = p2.x; + m_triangle[i].triangle[1].position.y = p2.y; + m_triangle[i].triangle[1].position.z = p2.z; - m_triangle[i].triangle[2].coord.x = p3.x; - m_triangle[i].triangle[2].coord.y = p3.y; - m_triangle[i].triangle[2].coord.z = p3.z; + m_triangle[i].triangle[2].position.x = p3.x; + m_triangle[i].triangle[2].position.y = p3.y; + m_triangle[i].triangle[2].position.z = p3.z; Math::Vector n(0.0f, 0.0f, -1.0f); diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index 33c144b8..e4d8e603 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -1475,15 +1475,15 @@ void CPyro::CreateTriangle(CObject* obj, ObjectType oType, int part) { Math::Vector p1, p2, p3; - p1.x = buffer[i].triangle[0].coord.x; - p1.y = buffer[i].triangle[0].coord.y; - p1.z = buffer[i].triangle[0].coord.z; - p2.x = buffer[i].triangle[1].coord.x; - p2.y = buffer[i].triangle[1].coord.y; - p2.z = buffer[i].triangle[1].coord.z; - p3.x = buffer[i].triangle[2].coord.x; - p3.y = buffer[i].triangle[2].coord.y; - p3.z = buffer[i].triangle[2].coord.z; + p1.x = buffer[i].triangle[0].position.x; + p1.y = buffer[i].triangle[0].position.y; + p1.z = buffer[i].triangle[0].position.z; + p2.x = buffer[i].triangle[1].position.x; + p2.y = buffer[i].triangle[1].position.y; + p2.z = buffer[i].triangle[1].position.z; + p3.x = buffer[i].triangle[2].position.x; + p3.y = buffer[i].triangle[2].position.y; + p3.z = buffer[i].triangle[2].position.z; float h; @@ -1511,32 +1511,32 @@ void CPyro::CreateTriangle(CObject* obj, ObjectType oType, int part) p1.z = p3.z+((p1.z-p3.z)*5.0f/h); } - buffer[i].triangle[0].coord.x = p1.x; - buffer[i].triangle[0].coord.y = p1.y; - buffer[i].triangle[0].coord.z = p1.z; - buffer[i].triangle[1].coord.x = p2.x; - buffer[i].triangle[1].coord.y = p2.y; - buffer[i].triangle[1].coord.z = p2.z; - buffer[i].triangle[2].coord.x = p3.x; - buffer[i].triangle[2].coord.y = p3.y; - buffer[i].triangle[2].coord.z = p3.z; + buffer[i].triangle[0].position.x = p1.x; + buffer[i].triangle[0].position.y = p1.y; + buffer[i].triangle[0].position.z = p1.z; + buffer[i].triangle[1].position.x = p2.x; + buffer[i].triangle[1].position.y = p2.y; + buffer[i].triangle[1].position.z = p2.z; + buffer[i].triangle[2].position.x = p3.x; + buffer[i].triangle[2].position.y = p3.y; + buffer[i].triangle[2].position.z = p3.z; Math::Vector offset; - offset.x = (buffer[i].triangle[0].coord.x+buffer[i].triangle[1].coord.x+buffer[i].triangle[2].coord.x)/3.0f; - offset.y = (buffer[i].triangle[0].coord.y+buffer[i].triangle[1].coord.y+buffer[i].triangle[2].coord.y)/3.0f; - offset.z = (buffer[i].triangle[0].coord.z+buffer[i].triangle[1].coord.z+buffer[i].triangle[2].coord.z)/3.0f; + offset.x = (buffer[i].triangle[0].position.x+buffer[i].triangle[1].position.x+buffer[i].triangle[2].position.x)/3.0f; + offset.y = (buffer[i].triangle[0].position.y+buffer[i].triangle[1].position.y+buffer[i].triangle[2].position.y)/3.0f; + offset.z = (buffer[i].triangle[0].position.z+buffer[i].triangle[1].position.z+buffer[i].triangle[2].position.z)/3.0f; - buffer[i].triangle[0].coord.x -= offset.x; - buffer[i].triangle[1].coord.x -= offset.x; - buffer[i].triangle[2].coord.x -= offset.x; + buffer[i].triangle[0].position.x -= offset.x; + buffer[i].triangle[1].position.x -= offset.x; + buffer[i].triangle[2].position.x -= offset.x; - buffer[i].triangle[0].coord.y -= offset.y; - buffer[i].triangle[1].coord.y -= offset.y; - buffer[i].triangle[2].coord.y -= offset.y; + buffer[i].triangle[0].position.y -= offset.y; + buffer[i].triangle[1].position.y -= offset.y; + buffer[i].triangle[2].position.y -= offset.y; - buffer[i].triangle[0].coord.z -= offset.z; - buffer[i].triangle[1].coord.z -= offset.z; - buffer[i].triangle[2].coord.z -= offset.z; + buffer[i].triangle[0].position.z -= offset.z; + buffer[i].triangle[1].position.z -= offset.z; + buffer[i].triangle[2].position.z -= offset.z; Math::Vector speed; float mass; diff --git a/src/graphics/model/model_input.cpp b/src/graphics/model/model_input.cpp index 33bc2419..a2b02ca7 100644 --- a/src/graphics/model/model_input.cpp +++ b/src/graphics/model/model_input.cpp @@ -446,9 +446,9 @@ std::vector ModelInput::ReadOldModelV1(std::istream &stream, int continue; ModelTriangle triangle; - triangle.p1.FromVertex(t.p1); - triangle.p2.FromVertex(t.p2); - triangle.p3.FromVertex(t.p3); + triangle.p1 = t.p1; + triangle.p2 = t.p2; + triangle.p3 = t.p3; triangle.ambient = t.material.ambient; triangle.diffuse = t.material.diffuse; @@ -494,9 +494,9 @@ std::vector ModelInput::ReadOldModelV2(std::istream &stream, int continue; ModelTriangle triangle; - triangle.p1.FromVertex(t.p1); - triangle.p2.FromVertex(t.p2); - triangle.p3.FromVertex(t.p3); + triangle.p1 = t.p1; + triangle.p2 = t.p2; + triangle.p3 = t.p3; triangle.ambient = t.material.ambient; triangle.diffuse = t.material.diffuse; diff --git a/src/graphics/model/model_io_structs.h b/src/graphics/model/model_io_structs.h index b5e1f8eb..f972d23b 100644 --- a/src/graphics/model/model_io_structs.h +++ b/src/graphics/model/model_io_structs.h @@ -227,9 +227,9 @@ struct OldModelTriangleV3 { char used = 0; char selected = 0; - VertexTex2 p1; - VertexTex2 p2; - VertexTex2 p3; + Vertex3D p1; + Vertex3D p2; + Vertex3D p3; Material material; char texName[21] = {'\0'}; float min = 0.0f; diff --git a/src/graphics/model/model_output.cpp b/src/graphics/model/model_output.cpp index e15d447d..a4c3b488 100644 --- a/src/graphics/model/model_output.cpp +++ b/src/graphics/model/model_output.cpp @@ -49,10 +49,10 @@ namespace ModelOutput int ConvertToOldState(const ModelTriangle& triangle); - void WriteBinaryVertexTex2(VertexTex2 vertex, std::ostream &stream); + void WriteBinaryVertex3D(const Vertex3D& vertex, std::ostream &stream); void WriteBinaryMaterial(const Material& material, std::ostream &stream); - void WriteTextVertexTex2(const VertexTex2& vertex, std::ostream &stream); + void WriteTextVertex3D(const Vertex3D& vertex, std::ostream &stream); void WriteTextMaterial(const Material& material, std::ostream &stream); } @@ -180,11 +180,11 @@ void ModelOutput::WriteTextMesh(const CModelMesh* mesh, const std::string& meshN for (const ModelTriangle& t : mesh->GetTriangles()) { stream << "p1 "; - WriteTextVertexTex2(t.p1, stream); + WriteTextVertex3D(t.p1, stream); stream << "p2 "; - WriteTextVertexTex2(t.p2, stream); + WriteTextVertex3D(t.p2, stream); stream << "p3 "; - WriteTextVertexTex2(t.p3, stream); + WriteTextVertex3D(t.p3, stream); stream << "mat "; Material material; material.ambient = t.ambient; @@ -287,9 +287,9 @@ void ModelOutput::WriteBinaryModel(const CModel& model, std::ostream &stream) t.variableTex2 = triangle.variableTex2; t.state = ConvertToOldState(triangle); - WriteBinaryVertexTex2(t.p1, stream); - WriteBinaryVertexTex2(t.p2, stream); - WriteBinaryVertexTex2(t.p3, stream); + WriteBinaryVertex3D(t.p1, stream); + WriteBinaryVertex3D(t.p2, stream); + WriteBinaryVertex3D(t.p3, stream); WriteBinaryMaterial(t.material, stream); WriteBinaryString<1>(t.tex1Name, stream); WriteBinaryString<1>(t.tex2Name, stream); @@ -350,9 +350,9 @@ void ModelOutput::WriteOldModel(const CModel& model, std::ostream &stream) /* padding */ WriteBinary<2, unsigned int>(0, stream); - WriteBinaryVertexTex2(t.p1, stream); - WriteBinaryVertexTex2(t.p2, stream); - WriteBinaryVertexTex2(t.p3, stream); + WriteBinaryVertex3D(t.p1, stream); + WriteBinaryVertex3D(t.p2, stream); + WriteBinaryVertex3D(t.p3, stream); WriteBinaryMaterial(t.material, stream); stream.write(t.texName, 20); @@ -413,18 +413,18 @@ int ModelOutput::ConvertToOldState(const ModelTriangle& triangle) return state; } -void ModelOutput::WriteBinaryVertexTex2(VertexTex2 vertex, std::ostream &stream) +void ModelOutput::WriteBinaryVertex3D(const Vertex3D& vertex, std::ostream &stream) { - WriteBinaryFloat(vertex.coord.x, stream); - WriteBinaryFloat(vertex.coord.y, stream); - WriteBinaryFloat(vertex.coord.z, stream); + WriteBinaryFloat(vertex.position.x, stream); + WriteBinaryFloat(vertex.position.y, stream); + WriteBinaryFloat(vertex.position.z, stream); WriteBinaryFloat(vertex.normal.x, stream); WriteBinaryFloat(vertex.normal.y, stream); WriteBinaryFloat(vertex.normal.z, stream); - WriteBinaryFloat(vertex.texCoord.x, stream); - WriteBinaryFloat(vertex.texCoord.y, stream); - WriteBinaryFloat(vertex.texCoord2.x, stream); - WriteBinaryFloat(vertex.texCoord2.y, stream); + WriteBinaryFloat(vertex.uv.x, stream); + WriteBinaryFloat(vertex.uv.y, stream); + WriteBinaryFloat(vertex.uv2.x, stream); + WriteBinaryFloat(vertex.uv2.y, stream); } void ModelOutput::WriteBinaryMaterial(const Material& material, std::ostream &stream) @@ -452,12 +452,12 @@ void ModelOutput::WriteBinaryMaterial(const Material& material, std::ostream &st /* power */ WriteBinaryFloat(0.0f, stream); } -void ModelOutput::WriteTextVertexTex2(const VertexTex2& vertex, std::ostream &stream) +void ModelOutput::WriteTextVertex3D(const Vertex3D& vertex, std::ostream &stream) { - stream << "c " << vertex.coord.x << " " << vertex.coord.y << " " << vertex.coord.z; + stream << "c " << vertex.position.x << " " << vertex.position.y << " " << vertex.position.z; stream << " n " << vertex.normal.x << " " << vertex.normal.y << " " << vertex.normal.z; - stream << " t1 " << vertex.texCoord.x << " " << vertex.texCoord.y; - stream << " t2 " << vertex.texCoord2.x << " " << vertex.texCoord2.y; + stream << " t1 " << vertex.uv.x << " " << vertex.uv.y; + stream << " t2 " << vertex.uv2.x << " " << vertex.uv2.y; stream << std::endl; } diff --git a/src/graphics/model/model_triangle.h b/src/graphics/model/model_triangle.h index ef96eeea..b6d15375 100644 --- a/src/graphics/model/model_triangle.h +++ b/src/graphics/model/model_triangle.h @@ -60,11 +60,11 @@ enum class ModelTransparentMode struct ModelTriangle { //! 1st vertex - VertexTex2 p1; + Vertex3D p1; //! 2nd vertex - VertexTex2 p2; + Vertex3D p2; //! 3rd vertex - VertexTex2 p3; + Vertex3D p3; //! Diffuse color Color diffuse; //! Ambient color diff --git a/src/graphics/opengl/gl33device.cpp b/src/graphics/opengl/gl33device.cpp index 6dcc843a..7e2723fa 100644 --- a/src/graphics/opengl/gl33device.cpp +++ b/src/graphics/opengl/gl33device.cpp @@ -48,6 +48,49 @@ namespace Gfx { +CGL33VertexBuffer::CGL33VertexBuffer(PrimitiveType type, size_t size) + : CVertexBuffer(type, size) +{ + glGenVertexArrays(1, &m_vao); + glBindVertexArray(m_vao); + + glGenBuffers(1, &m_vbo); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glBufferData(GL_ARRAY_BUFFER, m_data.size() * sizeof(Vertex3D), nullptr, GL_STATIC_DRAW); + + // Vertex coordinate + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), reinterpret_cast(offsetof(Vertex3D, position))); + + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), reinterpret_cast(offsetof(Vertex3D, normal))); + + // Color + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex3D), reinterpret_cast(offsetof(Vertex3D, color))); + + // Texture coordinate 0 + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), reinterpret_cast(offsetof(Vertex3D, uv))); + + // Texture coordinate 1 + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), reinterpret_cast(offsetof(Vertex3D, uv2))); +} + +CGL33VertexBuffer::~CGL33VertexBuffer() +{ + glDeleteVertexArrays(1, &m_vao); + glDeleteBuffers(1, &m_vbo); +} + +void CGL33VertexBuffer::Update() +{ + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glBufferSubData(GL_ARRAY_BUFFER, 0, m_data.size() * sizeof(Vertex3D), m_data.data()); +} + CGL33Device::CGL33Device(const DeviceConfig &config) : m_config(config) {} @@ -516,6 +559,11 @@ void CGL33Device::Destroy() m_texturesEnabled.clear(); m_textureStageParams.clear(); + for (auto buffer : m_buffers) + delete buffer; + + m_buffers.clear(); + m_uiRenderer = nullptr; } @@ -1016,8 +1064,6 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int { if (m_updateLights) UpdateLights(); - Vertex* vs = const_cast(vertices); - unsigned int size = vertexCount * sizeof(Vertex); DynamicBuffer& buffer = m_dynamicBuffer; @@ -1025,7 +1071,7 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int BindVAO(buffer.vao); BindVBO(buffer.vbo); - unsigned int offset = UploadVertexData(buffer, vs, size); + unsigned int offset = UploadVertexData(buffer, vertices, size); // Vertex coordinate glEnableVertexAttribArray(0); @@ -1057,8 +1103,6 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, { if (m_updateLights) UpdateLights(); - VertexTex2* vs = const_cast(vertices); - unsigned int size = vertexCount * sizeof(VertexTex2); DynamicBuffer& buffer = m_dynamicBuffer; @@ -1066,7 +1110,7 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, BindVAO(buffer.vao); BindVBO(buffer.vbo); - unsigned int offset = UploadVertexData(buffer, vs, size); + unsigned int offset = UploadVertexData(buffer, vertices, size); // Vertex coordinate glEnableVertexAttribArray(0); @@ -1099,8 +1143,6 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i { if (m_updateLights) UpdateLights(); - VertexCol* vs = const_cast(vertices); - unsigned int size = vertexCount * sizeof(VertexCol); DynamicBuffer& buffer = m_dynamicBuffer; @@ -1108,7 +1150,7 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i BindVAO(buffer.vao); BindVBO(buffer.vbo); - unsigned int offset = UploadVertexData(buffer, vs, size); + unsigned int offset = UploadVertexData(buffer, vertices, size); // Vertex coordinate glEnableVertexAttribArray(0); @@ -1135,6 +1177,47 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); } +void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex3D* vertices, int vertexCount) +{ + if (m_updateLights) UpdateLights(); + + unsigned int size = vertexCount * sizeof(Vertex3D); + + DynamicBuffer& buffer = m_dynamicBuffer; + + BindVAO(buffer.vao); + BindVBO(buffer.vbo); + + unsigned int offset = UploadVertexData(buffer, vertices, size); + + // Vertex coordinate + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), + reinterpret_cast(offset + offsetof(Vertex3D, position))); + + // Normal + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), + reinterpret_cast(offset + offsetof(Vertex3D, normal))); + + // Color + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex3D), + reinterpret_cast(offset + offsetof(Vertex3D, color))); + + // Texture coordinate 0 + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), + reinterpret_cast(offset + offsetof(Vertex3D, uv))); + + // Texture coordinate 1 + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), + reinterpret_cast(offset + offsetof(Vertex3D, uv2))); + + glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); +} + void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex2D* vertices, int vertexCount) { m_uiRenderer->DrawPrimitive(type, vertexCount, vertices); @@ -1145,8 +1228,6 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, { if (m_updateLights) UpdateLights(); - Vertex* vs = const_cast(vertices); - int vertexCount = 0; for (int i = 0; i < drawCount; i++) @@ -1164,7 +1245,7 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices, BindVAO(buffer.vao); BindVBO(buffer.vbo); - unsigned int offset = UploadVertexData(buffer, vs, size); + unsigned int offset = UploadVertexData(buffer, vertices, size); // Vertex coordinate glEnableVertexAttribArray(0); @@ -1197,8 +1278,6 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, { if (m_updateLights) UpdateLights(); - VertexTex2* vs = const_cast(vertices); - int vertexCount = 0; for (int i = 0; i < drawCount; i++) @@ -1216,7 +1295,7 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, BindVAO(buffer.vao); BindVBO(buffer.vbo); - unsigned int offset = UploadVertexData(buffer, vs, size); + unsigned int offset = UploadVertexData(buffer, vertices, size); // Vertex coordinate glEnableVertexAttribArray(0); @@ -1250,8 +1329,6 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, { if (m_updateLights) UpdateLights(); - VertexCol* vs = const_cast(vertices); - int vertexCount = 0; for (int i = 0; i < drawCount; i++) @@ -1269,7 +1346,7 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, BindVAO(buffer.vao); BindVBO(buffer.vbo); - unsigned int offset = UploadVertexData(buffer, vs, size); + unsigned int offset = UploadVertexData(buffer, vertices, size); // Vertex coordinate glEnableVertexAttribArray(0); @@ -1296,189 +1373,38 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices, glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); } -namespace +CVertexBuffer* CGL33Device::CreateVertexBuffer(PrimitiveType primitiveType, const Vertex3D* vertices, int vertexCount) { -template void SetVertexAttributes(); + auto buffer = new CGL33VertexBuffer(primitiveType, vertexCount); -template <> void SetVertexAttributes() -{ - // Vertex coordinate - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, coord))); + buffer->SetData(vertices, 0, vertexCount); + buffer->Update(); - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, normal))); + m_buffers.insert(buffer); - // Color - glDisableVertexAttribArray(2); - glVertexAttrib4f(2, 1.0f, 1.0f, 1.0f, 1.0f); - - // Texture coordinate 0 - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, texCoord))); - - // Texture coordinate 1 - glDisableVertexAttribArray(4); - glVertexAttrib2f(4, 0.0f, 0.0f); + return buffer; } -template <> void SetVertexAttributes() -{ - // Vertex coordinate - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, coord))); - - // Normal - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, normal))); - - // Color - glDisableVertexAttribArray(2); - glVertexAttrib4f(2, 1.0f, 1.0f, 1.0f, 1.0f); - - // Texture coordinate 0 - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, texCoord))); - - // Texture coordinate 1 - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast(offsetof(VertexTex2, texCoord2))); -} - -template <> void SetVertexAttributes() -{ - // Vertex coordinate - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast(offsetof(VertexCol, coord))); - - // Normal - glDisableVertexAttribArray(1); - glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f); - - // Color - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast(offsetof(VertexCol, color))); - - // Texture coordinate 0 - glDisableVertexAttribArray(3); - glVertexAttrib2f(3, 0.0f, 0.0f); - - // Texture coordinate 1 - glDisableVertexAttribArray(4); - glVertexAttrib2f(4, 0.0f, 0.0f); -} -} // namespace - -template -unsigned int CGL33Device::CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) -{ - unsigned int id = 0; - - id = ++m_lastVboId; - - VertexBufferInfo info; - info.primitiveType = primitiveType; - info.vertexType = Vertex::VERTEX_TYPE; - info.vertexCount = vertexCount; - info.size = vertexCount * sizeof(Vertex); - - glGenVertexArrays(1, &info.vao); - BindVAO(info.vao); - - glGenBuffers(1, &info.vbo); - BindVBO(info.vbo); - - glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW); - m_vboMemory += info.size; - - SetVertexAttributes(); - - m_vboObjects[id] = info; - - return id; -} - -template -void CGL33Device::UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) -{ - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; - - VertexBufferInfo& info = (*it).second; - - unsigned int size = vertexCount * sizeof(Vertex); - - bool changed = (info.vertexType != Vertex::VERTEX_TYPE) || (size > info.size); - - if (info.vertexType != Vertex::VERTEX_TYPE) CLogger::GetInstance().Debug("Changing static buffer type\n"); - - info.primitiveType = primitiveType; - info.vertexType = Vertex::VERTEX_TYPE; - info.vertexCount = vertexCount; - - BindVBO(info.vbo); - - if (info.size < size) - { - CLogger::GetInstance().Debug("Resizing static buffer: %d->%d\n", info.size, size); - glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); - m_vboMemory -= info.size; - info.size = size; - m_vboMemory += info.size; - } - else - { - glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices); - } - - if (changed) // Update vertex array bindings - { - BindVAO(info.vao); - - SetVertexAttributes(); - } -} - -void CGL33Device::DrawStaticBuffer(unsigned int bufferId) +void CGL33Device::DrawVertexBuffer(CVertexBuffer* buffer) { if (m_updateLights) UpdateLights(); + if (m_buffers.count(buffer) == 0) return; - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; + auto b = dynamic_cast(buffer); - VertexBufferInfo &info = (*it).second; + BindVAO(b->GetVAO()); - BindVAO(info.vao); - - GLenum mode = TranslateGfxPrimitive(info.primitiveType); - glDrawArrays(mode, 0, info.vertexCount); + GLenum type = TranslateGfxPrimitive(b->GetType()); + glDrawArrays(type, 0, b->Size()); } -void CGL33Device::DestroyStaticBuffer(unsigned int bufferId) +void CGL33Device::DestroyVertexBuffer(CVertexBuffer* buffer) { - auto it = m_vboObjects.find(bufferId); - if (it == m_vboObjects.end()) - return; + if (m_buffers.count(buffer) == 0) return; - VertexBufferInfo &info = (*it).second; + m_buffers.erase(buffer); - if (m_currentVAO == info.vao) - BindVAO(0); - if (m_currentVBO == info.vbo) - BindVBO(0); - - m_vboMemory -= info.size; - - glDeleteBuffers(1, &info.vbo); - glDeleteVertexArrays(1, &info.vao); - - info.vbo = 0; - info.vao = 0; - - m_vboObjects.erase(it); + delete buffer; } /* Based on libwine's implementation */ diff --git a/src/graphics/opengl/gl33device.h b/src/graphics/opengl/gl33device.h index 9d883eea..6baa2af2 100644 --- a/src/graphics/opengl/gl33device.h +++ b/src/graphics/opengl/gl33device.h @@ -38,6 +38,7 @@ #include #include #include +#include // Graphics module namespace @@ -57,6 +58,28 @@ struct DynamicBuffer unsigned int offset = 0; }; +class CGL33VertexBuffer : public CVertexBuffer +{ + GLuint m_vao = 0; + GLuint m_vbo = 0; + +public: + CGL33VertexBuffer(PrimitiveType type, size_t size); + virtual ~CGL33VertexBuffer(); + + virtual void Update() override; + + GLuint GetVAO() const + { + return m_vao; + } + + GLuint GetVBO() const + { + return m_vbo; + } +}; + class CGL33UIRenderer; /** @@ -128,6 +151,8 @@ public: virtual void DrawPrimitive(PrimitiveType type, const Vertex2D* vertices, int vertexCount) override; + virtual void DrawPrimitive(PrimitiveType type, const Vertex3D* vertices, int vertexCount) override; + virtual void DrawPrimitives(PrimitiveType type, const Vertex *vertices, int first[], int count[], int drawCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; @@ -137,16 +162,9 @@ public: virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices, int first[], int count[], int drawCount) override; - unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override - { - return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); - } - void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override - { - UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); - } - void DrawStaticBuffer(unsigned int bufferId) override; - void DestroyStaticBuffer(unsigned int bufferId) override; + CVertexBuffer* CreateVertexBuffer(PrimitiveType primitiveType, const Vertex3D* vertices, int vertexCount) override; + void DrawVertexBuffer(CVertexBuffer*) override; + void DestroyVertexBuffer(CVertexBuffer*) override; int ComputeSphereVisibility(const Math::Vector ¢er, float radius) override; @@ -217,11 +235,6 @@ private: //! Uploads data to dynamic buffer and returns offset to it unsigned int UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size); - template - unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); - template - void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); - private: //! Current config DeviceConfig m_config; @@ -263,20 +276,9 @@ private: //! Free texture unit const int m_freeTexture = 3; - //! Info about static VBO buffers - struct VertexBufferInfo - { - PrimitiveType primitiveType = {}; - GLuint vbo = 0; - GLuint vao = 0; - VertexType vertexType = {}; - int vertexCount = 0; - unsigned int size = 0; - }; - //! Detected capabilities - //! Map of saved VBO objects - std::map m_vboObjects; + //! Set of vertex buffers + std::unordered_set m_buffers; //! Last ID of VBO object unsigned int m_lastVboId = 0; //! Currently bound VBO diff --git a/src/math/point.h b/src/math/point.h index de3bc88a..02fcbcfe 100644 --- a/src/math/point.h +++ b/src/math/point.h @@ -31,6 +31,7 @@ #include #include +#include // Math module namespace @@ -66,6 +67,11 @@ struct Point , y(_y) {} + inline Point(const glm::vec2& point) + : x(point.x) + , y(point.y) + {} + //! Sets the zero point: (0,0) inline void LoadZero() { @@ -84,6 +90,11 @@ struct Point return reinterpret_cast(this); } + operator glm::vec2() const + { + return { x, y }; + } + //! Returns the distance from (0,0) to the point (x,y) inline float Length() { diff --git a/src/math/vector.h b/src/math/vector.h index 9f3a286f..9a01c90e 100644 --- a/src/math/vector.h +++ b/src/math/vector.h @@ -31,7 +31,7 @@ #include #include - +#include // Math module namespace namespace Math @@ -73,6 +73,12 @@ struct Vector , z(_z) {} + inline Vector(const glm::vec3& vector) + : x(vector.x) + , y(vector.y) + , z(vector.z) + {} + //! Loads the zero vector (0, 0, 0) inline void LoadZero() { @@ -91,6 +97,11 @@ struct Vector return reinterpret_cast(this); } + operator glm::vec3() const + { + return { x, y, z }; + } + //! Returns the vector length inline float Length() const {