Added CVertexBuffer and reimplemented vertex buffer management
parent
5c037837f5
commit
100be95113
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class CImage;
|
||||
|
@ -312,6 +313,92 @@ public:
|
|||
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
|
||||
* \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
|
||||
|
|
|
@ -689,8 +689,8 @@ void CEngine::DeleteBaseObject(int baseObjRank)
|
|||
for (int l3 = 0; l3 < static_cast<int>( 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<int>( 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<int>( 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<int>( 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<Gfx::VertexTex2>& vs = p4->vertices;
|
||||
std::vector<Gfx::Vertex3D>& 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<int>( 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<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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<VertexTex2> vertices;
|
||||
unsigned int staticBufferId;
|
||||
std::vector<Vertex3D> 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. */
|
||||
|
|
|
@ -184,9 +184,9 @@ void COldModelManager::Mirror(std::vector<ModelTriangle>& 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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -446,9 +446,9 @@ std::vector<ModelTriangle> 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<ModelTriangle> 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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<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)
|
||||
: 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<Vertex*>(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<VertexTex2*>(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<VertexCol*>(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<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)
|
||||
{
|
||||
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<Vertex*>(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<VertexTex2*>(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<VertexCol*>(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 <typename Vertex> void SetVertexAttributes();
|
||||
auto buffer = new CGL33VertexBuffer(primitiveType, vertexCount);
|
||||
|
||||
template <> void SetVertexAttributes<Vertex>()
|
||||
{
|
||||
// Vertex coordinate
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, coord)));
|
||||
buffer->SetData(vertices, 0, vertexCount);
|
||||
buffer->Update();
|
||||
|
||||
// Normal
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(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<void*>(offsetof(Vertex, texCoord)));
|
||||
|
||||
// Texture coordinate 1
|
||||
glDisableVertexAttribArray(4);
|
||||
glVertexAttrib2f(4, 0.0f, 0.0f);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <> void SetVertexAttributes<VertexTex2>()
|
||||
{
|
||||
// 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)
|
||||
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<CGL33VertexBuffer*>(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 */
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
|
||||
// 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 <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:
|
||||
//! 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<unsigned int, VertexBufferInfo> m_vboObjects;
|
||||
//! Set of vertex buffers
|
||||
std::unordered_set<CVertexBuffer*> m_buffers;
|
||||
//! Last ID of VBO object
|
||||
unsigned int m_lastVboId = 0;
|
||||
//! Currently bound VBO
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
|
||||
// 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<const float*>(this);
|
||||
}
|
||||
|
||||
operator glm::vec2() const
|
||||
{
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
//! Returns the distance from (0,0) to the point (x,y)
|
||||
inline float Length()
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
// 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<const float*>(this);
|
||||
}
|
||||
|
||||
operator glm::vec3() const
|
||||
{
|
||||
return { x, y, z };
|
||||
}
|
||||
|
||||
//! Returns the vector length
|
||||
inline float Length() const
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue