Rewritten particle rendering, now uses its own vertex type for optimization
parent
cac34e259b
commit
a25ce2d5df
|
@ -24,8 +24,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/core/vertex.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
// Graphics module namespace
|
||||
|
@ -35,7 +33,11 @@ namespace Gfx
|
|||
class CVertexBuffer;
|
||||
enum class CullFace : unsigned char;
|
||||
enum class TransparencyMode : unsigned char;
|
||||
struct Color;
|
||||
struct Texture;
|
||||
struct Vertex2D;
|
||||
struct Vertex3D;
|
||||
struct VertexParticle;
|
||||
|
||||
/**
|
||||
* \enum PrimitiveType
|
||||
|
@ -250,7 +252,7 @@ public:
|
|||
virtual void SetTransparency(TransparencyMode mode) = 0;
|
||||
|
||||
//! Draws particles
|
||||
virtual void DrawParticle(PrimitiveType type, int count, const Vertex3D* vertices) = 0;
|
||||
virtual void DrawParticle(PrimitiveType type, int count, const VertexParticle* vertices) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -61,4 +61,15 @@ struct Vertex3D
|
|||
glm::vec3 normal = { 0.0f, 0.0f, 1.0f };
|
||||
};
|
||||
|
||||
/**
|
||||
* \struct VertexParticle
|
||||
* \brief 3D vertex for particle rendering, contains color and UV coordinates
|
||||
*/
|
||||
struct VertexParticle
|
||||
{
|
||||
glm::vec3 position = { 0.0f, 0.0f, 0.0f };
|
||||
glm::u8vec4 color = { 255, 255, 255, 255 };
|
||||
glm::vec2 uv = { 0.0f, 0.0f };
|
||||
};
|
||||
|
||||
} // namespace Gfx
|
||||
|
|
|
@ -244,7 +244,7 @@ void CLightning::Draw()
|
|||
glm::vec3 n = glm::normalize(p1-eye);
|
||||
|
||||
glm::vec3 corner[4];
|
||||
Vertex3D vertex[4];
|
||||
VertexParticle vertex[4];
|
||||
|
||||
for (std::size_t i = 0; i < m_segments.size() - 1; i++)
|
||||
{
|
||||
|
|
|
@ -2604,7 +2604,7 @@ void CParticle::TrackDraw(int i, ParticleType type)
|
|||
glm::vec3 eye = m_engine->GetEyePt();
|
||||
float a = Math::RotateAngle(eye.x-p1.x, eye.z-p1.z);
|
||||
|
||||
Vertex3D vertex[4];
|
||||
VertexParticle vertex[4];
|
||||
glm::vec3 corner[4];
|
||||
|
||||
for (int counter = 0; counter < m_track[i].posUsed-1; counter++)
|
||||
|
@ -2692,7 +2692,16 @@ void CParticle::DrawParticleTriangle(int i)
|
|||
mat[3][2] = pos.z;
|
||||
m_renderer->SetModelMatrix(mat);
|
||||
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLES, 3, m_triangle[i].triangle);
|
||||
VertexParticle vertices[3];
|
||||
|
||||
for (size_t j = 0; j < 3; j++)
|
||||
{
|
||||
vertices[j].position = m_triangle[i].triangle[j].position;
|
||||
vertices[j].color = m_triangle[i].triangle[j].color;
|
||||
vertices[j].uv = m_triangle[i].triangle[j].uv;
|
||||
}
|
||||
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLES, 3, vertices);
|
||||
m_engine->AddStatisticTriangle(1);
|
||||
}
|
||||
|
||||
|
@ -2705,7 +2714,7 @@ void CParticle::DrawParticleNorm(int i)
|
|||
|
||||
|
||||
glm::vec3 corner[4];
|
||||
Vertex3D vertex[4];
|
||||
VertexParticle vertex[4];
|
||||
|
||||
if (m_particle[i].sheet == SH_INTERFACE)
|
||||
{
|
||||
|
@ -2853,7 +2862,7 @@ void CParticle::DrawParticleFlat(int i)
|
|||
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
Vertex3D vertex[4];
|
||||
VertexParticle vertex[4];
|
||||
vertex[0] = { corner[1], white, { m_particle[i].texSup.x, m_particle[i].texSup.y } };
|
||||
vertex[1] = { corner[0], white, { m_particle[i].texInf.x, m_particle[i].texSup.y } };
|
||||
vertex[2] = { corner[3], white, { m_particle[i].texSup.x, m_particle[i].texInf.y } };
|
||||
|
@ -2939,7 +2948,7 @@ void CParticle::DrawParticleFog(int i)
|
|||
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
Vertex3D vertex[4];
|
||||
VertexParticle vertex[4];
|
||||
|
||||
vertex[0] = { corner[1], white, { m_particle[i].texSup.x, m_particle[i].texSup.y } };
|
||||
vertex[1] = { corner[0], white, { m_particle[i].texInf.x, m_particle[i].texSup.y } };
|
||||
|
@ -3067,7 +3076,7 @@ void CParticle::DrawParticleRay(int i)
|
|||
corner[2].z = (Math::Rand()-0.5f)*vario1;
|
||||
corner[3].z = (Math::Rand()-0.5f)*vario1;
|
||||
|
||||
Vertex3D vertex[4];
|
||||
VertexParticle vertex[4];
|
||||
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
|
@ -3164,7 +3173,7 @@ void CParticle::DrawParticleSphere(int i)
|
|||
float deltaRingAngle = Math::PI/numRings;
|
||||
float deltaSegAngle = 2.0f*Math::PI/numSegments;
|
||||
|
||||
std::vector<Vertex3D> vertex(2*16*(16+1));
|
||||
std::vector<VertexParticle> vertex(2*16*(16+1));
|
||||
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
|
@ -3265,7 +3274,7 @@ void CParticle::DrawParticleCylinder(int i)
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<Vertex3D> vertex(2*5*(10+1));
|
||||
std::vector<VertexParticle> vertex(2*5*(10+1));
|
||||
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
|
@ -3360,7 +3369,7 @@ void CParticle::DrawParticleWheel(int i)
|
|||
|
||||
auto color = ColorToIntColor(TraceColorColor(m_wheelTrace[i].color));
|
||||
|
||||
Vertex3D vertex[4];
|
||||
VertexParticle vertex[4];
|
||||
vertex[0] = { pos[0], color, { ts.x, ts.y } };
|
||||
vertex[1] = { pos[1], color, { ti.x, ts.y } };
|
||||
vertex[2] = { pos[2], color, { ts.x, ti.y } };
|
||||
|
@ -3379,7 +3388,7 @@ void CParticle::DrawParticleWheel(int i)
|
|||
|
||||
auto color = ColorToIntColor(TraceColorColor(m_wheelTrace[i].color));
|
||||
|
||||
Vertex3D vertex[4];
|
||||
VertexParticle vertex[4];
|
||||
vertex[0] = { pos[0], color };
|
||||
vertex[1] = { pos[1], color };
|
||||
vertex[2] = { pos[2], color };
|
||||
|
|
|
@ -67,8 +67,6 @@ CGL33ParticleRenderer::CGL33ParticleRenderer(CGL33Device* device)
|
|||
glUseProgram(m_program);
|
||||
|
||||
// Setup uniforms
|
||||
glm::mat4 identity(1.0f);
|
||||
|
||||
m_projectionMatrix = glGetUniformLocation(m_program, "uni_ProjectionMatrix");
|
||||
m_viewMatrix = glGetUniformLocation(m_program, "uni_ViewMatrix");
|
||||
m_modelMatrix = glGetUniformLocation(m_program, "uni_ModelMatrix");
|
||||
|
@ -102,7 +100,8 @@ CGL33ParticleRenderer::CGL33ParticleRenderer(CGL33Device* device)
|
|||
// Generic buffer
|
||||
glGenBuffers(1, &m_bufferVBO);
|
||||
glBindBuffer(GL_COPY_WRITE_BUFFER, m_bufferVBO);
|
||||
glBufferData(GL_COPY_WRITE_BUFFER, m_bufferCapacity, nullptr, GL_STREAM_DRAW);
|
||||
glBufferData(GL_COPY_WRITE_BUFFER, m_bufferCapacity * sizeof(VertexParticle), nullptr, GL_STREAM_DRAW);
|
||||
m_bufferOffset = m_bufferCapacity;
|
||||
|
||||
glGenVertexArrays(1, &m_bufferVAO);
|
||||
glBindVertexArray(m_bufferVAO);
|
||||
|
@ -194,26 +193,52 @@ void CGL33ParticleRenderer::SetTransparency(TransparencyMode mode)
|
|||
m_device->SetTransparency(mode);
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::DrawParticle(PrimitiveType type, int count, const Vertex3D* vertices)
|
||||
void CGL33ParticleRenderer::DrawParticle(PrimitiveType type, int count, const VertexParticle* vertices)
|
||||
{
|
||||
size_t size = count * sizeof(Vertex3D);
|
||||
GLuint total = m_bufferOffset + count;
|
||||
|
||||
if (m_bufferCapacity < size)
|
||||
m_bufferCapacity = size;
|
||||
// Buffer full, orphan
|
||||
if (total >= m_bufferCapacity)
|
||||
{
|
||||
glBufferData(GL_ARRAY_BUFFER, m_bufferCapacity * sizeof(VertexParticle), nullptr, GL_STREAM_DRAW);
|
||||
|
||||
// Send new vertices to GPU
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_bufferVBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, m_bufferCapacity, nullptr, GL_STREAM_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices);
|
||||
m_bufferOffset = 0;
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex3D, position)));
|
||||
// Respecify vertex attributes
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexParticle),
|
||||
reinterpret_cast<void*>(offsetof(VertexParticle, position)));
|
||||
|
||||
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex3D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex3D, color)));
|
||||
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VertexParticle),
|
||||
reinterpret_cast<void*>(offsetof(VertexParticle, color)));
|
||||
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex3D, uv)));
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexParticle),
|
||||
reinterpret_cast<void*>(offsetof(VertexParticle, uv)));
|
||||
}
|
||||
|
||||
glDrawArrays(TranslateGfxPrimitive(type), 0, count);
|
||||
void* ptr = glMapBufferRange(GL_ARRAY_BUFFER,
|
||||
m_bufferOffset * sizeof(VertexParticle),
|
||||
count * sizeof(VertexParticle),
|
||||
GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
auto buffer = reinterpret_cast<VertexParticle*>(ptr);
|
||||
|
||||
std::copy_n(vertices, count, buffer);
|
||||
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferSubData(GL_ARRAY_BUFFER,
|
||||
m_bufferOffset * sizeof(VertexParticle),
|
||||
count * sizeof(VertexParticle),
|
||||
vertices);
|
||||
}
|
||||
|
||||
glDrawArrays(TranslateGfxPrimitive(type),
|
||||
m_bufferOffset,
|
||||
count);
|
||||
|
||||
m_bufferOffset += count;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
virtual void SetTransparency(TransparencyMode mode) override;
|
||||
|
||||
//! Draws particles
|
||||
virtual void DrawParticle(PrimitiveType type, int count, const Vertex3D* vertices) override;
|
||||
virtual void DrawParticle(PrimitiveType type, int count, const VertexParticle* vertices) override;
|
||||
|
||||
private:
|
||||
CGL33Device* const m_device;
|
||||
|
@ -90,7 +90,9 @@ private:
|
|||
// Vertex array object
|
||||
GLuint m_bufferVAO = 0;
|
||||
// VBO capacity
|
||||
GLsizei m_bufferCapacity = 8 * sizeof(Vertex3D);
|
||||
GLsizei m_bufferCapacity = 64 * 1024;
|
||||
// Buffer offset
|
||||
GLsizei m_bufferOffset = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ uniform mat4 uni_ProjectionMatrix;
|
|||
uniform mat4 uni_ViewMatrix;
|
||||
uniform mat4 uni_ModelMatrix;
|
||||
|
||||
uniform vec4 uni_Color;
|
||||
|
||||
out VertexData
|
||||
{
|
||||
vec4 Color;
|
||||
|
@ -37,6 +39,6 @@ void main()
|
|||
{
|
||||
gl_Position = uni_ProjectionMatrix * uni_ViewMatrix * uni_ModelMatrix * in_VertexCoord;
|
||||
|
||||
data.Color = in_Color;
|
||||
data.Color = in_Color * uni_Color;
|
||||
data.TexCoord = in_TexCoord;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue