Added CVertexBuffer and reimplemented vertex buffer management

dev
Tomasz Kapuściński 2021-08-08 14:32:14 +02:00
parent 5c037837f5
commit 100be95113
14 changed files with 410 additions and 372 deletions

View File

@ -32,6 +32,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
class CImage; class CImage;
@ -312,6 +313,92 @@ public:
virtual void* GetPixelsData() = 0; virtual void* GetPixelsData() = 0;
}; };
class CVertexBuffer
{
protected:
PrimitiveType m_type;
std::vector<Vertex3D> 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 * \class CDevice
* \brief Abstract interface of graphics device * \brief Abstract interface of graphics device
@ -431,6 +518,8 @@ public:
virtual void DrawPrimitive(PrimitiveType type, const VertexCol *vertices , int vertexCount) = 0; virtual void DrawPrimitive(PrimitiveType type, const VertexCol *vertices , int vertexCount) = 0;
//! Renders primitive using UI renderer //! Renders primitive using UI renderer
virtual void DrawPrimitive(PrimitiveType type, const Vertex2D* vertices, int vertexCount) = 0; 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 //! Renders primitives composed of lists of vertices with single texture
virtual void DrawPrimitives(PrimitiveType type, const Vertex *vertices, virtual void DrawPrimitives(PrimitiveType type, const Vertex *vertices,
@ -444,17 +533,9 @@ public:
virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices, virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
int first[], int count[], int drawCount) = 0; int first[], int count[], int drawCount) = 0;
//! Creates a static buffer composed of given primitives with multitexturing virtual CVertexBuffer* CreateVertexBuffer(PrimitiveType primitiveType, const Vertex3D* vertices, int vertexCount) = 0;
virtual unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) = 0; virtual void DrawVertexBuffer(CVertexBuffer*) = 0;
virtual void DestroyVertexBuffer(CVertexBuffer*) = 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;
//! Tests whether a sphere is (partially) within the frustum volume //! Tests whether a sphere is (partially) within the frustum volume
//! Returns a mask of frustum planes for which the test is positive //! Returns a mask of frustum planes for which the test is positive

View File

@ -689,8 +689,8 @@ void CEngine::DeleteBaseObject(int baseObjRank)
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjDataTier& p3 = p2.next[l3]; EngineBaseObjDataTier& p3 = p2.next[l3];
m_device->DestroyStaticBuffer(p3.staticBufferId); m_device->DestroyVertexBuffer(p3.buffer);
p3.staticBufferId = 0; p3.buffer = nullptr;
} }
} }
@ -714,8 +714,8 @@ void CEngine::DeleteAllBaseObjects()
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjDataTier& p3 = p2.next[l3]; EngineBaseObjDataTier& p3 = p2.next[l3];
m_device->DestroyStaticBuffer(p3.staticBufferId); m_device->DestroyVertexBuffer(p3.buffer);
p3.staticBufferId = 0; p3.buffer = nullptr;
} }
} }
} }
@ -742,7 +742,7 @@ void CEngine::CopyBaseObject(int sourceBaseObjRank, int destBaseObjRank)
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjDataTier& p3 = p2.next[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<int>( p3.vertices.size() ); i++) for (int i = 0; i < static_cast<int>( p3.vertices.size() ); i++)
{ {
p1.bboxMin.x = Math::Min(p3.vertices[i].coord.x, p1.bboxMin.x); p1.bboxMin.x = Math::Min(p3.vertices[i].position.x, p1.bboxMin.x);
p1.bboxMin.y = Math::Min(p3.vertices[i].coord.y, p1.bboxMin.y); p1.bboxMin.y = Math::Min(p3.vertices[i].position.y, p1.bboxMin.y);
p1.bboxMin.z = Math::Min(p3.vertices[i].coord.z, p1.bboxMin.z); p1.bboxMin.z = Math::Min(p3.vertices[i].position.z, p1.bboxMin.z);
p1.bboxMax.x = Math::Max(p3.vertices[i].coord.x, p1.bboxMax.x); p1.bboxMax.x = Math::Max(p3.vertices[i].position.x, p1.bboxMax.x);
p1.bboxMax.y = Math::Max(p3.vertices[i].coord.y, p1.bboxMax.y); p1.bboxMax.y = Math::Max(p3.vertices[i].position.y, p1.bboxMax.y);
p1.bboxMax.z = Math::Max(p3.vertices[i].coord.z, p1.bboxMax.z); p1.bboxMax.z = Math::Max(p3.vertices[i].position.z, p1.bboxMax.z);
} }
p1.boundingSphere = Math::BoundingSphereForBox(p1.bboxMin, p1.bboxMax); p1.boundingSphere = Math::BoundingSphereForBox(p1.bboxMin, p1.bboxMax);
@ -880,7 +880,7 @@ void CEngine::DebugObject(int objRank)
l->Debug(" l3:\n"); l->Debug(" l3:\n");
l->Debug(" type: %d\n", p3.type); l->Debug(" type: %d\n", p3.type);
l->Debug(" state: %d\n", p3.state); 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"); 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++) 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;
p4->vertices[i].texCoord.y = p4->vertices[i].coord.y * av + bv; p4->vertices[i].uv.y = p4->vertices[i].position.y * av + bv;
} }
} }
else if (mode == ENG_TEX_MAPPING_Y) else if (mode == ENG_TEX_MAPPING_Y)
{ {
for (int i = 0; i < nb; i++) 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;
p4->vertices[i].texCoord.y = p4->vertices[i].coord.z * av + bv; p4->vertices[i].uv.y = p4->vertices[i].position.z * av + bv;
} }
} }
else if (mode == ENG_TEX_MAPPING_Z) else if (mode == ENG_TEX_MAPPING_Z)
{ {
for (int i = 0; i < nb; i++) 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;
p4->vertices[i].texCoord.y = p4->vertices[i].coord.y * av + bv; p4->vertices[i].uv.y = p4->vertices[i].position.y * av + bv;
} }
} }
else if (mode == ENG_TEX_MAPPING_1X) else if (mode == ENG_TEX_MAPPING_1X)
{ {
for (int i = 0; i < nb; i++) 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) else if (mode == ENG_TEX_MAPPING_1Y)
{ {
for (int i = 0; i < nb; i++) 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) else if (mode == ENG_TEX_MAPPING_1Z)
{ {
for (int i = 0; i < nb; i++) 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) if (tNum < 12 || tNum % 6 != 0)
return; return;
std::vector<Gfx::VertexTex2>& vs = p4->vertices; std::vector<Gfx::Vertex3D>& vs = p4->vertices;
while (pos < 0.0f) while (pos < 0.0f)
pos += 1.0f; // never negative! 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++) for (int j = 0; j < 6; j++)
{ {
if (Math::IsEqual(vs[i].coord.x, vs[j+6].coord.x) && if (Math::IsEqual(vs[i].position.x, vs[j+6].position.x) &&
Math::IsEqual(vs[i].coord.y, vs[j+6].coord.y)) Math::IsEqual(vs[i].position.y, vs[j+6].position.y))
{ {
current.x = vs[i].coord.x; // position end link current.x = vs[i].position.x; // position end link
current.y = vs[i].coord.y; current.y = vs[i].position.y;
break; break;
} }
} }
@ -1284,8 +1284,8 @@ void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state,
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
if (Math::IsEqual(vs[tBase + i].coord.x, current.x, 0.0001f) && if (Math::IsEqual(vs[tBase + i].position.x, current.x, 0.0001f) &&
Math::IsEqual(vs[tBase + i].coord.y, current.y, 0.0001f)) Math::IsEqual(vs[tBase + i].position.y, current.y, 0.0001f))
{ {
ie[e++] = i; ie[e++] = i;
} }
@ -1296,8 +1296,8 @@ void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state,
} }
if (s == 3 && e == 3) if (s == 3 && e == 3)
{ {
pe = ps + Math::Point(vs[tBase + is[0]].coord.x - vs[tBase + ie[0]].coord.x, pe = ps + Math::Point(vs[tBase + is[0]].position.x - vs[tBase + ie[0]].position.x,
vs[tBase + is[0]].coord.y - vs[tBase + ie[0]].coord.y).Length() / factor; // end position on the periphery vs[tBase + is[0]].position.y - vs[tBase + ie[0]].position.y).Length() / factor; // end position on the periphery
float pps = ps + pos; float pps = ps + pos;
float ppe = pe + 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++) for (int i = 0; i < 3; i++)
{ {
vs[tBase + is[i]].texCoord.x = ((pps * tl) + ts) / tt; vs[tBase + is[i]].uv.x = ((pps * tl) + ts) / tt;
vs[tBase + ie[i]].texCoord.x = ((ppe * 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++) for (int i = 0; i < 6; i++)
{ {
if (!Math::IsEqual(vs[tBase + i+6].coord.x, current.x, 0.0001f) || if (!Math::IsEqual(vs[tBase + i+6].position.x, current.x, 0.0001f) ||
!Math::IsEqual(vs[tBase + i+6].coord.y, current.y, 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.x = vs[tBase + i+6].position.x; // end next link
current.y = vs[tBase + i+6].coord.y; current.y = vs[tBase + i+6].position.y;
break; break;
} }
} }
@ -1677,12 +1677,12 @@ void CEngine::UpdateGeometry()
for (int i = 0; i < static_cast<int>( p3.vertices.size() ); i++) for (int i = 0; i < static_cast<int>( p3.vertices.size() ); i++)
{ {
p1.bboxMin.x = Math::Min(p3.vertices[i].coord.x, p1.bboxMin.x); p1.bboxMin.x = Math::Min(p3.vertices[i].position.x, p1.bboxMin.x);
p1.bboxMin.y = Math::Min(p3.vertices[i].coord.y, p1.bboxMin.y); p1.bboxMin.y = Math::Min(p3.vertices[i].position.y, p1.bboxMin.y);
p1.bboxMin.z = Math::Min(p3.vertices[i].coord.z, p1.bboxMin.z); p1.bboxMin.z = Math::Min(p3.vertices[i].position.z, p1.bboxMin.z);
p1.bboxMax.x = Math::Max(p3.vertices[i].coord.x, p1.bboxMax.x); p1.bboxMax.x = Math::Max(p3.vertices[i].position.x, p1.bboxMax.x);
p1.bboxMax.y = Math::Max(p3.vertices[i].coord.y, p1.bboxMax.y); p1.bboxMax.y = Math::Max(p3.vertices[i].position.y, p1.bboxMax.y);
p1.bboxMax.z = Math::Max(p3.vertices[i].coord.z, p1.bboxMax.z); p1.bboxMax.z = Math::Max(p3.vertices[i].position.z, p1.bboxMax.z);
} }
} }
} }
@ -1701,10 +1701,16 @@ void CEngine::UpdateStaticBuffer(EngineBaseObjDataTier& p4)
else else
type = PRIMITIVE_TRIANGLE_STRIP; type = PRIMITIVE_TRIANGLE_STRIP;
if (p4.staticBufferId == 0) if (p4.buffer == nullptr)
p4.staticBufferId = m_device->CreateStaticBuffer(type, &p4.vertices[0], p4.vertices.size()); {
p4.buffer = m_device->CreateVertexBuffer(type, &p4.vertices[0], p4.vertices.size());
}
else 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; p4.updateStaticBuffer = false;
} }
@ -1859,7 +1865,7 @@ int CEngine::DetectObject(Math::Point mouse, Math::Vector& targetPos, bool terra
return nearest; 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<int>(m_objects.size())); assert(objRank >= 0 && objRank < static_cast<int>(m_objects.size()));
@ -1867,9 +1873,9 @@ bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRan
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
p3D.x = triangle[i].coord.x; p3D.x = triangle[i].position.x;
p3D.y = triangle[i].coord.y; p3D.y = triangle[i].position.y;
p3D.z = triangle[i].coord.z; p3D.z = triangle[i].position.z;
if (! TransformPoint(p2D[i], objRank, p3D)) if (! TransformPoint(p2D[i], objRank, p3D))
return false; return false;
@ -1906,9 +1912,9 @@ bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRan
if (! Math::IsInsideTriangle(a, b, c, mouse)) if (! Math::IsInsideTriangle(a, b, c, mouse))
return false; return false;
Math::Vector a2 = Math::Transform(m_objects[objRank].transform, triangle[0].coord); Math::Vector a2 = Math::Transform(m_objects[objRank].transform, triangle[0].position);
Math::Vector b2 = Math::Transform(m_objects[objRank].transform, triangle[1].coord); Math::Vector b2 = Math::Transform(m_objects[objRank].transform, triangle[1].position);
Math::Vector c2 = Math::Transform(m_objects[objRank].transform, triangle[2].coord); 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 e = Math::Transform(m_matView.Inverse(), Math::Vector(0.0f, 0.0f, -1.0f));
Math::Vector f = Math::Transform(m_matView.Inverse(), Math::Vector( Math::Vector f = Math::Transform(m_matView.Inverse(), Math::Vector(
(mouse.x*2.0f-1.0f)*m_matProj.Inverse().Get(1,1), (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) 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) if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
m_statisticTriangle += p4.vertices.size() / 3; m_statisticTriangle += p4.vertices.size() / 3;
@ -4099,12 +4105,12 @@ void CEngine::DrawObject(const EngineBaseObjDataTier& p4)
{ {
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) 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; m_statisticTriangle += p4.vertices.size() / 3;
} }
else 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; m_statisticTriangle += p4.vertices.size() - 2;
} }
} }

View File

@ -71,6 +71,7 @@ class CPlanet;
class CTerrain; class CTerrain;
class CPyroManager; class CPyroManager;
class CModelMesh; class CModelMesh;
class CVertexBuffer;
struct ModelShadowSpot; struct ModelShadowSpot;
struct ModelTriangle; struct ModelTriangle;
@ -154,7 +155,7 @@ enum EngineTriangleType
struct EngineTriangle struct EngineTriangle
{ {
//! Triangle vertices //! Triangle vertices
VertexTex2 triangle[3]; Vertex3D triangle[3];
//! Material //! Material
Material material; Material material;
//! Render state //! Render state
@ -196,8 +197,8 @@ struct EngineBaseObjDataTier
EngineTriangleType type; EngineTriangleType type;
Material material; Material material;
int state; int state;
std::vector<VertexTex2> vertices; std::vector<Vertex3D> vertices;
unsigned int staticBufferId; CVertexBuffer* buffer;
bool updateStaticBuffer; bool updateStaticBuffer;
inline EngineBaseObjDataTier(EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES, inline EngineBaseObjDataTier(EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES,
@ -206,7 +207,7 @@ struct EngineBaseObjDataTier
: type(type) : type(type)
, material(material) , material(material)
, state(state) , state(state)
, staticBufferId(0) , buffer(nullptr)
, updateStaticBuffer(false) , updateStaticBuffer(false)
{} {}
}; };
@ -1264,7 +1265,7 @@ protected:
bool GetBBox2D(int objRank, Math::Point& min, Math::Point& max); bool GetBBox2D(int objRank, Math::Point& min, Math::Point& max);
//! Detects whether the mouse is in a triangle. //! 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 //! Transforms a 3D point (x, y, z) in 2D space (x, y, -) of the window
/** The coordinated p2D.z gives the distance. */ /** The coordinated p2D.z gives the distance. */

View File

@ -184,9 +184,9 @@ void COldModelManager::Mirror(std::vector<ModelTriangle>& triangles)
triangles[i].p1 = triangles[i].p2; triangles[i].p1 = triangles[i].p2;
triangles[i].p2 = t; triangles[i].p2 = t;
triangles[i].p1.coord.z = -triangles[i].p1.coord.z; triangles[i].p1.position.z = -triangles[i].p1.position.z;
triangles[i].p2.coord.z = -triangles[i].p2.coord.z; triangles[i].p2.position.z = -triangles[i].p2.position.z;
triangles[i].p3.coord.z = -triangles[i].p3.coord.z; triangles[i].p3.position.z = -triangles[i].p3.position.z;
triangles[i].p1.normal.z = -triangles[i].p1.normal.z; triangles[i].p1.normal.z = -triangles[i].p1.normal.z;
triangles[i].p2.normal.z = -triangles[i].p2.normal.z; triangles[i].p2.normal.z = -triangles[i].p2.normal.z;

View File

@ -399,19 +399,19 @@ int CParticle::CreateFrag(Math::Vector pos, Math::Vector speed,
m_totalInterface[t][sheet] ++; m_totalInterface[t][sheet] ++;
Math::Vector p1; Math::Vector p1;
p1.x = m_triangle[i].triangle[0].coord.x; p1.x = m_triangle[i].triangle[0].position.x;
p1.y = m_triangle[i].triangle[0].coord.y; p1.y = m_triangle[i].triangle[0].position.y;
p1.z = m_triangle[i].triangle[0].coord.z; p1.z = m_triangle[i].triangle[0].position.z;
Math::Vector p2; Math::Vector p2;
p2.x = m_triangle[i].triangle[1].coord.x; p2.x = m_triangle[i].triangle[1].position.x;
p2.y = m_triangle[i].triangle[1].coord.y; p2.y = m_triangle[i].triangle[1].position.y;
p2.z = m_triangle[i].triangle[1].coord.z; p2.z = m_triangle[i].triangle[1].position.z;
Math::Vector p3; Math::Vector p3;
p3.x = m_triangle[i].triangle[2].coord.x; p3.x = m_triangle[i].triangle[2].position.x;
p3.y = m_triangle[i].triangle[2].coord.y; p3.y = m_triangle[i].triangle[2].position.y;
p3.z = m_triangle[i].triangle[2].coord.z; p3.z = m_triangle[i].triangle[2].position.z;
float l1 = Math::Distance(p1, p2); float l1 = Math::Distance(p1, p2);
float l2 = Math::Distance(p2, p3); 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); p2 = Math::Vector( dx, dy, 0.0f);
p3 = 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].position.x = p1.x;
m_triangle[i].triangle[0].coord.y = p1.y; m_triangle[i].triangle[0].position.y = p1.y;
m_triangle[i].triangle[0].coord.z = p1.z; m_triangle[i].triangle[0].position.z = p1.z;
m_triangle[i].triangle[1].coord.x = p2.x; m_triangle[i].triangle[1].position.x = p2.x;
m_triangle[i].triangle[1].coord.y = p2.y; m_triangle[i].triangle[1].position.y = p2.y;
m_triangle[i].triangle[1].coord.z = p2.z; m_triangle[i].triangle[1].position.z = p2.z;
m_triangle[i].triangle[2].coord.x = p3.x; m_triangle[i].triangle[2].position.x = p3.x;
m_triangle[i].triangle[2].coord.y = p3.y; m_triangle[i].triangle[2].position.y = p3.y;
m_triangle[i].triangle[2].coord.z = p3.z; m_triangle[i].triangle[2].position.z = p3.z;
Math::Vector n(0.0f, 0.0f, -1.0f); Math::Vector n(0.0f, 0.0f, -1.0f);

View File

@ -1475,15 +1475,15 @@ void CPyro::CreateTriangle(CObject* obj, ObjectType oType, int part)
{ {
Math::Vector p1, p2, p3; Math::Vector p1, p2, p3;
p1.x = buffer[i].triangle[0].coord.x; p1.x = buffer[i].triangle[0].position.x;
p1.y = buffer[i].triangle[0].coord.y; p1.y = buffer[i].triangle[0].position.y;
p1.z = buffer[i].triangle[0].coord.z; p1.z = buffer[i].triangle[0].position.z;
p2.x = buffer[i].triangle[1].coord.x; p2.x = buffer[i].triangle[1].position.x;
p2.y = buffer[i].triangle[1].coord.y; p2.y = buffer[i].triangle[1].position.y;
p2.z = buffer[i].triangle[1].coord.z; p2.z = buffer[i].triangle[1].position.z;
p3.x = buffer[i].triangle[2].coord.x; p3.x = buffer[i].triangle[2].position.x;
p3.y = buffer[i].triangle[2].coord.y; p3.y = buffer[i].triangle[2].position.y;
p3.z = buffer[i].triangle[2].coord.z; p3.z = buffer[i].triangle[2].position.z;
float h; 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); p1.z = p3.z+((p1.z-p3.z)*5.0f/h);
} }
buffer[i].triangle[0].coord.x = p1.x; buffer[i].triangle[0].position.x = p1.x;
buffer[i].triangle[0].coord.y = p1.y; buffer[i].triangle[0].position.y = p1.y;
buffer[i].triangle[0].coord.z = p1.z; buffer[i].triangle[0].position.z = p1.z;
buffer[i].triangle[1].coord.x = p2.x; buffer[i].triangle[1].position.x = p2.x;
buffer[i].triangle[1].coord.y = p2.y; buffer[i].triangle[1].position.y = p2.y;
buffer[i].triangle[1].coord.z = p2.z; buffer[i].triangle[1].position.z = p2.z;
buffer[i].triangle[2].coord.x = p3.x; buffer[i].triangle[2].position.x = p3.x;
buffer[i].triangle[2].coord.y = p3.y; buffer[i].triangle[2].position.y = p3.y;
buffer[i].triangle[2].coord.z = p3.z; buffer[i].triangle[2].position.z = p3.z;
Math::Vector offset; 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.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].coord.y+buffer[i].triangle[1].coord.y+buffer[i].triangle[2].coord.y)/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].coord.z+buffer[i].triangle[1].coord.z+buffer[i].triangle[2].coord.z)/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[0].position.x -= offset.x;
buffer[i].triangle[1].coord.x -= offset.x; buffer[i].triangle[1].position.x -= offset.x;
buffer[i].triangle[2].coord.x -= offset.x; buffer[i].triangle[2].position.x -= offset.x;
buffer[i].triangle[0].coord.y -= offset.y; buffer[i].triangle[0].position.y -= offset.y;
buffer[i].triangle[1].coord.y -= offset.y; buffer[i].triangle[1].position.y -= offset.y;
buffer[i].triangle[2].coord.y -= offset.y; buffer[i].triangle[2].position.y -= offset.y;
buffer[i].triangle[0].coord.z -= offset.z; buffer[i].triangle[0].position.z -= offset.z;
buffer[i].triangle[1].coord.z -= offset.z; buffer[i].triangle[1].position.z -= offset.z;
buffer[i].triangle[2].coord.z -= offset.z; buffer[i].triangle[2].position.z -= offset.z;
Math::Vector speed; Math::Vector speed;
float mass; float mass;

