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