View File

@ -446,9 +446,9 @@ std::vector<ModelTriangle> ModelInput::ReadOldModelV1(std::istream &stream, int
continue; continue;
ModelTriangle triangle; ModelTriangle triangle;
triangle.p1.FromVertex(t.p1); triangle.p1 = t.p1;
triangle.p2.FromVertex(t.p2); triangle.p2 = t.p2;
triangle.p3.FromVertex(t.p3); triangle.p3 = t.p3;
triangle.ambient = t.material.ambient; triangle.ambient = t.material.ambient;
triangle.diffuse = t.material.diffuse; triangle.diffuse = t.material.diffuse;
@ -494,9 +494,9 @@ std::vector<ModelTriangle> ModelInput::ReadOldModelV2(std::istream &stream, int
continue; continue;
ModelTriangle triangle; ModelTriangle triangle;
triangle.p1.FromVertex(t.p1); triangle.p1 = t.p1;
triangle.p2.FromVertex(t.p2); triangle.p2 = t.p2;
triangle.p3.FromVertex(t.p3); triangle.p3 = t.p3;
triangle.ambient = t.material.ambient; triangle.ambient = t.material.ambient;
triangle.diffuse = t.material.diffuse; triangle.diffuse = t.material.diffuse;

View File

@ -227,9 +227,9 @@ struct OldModelTriangleV3
{ {
char used = 0; char used = 0;
char selected = 0; char selected = 0;
VertexTex2 p1; Vertex3D p1;
VertexTex2 p2; Vertex3D p2;
VertexTex2 p3; Vertex3D p3;
Material material; Material material;
char texName[21] = {'\0'}; char texName[21] = {'\0'};
float min = 0.0f; float min = 0.0f;

View File

@ -49,10 +49,10 @@ namespace ModelOutput
int ConvertToOldState(const ModelTriangle& triangle); 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 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); 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()) for (const ModelTriangle& t : mesh->GetTriangles())
{ {
stream << "p1 "; stream << "p1 ";
WriteTextVertexTex2(t.p1, stream); WriteTextVertex3D(t.p1, stream);
stream << "p2 "; stream << "p2 ";
WriteTextVertexTex2(t.p2, stream); WriteTextVertex3D(t.p2, stream);
stream << "p3 "; stream << "p3 ";
WriteTextVertexTex2(t.p3, stream); WriteTextVertex3D(t.p3, stream);
stream << "mat "; stream << "mat ";
Material material; Material material;
material.ambient = t.ambient; material.ambient = t.ambient;
@ -287,9 +287,9 @@ void ModelOutput::WriteBinaryModel(const CModel& model, std::ostream &stream)
t.variableTex2 = triangle.variableTex2; t.variableTex2 = triangle.variableTex2;
t.state = ConvertToOldState(triangle); t.state = ConvertToOldState(triangle);
WriteBinaryVertexTex2(t.p1, stream); WriteBinaryVertex3D(t.p1, stream);
WriteBinaryVertexTex2(t.p2, stream); WriteBinaryVertex3D(t.p2, stream);
WriteBinaryVertexTex2(t.p3, stream); WriteBinaryVertex3D(t.p3, stream);
WriteBinaryMaterial(t.material, stream); WriteBinaryMaterial(t.material, stream);
WriteBinaryString<1>(t.tex1Name, stream); WriteBinaryString<1>(t.tex1Name, stream);
WriteBinaryString<1>(t.tex2Name, 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); /* padding */ WriteBinary<2, unsigned int>(0, stream);
WriteBinaryVertexTex2(t.p1, stream); WriteBinaryVertex3D(t.p1, stream);
WriteBinaryVertexTex2(t.p2, stream); WriteBinaryVertex3D(t.p2, stream);
WriteBinaryVertexTex2(t.p3, stream); WriteBinaryVertex3D(t.p3, stream);
WriteBinaryMaterial(t.material, stream); WriteBinaryMaterial(t.material, stream);
stream.write(t.texName, 20); stream.write(t.texName, 20);
@ -413,18 +413,18 @@ int ModelOutput::ConvertToOldState(const ModelTriangle& triangle)
return state; 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.position.x, stream);
WriteBinaryFloat(vertex.coord.y, stream); WriteBinaryFloat(vertex.position.y, stream);
WriteBinaryFloat(vertex.coord.z, stream); WriteBinaryFloat(vertex.position.z, stream);
WriteBinaryFloat(vertex.normal.x, stream); WriteBinaryFloat(vertex.normal.x, stream);
WriteBinaryFloat(vertex.normal.y, stream); WriteBinaryFloat(vertex.normal.y, stream);
WriteBinaryFloat(vertex.normal.z, stream); WriteBinaryFloat(vertex.normal.z, stream);
WriteBinaryFloat(vertex.texCoord.x, stream); WriteBinaryFloat(vertex.uv.x, stream);
WriteBinaryFloat(vertex.texCoord.y, stream); WriteBinaryFloat(vertex.uv.y, stream);
WriteBinaryFloat(vertex.texCoord2.x, stream); WriteBinaryFloat(vertex.uv2.x, stream);
WriteBinaryFloat(vertex.texCoord2.y, stream); WriteBinaryFloat(vertex.uv2.y, stream);
} }
void ModelOutput::WriteBinaryMaterial(const Material& material, std::ostream &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); /* 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 << " n " << vertex.normal.x << " " << vertex.normal.y << " " << vertex.normal.z;
stream << " t1 " << vertex.texCoord.x << " " << vertex.texCoord.y; stream << " t1 " << vertex.uv.x << " " << vertex.uv.y;
stream << " t2 " << vertex.texCoord2.x << " " << vertex.texCoord2.y; stream << " t2 " << vertex.uv2.x << " " << vertex.uv2.y;
stream << std::endl; stream << std::endl;
} }

View File

@ -60,11 +60,11 @@ enum class ModelTransparentMode
struct ModelTriangle struct ModelTriangle
{ {
//! 1st vertex //! 1st vertex
VertexTex2 p1; Vertex3D p1;
//! 2nd vertex //! 2nd vertex
VertexTex2 p2; Vertex3D p2;
//! 3rd vertex //! 3rd vertex
VertexTex2 p3; Vertex3D p3;
//! Diffuse color //! Diffuse color
Color diffuse; Color diffuse;
//! Ambient color //! Ambient color

View File

@ -48,6 +48,49 @@
namespace Gfx 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<void*>(offsetof(Vertex3D, position)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), reinterpret_cast<void*>(offsetof(Vertex3D, normal)));
// Color
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex3D), reinterpret_cast<void*>(offsetof(Vertex3D, color)));
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), reinterpret_cast<void*>(offsetof(Vertex3D, uv)));
// Texture coordinate 1
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), reinterpret_cast<void*>(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) CGL33Device::CGL33Device(const DeviceConfig &config)
: m_config(config) : m_config(config)
{} {}
@ -516,6 +559,11 @@ void CGL33Device::Destroy()
m_texturesEnabled.clear(); m_texturesEnabled.clear();
m_textureStageParams.clear(); m_textureStageParams.clear();
for (auto buffer : m_buffers)
delete buffer;
m_buffers.clear();
m_uiRenderer = nullptr; m_uiRenderer = nullptr;
} }
@ -1016,8 +1064,6 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int
{ {
if (m_updateLights) UpdateLights(); if (m_updateLights) UpdateLights();
Vertex* vs = const_cast<Vertex*>(vertices);
unsigned int size = vertexCount * sizeof(Vertex); unsigned int size = vertexCount * sizeof(Vertex);
DynamicBuffer& buffer = m_dynamicBuffer; DynamicBuffer& buffer = m_dynamicBuffer;
@ -1025,7 +1071,7 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int
BindVAO(buffer.vao); BindVAO(buffer.vao);
BindVBO(buffer.vbo); BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size); unsigned int offset = UploadVertexData(buffer, vertices, size);
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -1057,8 +1103,6 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices,
{ {
if (m_updateLights) UpdateLights(); if (m_updateLights) UpdateLights();
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
unsigned int size = vertexCount * sizeof(VertexTex2); unsigned int size = vertexCount * sizeof(VertexTex2);
DynamicBuffer& buffer = m_dynamicBuffer; DynamicBuffer& buffer = m_dynamicBuffer;
@ -1066,7 +1110,7 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices,
BindVAO(buffer.vao); BindVAO(buffer.vao);
BindVBO(buffer.vbo); BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size); unsigned int offset = UploadVertexData(buffer, vertices, size);
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -1099,8 +1143,6 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
{ {
if (m_updateLights) UpdateLights(); if (m_updateLights) UpdateLights();
VertexCol* vs = const_cast<VertexCol*>(vertices);
unsigned int size = vertexCount * sizeof(VertexCol); unsigned int size = vertexCount * sizeof(VertexCol);
DynamicBuffer& buffer = m_dynamicBuffer; DynamicBuffer& buffer = m_dynamicBuffer;
@ -1108,7 +1150,7 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
BindVAO(buffer.vao); BindVAO(buffer.vao);
BindVBO(buffer.vbo); BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size); unsigned int offset = UploadVertexData(buffer, vertices, size);
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -1135,6 +1177,47 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount); 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<void*>(offset + offsetof(Vertex3D, position)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
reinterpret_cast<void*>(offset + offsetof(Vertex3D, normal)));
// Color
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex3D),
reinterpret_cast<void*>(offset + offsetof(Vertex3D, color)));
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
reinterpret_cast<void*>(offset + offsetof(Vertex3D, uv)));
// Texture coordinate 1
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
reinterpret_cast<void*>(offset + offsetof(Vertex3D, uv2)));
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
}
void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex2D* vertices, int vertexCount) void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex2D* vertices, int vertexCount)
{ {
m_uiRenderer->DrawPrimitive(type, vertexCount, vertices); m_uiRenderer->DrawPrimitive(type, vertexCount, vertices);
@ -1145,8 +1228,6 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
{ {
if (m_updateLights) UpdateLights(); if (m_updateLights) UpdateLights();
Vertex* vs = const_cast<Vertex*>(vertices);
int vertexCount = 0; int vertexCount = 0;
for (int i = 0; i < drawCount; i++) for (int i = 0; i < drawCount; i++)
@ -1164,7 +1245,7 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
BindVAO(buffer.vao); BindVAO(buffer.vao);
BindVBO(buffer.vbo); BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size); unsigned int offset = UploadVertexData(buffer, vertices, size);
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -1197,8 +1278,6 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
{ {
if (m_updateLights) UpdateLights(); if (m_updateLights) UpdateLights();
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
int vertexCount = 0; int vertexCount = 0;
for (int i = 0; i < drawCount; i++) for (int i = 0; i < drawCount; i++)
@ -1216,7 +1295,7 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
BindVAO(buffer.vao); BindVAO(buffer.vao);
BindVBO(buffer.vbo); BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size); unsigned int offset = UploadVertexData(buffer, vertices, size);
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -1250,8 +1329,6 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
{ {
if (m_updateLights) UpdateLights(); if (m_updateLights) UpdateLights();
VertexCol* vs = const_cast<VertexCol*>(vertices);
int vertexCount = 0; int vertexCount = 0;
for (int i = 0; i < drawCount; i++) for (int i = 0; i < drawCount; i++)
@ -1269,7 +1346,7 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
BindVAO(buffer.vao); BindVAO(buffer.vao);
BindVBO(buffer.vbo); BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size); unsigned int offset = UploadVertexData(buffer, vertices, size);
// Vertex coordinate // Vertex coordinate
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -1296,189 +1373,38 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount); glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
} }
namespace CVertexBuffer* CGL33Device::CreateVertexBuffer(PrimitiveType primitiveType, const Vertex3D* vertices, int vertexCount)
{ {
template <typename Vertex> void SetVertexAttributes(); auto buffer = new CGL33VertexBuffer(primitiveType, vertexCount);
template <> void SetVertexAttributes<Vertex>() buffer->SetData(vertices, 0, vertexCount);
{ buffer->Update();
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, coord)));
// Normal m_buffers.insert(buffer);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)));
// Color return buffer;
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<void*>(offsetof(Vertex, texCoord)));
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
} }
template <> void SetVertexAttributes<VertexTex2>() void CGL33Device::DrawVertexBuffer(CVertexBuffer* buffer)
{
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast<void*>(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<void*>(offsetof(VertexTex2, texCoord)));
// Texture coordinate 1
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast<void*>(offsetof(VertexTex2, texCoord2)));
}
template <> void SetVertexAttributes<VertexCol>()
{
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast<void*>(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<void*>(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 <typename Vertex>
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<Vertex>();
m_vboObjects[id] = info;
return id;
}
template <typename Vertex>
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<Vertex>();
}
}
void CGL33Device::DrawStaticBuffer(unsigned int bufferId)
{ {
if (m_updateLights) UpdateLights(); if (m_updateLights) UpdateLights();
if (m_buffers.count(buffer) == 0) return;
auto it = m_vboObjects.find(bufferId); auto b = dynamic_cast<CGL33VertexBuffer*>(buffer);
if (it == m_vboObjects.end())
return;
VertexBufferInfo &info = (*it).second; BindVAO(b->GetVAO());
BindVAO(info.vao); GLenum type = TranslateGfxPrimitive(b->GetType());
glDrawArrays(type, 0, b->Size());
GLenum mode = TranslateGfxPrimitive(info.primitiveType);
glDrawArrays(mode, 0, info.vertexCount);
} }
void CGL33Device::DestroyStaticBuffer(unsigned int bufferId) void CGL33Device::DestroyVertexBuffer(CVertexBuffer* buffer)
{ {
auto it = m_vboObjects.find(bufferId); if (m_buffers.count(buffer) == 0) return;
if (it == m_vboObjects.end())
return;
VertexBufferInfo &info = (*it).second; m_buffers.erase(buffer);
if (m_currentVAO == info.vao) delete buffer;
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);
} }
/* Based on libwine's implementation */ /* Based on libwine's implementation */

View File

@ -38,6 +38,7 @@
#include <set> #include <set>
#include <string> #include <string>
#include <vector> #include <vector>
#include <unordered_set>
// Graphics module namespace // Graphics module namespace
@ -57,6 +58,28 @@ struct DynamicBuffer
unsigned int offset = 0; 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; class CGL33UIRenderer;
/** /**
@ -128,6 +151,8 @@ public:
virtual void DrawPrimitive(PrimitiveType type, const Vertex2D* vertices, int vertexCount) override; 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, virtual void DrawPrimitives(PrimitiveType type, const Vertex *vertices,
int first[], int count[], int drawCount, int first[], int count[], int drawCount,
Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; 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, virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
int first[], int count[], int drawCount) override; int first[], int count[], int drawCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override CVertexBuffer* CreateVertexBuffer(PrimitiveType primitiveType, const Vertex3D* vertices, int vertexCount) override;
{ void DrawVertexBuffer(CVertexBuffer*) override;
return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); void DestroyVertexBuffer(CVertexBuffer*) override;
}
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;
int ComputeSphereVisibility(const Math::Vector &center, float radius) override; int ComputeSphereVisibility(const Math::Vector &center, float radius) override;
@ -217,11 +235,6 @@ private:
//! Uploads data to dynamic buffer and returns offset to it //! Uploads data to dynamic buffer and returns offset to it
unsigned int UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size); unsigned int UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size);
template <typename Vertex>
unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount);
template <typename Vertex>
void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount);
private: private:
//! Current config //! Current config
DeviceConfig m_config; DeviceConfig m_config;
@ -263,20 +276,9 @@ private:
//! Free texture unit //! Free texture unit
const int m_freeTexture = 3; 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 //! Detected capabilities
//! Map of saved VBO objects //! Set of vertex buffers
std::map<unsigned int, VertexBufferInfo> m_vboObjects; std::unordered_set<CVertexBuffer*> m_buffers;
//! Last ID of VBO object //! Last ID of VBO object
unsigned int m_lastVboId = 0; unsigned int m_lastVboId = 0;
//! Currently bound VBO //! Currently bound VBO

View File

@ -31,6 +31,7 @@
#include <cmath> #include <cmath>
#include <sstream> #include <sstream>
#include <glm/glm.hpp>
// Math module namespace // Math module namespace
@ -66,6 +67,11 @@ struct Point
, y(_y) , y(_y)
{} {}
inline Point(const glm::vec2& point)
: x(point.x)
, y(point.y)
{}
//! Sets the zero point: (0,0) //! Sets the zero point: (0,0)
inline void LoadZero() inline void LoadZero()
{ {
@ -84,6 +90,11 @@ struct Point
return reinterpret_cast<const float*>(this); return reinterpret_cast<const float*>(this);
} }
operator glm::vec2() const
{
return { x, y };
}
//! Returns the distance from (0,0) to the point (x,y) //! Returns the distance from (0,0) to the point (x,y)
inline float Length() inline float Length()
{ {

View File

@ -31,7 +31,7 @@
#include <cmath> #include <cmath>
#include <sstream> #include <sstream>
#include <glm/glm.hpp>
// Math module namespace // Math module namespace
namespace Math namespace Math
@ -73,6 +73,12 @@ struct Vector
, z(_z) , z(_z)
{} {}
inline Vector(const glm::vec3& vector)
: x(vector.x)
, y(vector.y)
, z(vector.z)
{}
//! Loads the zero vector (0, 0, 0) //! Loads the zero vector (0, 0, 0)
inline void LoadZero() inline void LoadZero()
{ {
@ -91,6 +97,11 @@ struct Vector
return reinterpret_cast<const float*>(this); return reinterpret_cast<const float*>(this);
} }
operator glm::vec3() const
{
return { x, y, z };
}
//! Returns the vector length //! Returns the vector length
inline float Length() const inline float Length() const
{ {