Added CParticleRenderer and reimplemented particle rendering code to use it
parent
710f448477
commit
048393f448
|
@ -147,6 +147,8 @@ add_library(colobotbase STATIC
|
|||
graphics/opengl/gl33renderers.h
|
||||
graphics/opengl/gl33objectrenderer.cpp
|
||||
graphics/opengl/gl33objectrenderer.h
|
||||
graphics/opengl/gl33particlerenderer.cpp
|
||||
graphics/opengl/gl33particlerenderer.h
|
||||
graphics/opengl/glframebuffer.cpp
|
||||
graphics/opengl/glframebuffer.h
|
||||
graphics/opengl/glutil.cpp
|
||||
|
|
|
@ -48,6 +48,8 @@ class CUIRenderer;
|
|||
class CTerrainRenderer;
|
||||
class CShadowRenderer;
|
||||
class CObjectRenderer;
|
||||
class CParticleRenderer;
|
||||
|
||||
struct FramebufferParams;
|
||||
struct Light;
|
||||
struct Material;
|
||||
|
@ -442,6 +444,8 @@ public:
|
|||
virtual CTerrainRenderer* GetTerrainRenderer() = 0;
|
||||
//! Returns object renderer
|
||||
virtual CObjectRenderer* GetObjectRenderer() = 0;
|
||||
//! Returns particle renderer
|
||||
virtual CParticleRenderer* GetParticleRenderer() = 0;
|
||||
//! Returns shadow renderer
|
||||
virtual CShadowRenderer* GetShadowRenderer() = 0;
|
||||
|
||||
|
|
|
@ -182,6 +182,38 @@ public:
|
|||
virtual void DrawObject(const CVertexBuffer* buffer) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CParticleRenderer
|
||||
* \brief Abstract interface for particle renderers
|
||||
*/
|
||||
class CParticleRenderer : public CRenderer
|
||||
{
|
||||
public:
|
||||
virtual ~CParticleRenderer() { }
|
||||
|
||||
virtual void Begin() = 0;
|
||||
|
||||
virtual void End() = 0;
|
||||
|
||||
//! Sets projection matrix
|
||||
virtual void SetProjectionMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets view matrix
|
||||
virtual void SetViewMatrix(const glm::mat4& matrix) = 0;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) = 0;
|
||||
|
||||
//! Sets color
|
||||
virtual void SetColor(const glm::vec4& color) = 0;
|
||||
//! Sets texture
|
||||
virtual void SetTexture(const Texture& texture) = 0;
|
||||
|
||||
//! Sets transparency mode
|
||||
virtual void SetTransparency(TransparencyMode mode) = 0;
|
||||
|
||||
//! Draws particles
|
||||
virtual void DrawParticle(PrimitiveType type, int count, const Vertex3D* vertices) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CShadowRenderer
|
||||
* \brief Abstract interface for shadow renderers
|
||||
|
|
|
@ -3672,10 +3672,17 @@ void CEngine::Draw3DScene()
|
|||
}
|
||||
m_displayGoto.clear();
|
||||
|
||||
auto particleRenderer = m_device->GetParticleRenderer();
|
||||
particleRenderer->Begin();
|
||||
particleRenderer->SetProjectionMatrix(m_matProj);
|
||||
particleRenderer->SetViewMatrix(m_matView);
|
||||
|
||||
CProfiler::StartPerformanceCounter(PCNT_RENDER_PARTICLE_WORLD);
|
||||
m_particle->DrawParticle(SH_WORLD); // draws the particles of the 3D world
|
||||
CProfiler::StopPerformanceCounter(PCNT_RENDER_PARTICLE_WORLD);
|
||||
|
||||
particleRenderer->End();
|
||||
|
||||
m_device->SetRenderState(RENDER_STATE_LIGHTING, true);
|
||||
|
||||
m_lightning->Draw(); // draws lightning
|
||||
|
@ -4293,9 +4300,17 @@ void CEngine::DrawInterface()
|
|||
|
||||
if (!m_screenshotMode && m_renderInterface)
|
||||
{
|
||||
auto particleRenderer = m_device->GetParticleRenderer();
|
||||
particleRenderer->Begin();
|
||||
particleRenderer->SetProjectionMatrix(m_matProjInterface);
|
||||
particleRenderer->SetViewMatrix(m_matViewInterface);
|
||||
particleRenderer->SetModelMatrix(m_matWorldInterface);
|
||||
|
||||
CProfiler::StartPerformanceCounter(PCNT_RENDER_PARTICLE_IFACE);
|
||||
m_particle->DrawParticle(SH_INTERFACE); // draws the particles of the interface
|
||||
CProfiler::StopPerformanceCounter(PCNT_RENDER_PARTICLE_IFACE);
|
||||
|
||||
particleRenderer->End();
|
||||
}
|
||||
|
||||
// 3D objects drawn in front of interface
|
||||
|
@ -4376,8 +4391,15 @@ void CEngine::DrawInterface()
|
|||
|
||||
renderer->End();
|
||||
|
||||
auto particleRenderer = m_device->GetParticleRenderer();
|
||||
particleRenderer->Begin();
|
||||
particleRenderer->SetProjectionMatrix(m_matProj);
|
||||
particleRenderer->SetViewMatrix(m_matView);
|
||||
|
||||
m_particle->DrawParticle(SH_FRONT); // draws the particles of the 3D world
|
||||
|
||||
particleRenderer->End();
|
||||
|
||||
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, false);
|
||||
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
||||
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "common/logger.h"
|
||||
|
||||
#include "graphics/core/device.h"
|
||||
#include "graphics/core/renderers.h"
|
||||
|
||||
#include "graphics/engine/engine.h"
|
||||
#include "graphics/engine/terrain.h"
|
||||
|
@ -84,6 +85,7 @@ CParticle::~CParticle()
|
|||
void CParticle::SetDevice(CDevice* device)
|
||||
{
|
||||
m_device = device;
|
||||
m_renderer = device->GetParticleRenderer();
|
||||
}
|
||||
|
||||
void CParticle::FlushParticle()
|
||||
|
@ -2505,7 +2507,7 @@ void CParticle::TrackDraw(int i, ParticleType type)
|
|||
}
|
||||
|
||||
glm::mat4 mat = glm::mat4(1.0f);
|
||||
m_device->SetTransform(TRANSFORM_WORLD, mat);
|
||||
m_renderer->SetModelMatrix(mat);
|
||||
|
||||
glm::vec2 texInf{ 0, 0 }, texSup{ 0, 0 };
|
||||
|
||||
|
@ -2601,7 +2603,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);
|
||||
|
||||
Vertex vertex[4];
|
||||
Vertex3D vertex[4];
|
||||
glm::vec3 corner[4];
|
||||
|
||||
for (int counter = 0; counter < m_track[i].posUsed-1; counter++)
|
||||
|
@ -2640,22 +2642,24 @@ void CParticle::TrackDraw(int i, ParticleType type)
|
|||
corner[3].y = p2.y;
|
||||
corner[3].z = rot.y;
|
||||
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
if (p2.y < p1.y)
|
||||
{
|
||||
vertex[0] = { corner[1], n, { texSup.x, texSup.y } };
|
||||
vertex[1] = { corner[0], n, { texInf.x, texSup.y } };
|
||||
vertex[2] = { corner[3], n, { texSup.x, texInf.y } };
|
||||
vertex[3] = { corner[2], n, { texInf.x, texInf.y } };
|
||||
vertex[0] = { corner[1], white, { texSup.x, texSup.y } };
|
||||
vertex[1] = { corner[0], white, { texInf.x, texSup.y } };
|
||||
vertex[2] = { corner[3], white, { texSup.x, texInf.y } };
|
||||
vertex[3] = { corner[2], white, { texInf.x, texInf.y } };
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex[0] = { corner[0], n, { texSup.x, texSup.y } };
|
||||
vertex[1] = { corner[1], n, { texInf.x, texSup.y } };
|
||||
vertex[2] = { corner[2], n, { texSup.x, texInf.y } };
|
||||
vertex[3] = { corner[3], n, { texInf.x, texInf.y } };
|
||||
vertex[0] = { corner[0], white, { texSup.x, texSup.y } };
|
||||
vertex[1] = { corner[1], white, { texInf.x, texSup.y } };
|
||||
vertex[2] = { corner[2], white, { texSup.x, texInf.y } };
|
||||
vertex[3] = { corner[3], white, { texInf.x, texInf.y } };
|
||||
}
|
||||
|
||||
m_device->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, vertex, 4);
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLE_STRIP, 4, vertex);
|
||||
m_engine->AddStatisticTriangle(2);
|
||||
|
||||
if (f2 < 0.0f) break;
|
||||
|
@ -2685,9 +2689,9 @@ void CParticle::DrawParticleTriangle(int i)
|
|||
mat[3][0] = pos.x;
|
||||
mat[3][1] = pos.y;
|
||||
mat[3][2] = pos.z;
|
||||
m_device->SetTransform(TRANSFORM_WORLD, mat);
|
||||
m_renderer->SetModelMatrix(mat);
|
||||
|
||||
m_device->DrawPrimitive(PrimitiveType::TRIANGLES, m_triangle[i].triangle, 3);
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLES, 3, m_triangle[i].triangle);
|
||||
m_engine->AddStatisticTriangle(1);
|
||||
}
|
||||
|
||||
|
@ -2700,7 +2704,7 @@ void CParticle::DrawParticleNorm(int i)
|
|||
|
||||
|
||||
glm::vec3 corner[4];
|
||||
Vertex vertex[4];
|
||||
Vertex3D vertex[4];
|
||||
|
||||
if (m_particle[i].sheet == SH_INTERFACE)
|
||||
{
|
||||
|
@ -2728,12 +2732,14 @@ void CParticle::DrawParticleNorm(int i)
|
|||
corner[3].y = pos.y-dim.y;
|
||||
corner[3].z = 0.0f;
|
||||
|
||||
vertex[0] = { corner[1], n, { m_particle[i].texSup.x, m_particle[i].texSup.y } };
|
||||
vertex[1] = { corner[0], n, { m_particle[i].texInf.x, m_particle[i].texSup.y } };
|
||||
vertex[2] = { corner[3], n, { m_particle[i].texSup.x, m_particle[i].texInf.y } };
|
||||
vertex[3] = { corner[2], n, { m_particle[i].texInf.x, m_particle[i].texInf.y } };
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
m_device->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, 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 } };
|
||||
vertex[3] = { corner[2], white, { m_particle[i].texInf.x, m_particle[i].texInf.y } };
|
||||
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLE_STRIP, 4, vertex);
|
||||
m_engine->AddStatisticTriangle(2);
|
||||
}
|
||||
else
|
||||
|
@ -2755,7 +2761,7 @@ void CParticle::DrawParticleNorm(int i)
|
|||
mat[3][0] = pos.x;
|
||||
mat[3][1] = pos.y;
|
||||
mat[3][2] = pos.z;
|
||||
m_device->SetTransform(TRANSFORM_WORLD, mat);
|
||||
m_renderer->SetModelMatrix(mat);
|
||||
|
||||
glm::vec3 n(0.0f, 0.0f, -1.0f);
|
||||
|
||||
|
@ -2779,12 +2785,14 @@ void CParticle::DrawParticleNorm(int i)
|
|||
corner[3].y = -dim.y;
|
||||
corner[3].z = 0.0f;
|
||||
|
||||
vertex[0] = { corner[1], n, { m_particle[i].texSup.x, m_particle[i].texSup.y } };
|
||||
vertex[1] = { corner[0], n, { m_particle[i].texInf.x, m_particle[i].texSup.y } };
|
||||
vertex[2] = { corner[3], n, { m_particle[i].texSup.x, m_particle[i].texInf.y } };
|
||||
vertex[3] = { corner[2], n, { m_particle[i].texInf.x, m_particle[i].texInf.y } };
|
||||
glm::u8vec4 color = ColorToIntColor(m_particle[i].color);
|
||||
|
||||
m_device->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, vertex, 4, m_particle[i].color);
|
||||
vertex[0] = { corner[1], color, { m_particle[i].texSup.x, m_particle[i].texSup.y } };
|
||||
vertex[1] = { corner[0], color, { m_particle[i].texInf.x, m_particle[i].texSup.y } };
|
||||
vertex[2] = { corner[3], color, { m_particle[i].texSup.x, m_particle[i].texInf.y } };
|
||||
vertex[3] = { corner[2], color, { m_particle[i].texInf.x, m_particle[i].texInf.y } };
|
||||
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLE_STRIP, 4, vertex);
|
||||
m_engine->AddStatisticTriangle(2);
|
||||
}
|
||||
}
|
||||
|
@ -2817,7 +2825,7 @@ void CParticle::DrawParticleFlat(int i)
|
|||
mat[3][0] = pos.x;
|
||||
mat[3][1] = pos.y;
|
||||
mat[3][2] = pos.z;
|
||||
m_device->SetTransform(TRANSFORM_WORLD, mat);
|
||||
m_renderer->SetModelMatrix(mat);
|
||||
|
||||
glm::vec3 n(0.0f, 0.0f, -1.0f);
|
||||
|
||||
|
@ -2842,13 +2850,15 @@ void CParticle::DrawParticleFlat(int i)
|
|||
corner[3].y = -dim.y;
|
||||
corner[3].z = 0.0f;
|
||||
|
||||
Vertex vertex[4];
|
||||
vertex[0] = { corner[1], n, { m_particle[i].texSup.x, m_particle[i].texSup.y } };
|
||||
vertex[1] = { corner[0], n, { m_particle[i].texInf.x, m_particle[i].texSup.y } };
|
||||
vertex[2] = { corner[3], n, { m_particle[i].texSup.x, m_particle[i].texInf.y } };
|
||||
vertex[3] = { corner[2], n, { m_particle[i].texInf.x, m_particle[i].texInf.y } };
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
m_device->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, vertex, 4);
|
||||
Vertex3D 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 } };
|
||||
vertex[3] = { corner[2], white, { m_particle[i].texInf.x, m_particle[i].texInf.y } };
|
||||
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLE_STRIP, 4, vertex);
|
||||
m_engine->AddStatisticTriangle(2);
|
||||
}
|
||||
|
||||
|
@ -2906,9 +2916,7 @@ void CParticle::DrawParticleFog(int i)
|
|||
mat[3][0] = pos.x;
|
||||
mat[3][1] = pos.y;
|
||||
mat[3][2] = pos.z;
|
||||
m_device->SetTransform(TRANSFORM_WORLD, mat);
|
||||
|
||||
glm::vec3 n(0.0f, 0.0f, -1.0f);
|
||||
m_renderer->SetModelMatrix(mat);
|
||||
|
||||
glm::vec3 corner[4];
|
||||
|
||||
|
@ -2928,14 +2936,16 @@ void CParticle::DrawParticleFog(int i)
|
|||
corner[3].y = -dim.y;
|
||||
corner[3].z = 0.0f;
|
||||
|
||||
Vertex vertex[4];
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
vertex[0] = { corner[1], n, { m_particle[i].texSup.x, m_particle[i].texSup.y } };
|
||||
vertex[1] = { corner[0], n, { m_particle[i].texInf.x, m_particle[i].texSup.y } };
|
||||
vertex[2] = { corner[3], n, { m_particle[i].texSup.x, m_particle[i].texInf.y } };
|
||||
vertex[3] = { corner[2], n, { m_particle[i].texInf.x, m_particle[i].texInf.y } };
|
||||
Vertex3D vertex[4];
|
||||
|
||||
m_device->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, 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 } };
|
||||
vertex[3] = { corner[2], white, { m_particle[i].texInf.x, m_particle[i].texInf.y } };
|
||||
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLE_STRIP, 4, vertex);
|
||||
m_engine->AddStatisticTriangle(2);
|
||||
}
|
||||
|
||||
|
@ -2967,7 +2977,7 @@ void CParticle::DrawParticleRay(int i)
|
|||
mat[3][0] = pos.x;
|
||||
mat[3][1] = pos.y;
|
||||
mat[3][2] = pos.z;
|
||||
m_device->SetTransform(TRANSFORM_WORLD, mat);
|
||||
m_renderer->SetModelMatrix(mat);
|
||||
|
||||
glm::vec3 n(0.0f, 0.0f, left ? 1.0f : -1.0f);
|
||||
|
||||
|
@ -3056,7 +3066,9 @@ void CParticle::DrawParticleRay(int i)
|
|||
corner[2].z = (Math::Rand()-0.5f)*vario1;
|
||||
corner[3].z = (Math::Rand()-0.5f)*vario1;
|
||||
|
||||
Vertex vertex[4];
|
||||
Vertex3D vertex[4];
|
||||
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
for (int rank = 0; rank < step; rank++)
|
||||
{
|
||||
|
@ -3084,12 +3096,12 @@ void CParticle::DrawParticleRay(int i)
|
|||
if (r % 4 < 2)
|
||||
Math::Swap(texInf.y, texSup.y);
|
||||
|
||||
vertex[0] = { corner[1], n, { texSup.x, texSup.y } };
|
||||
vertex[1] = { corner[0], n, { texInf.x, texSup.y } };
|
||||
vertex[2] = { corner[3], n, { texSup.x, texInf.y } };
|
||||
vertex[3] = { corner[2], n, { texInf.x, texInf.y } };
|
||||
vertex[0] = { corner[1], white, { texSup.x, texSup.y } };
|
||||
vertex[1] = { corner[0], white, { texInf.x, texSup.y } };
|
||||
vertex[2] = { corner[3], white, { texSup.x, texInf.y } };
|
||||
vertex[3] = { corner[2], white, { texInf.x, texInf.y } };
|
||||
|
||||
m_device->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, vertex, 4);
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLE_STRIP, 4, vertex);
|
||||
m_engine->AddStatisticTriangle(2);
|
||||
}
|
||||
adv += dim.x*2.0f;
|
||||
|
@ -3102,8 +3114,8 @@ void CParticle::DrawParticleSphere(int i)
|
|||
|
||||
if (zoom == 0.0f) return;
|
||||
|
||||
m_engine->SetState(ENG_RSTATE_TTEXTURE_BLACK | ENG_RSTATE_2FACE | ENG_RSTATE_WRAP,
|
||||
IntensityToColor(m_particle[i].intensity));
|
||||
m_renderer->SetTransparency(TransparencyMode::BLACK);
|
||||
m_renderer->SetColor(IntensityToColor(m_particle[i].intensity));
|
||||
|
||||
glm::mat4 mat = glm::mat4(1.0f);
|
||||
mat[0][0] = zoom;
|
||||
|
@ -3124,7 +3136,7 @@ void CParticle::DrawParticleSphere(int i)
|
|||
mat = mat * rot;
|
||||
}
|
||||
|
||||
m_device->SetTransform(TRANSFORM_WORLD, mat);
|
||||
m_renderer->SetModelMatrix(mat);
|
||||
|
||||
glm::vec2 ts, ti;
|
||||
ts.x = m_particle[i].texSup.x;
|
||||
|
@ -3151,7 +3163,9 @@ void CParticle::DrawParticleSphere(int i)
|
|||
float deltaRingAngle = Math::PI/numRings;
|
||||
float deltaSegAngle = 2.0f*Math::PI/numSegments;
|
||||
|
||||
Vertex vertex[2*16*(16+1)];
|
||||
std::vector<Vertex3D> vertex(2*16*(16+1));
|
||||
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
// Generate the group of rings for the sphere.
|
||||
int j = 0;
|
||||
|
@ -3183,15 +3197,16 @@ void CParticle::DrawParticleSphere(int i)
|
|||
tu0 = ts.x+(ti.x-ts.x)*tu0;
|
||||
float tu1 = tu0;
|
||||
|
||||
vertex[j++] = { v0, v0, { tu0, tv0 } };
|
||||
vertex[j++] = { v1, v1, { tu1, tv1 } };
|
||||
vertex[j++] = { v0, white, { tu0, tv0 } };
|
||||
vertex[j++] = { v1, white, { tu1, tv1 } };
|
||||
}
|
||||
}
|
||||
|
||||
m_device->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, vertex, j);
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLE_STRIP, j, vertex.data());
|
||||
m_engine->AddStatisticTriangle(j);
|
||||
|
||||
m_engine->SetState(ENG_RSTATE_TTEXTURE_BLACK, IntensityToColor(m_particle[i].intensity));
|
||||
m_renderer->SetColor(IntensityToColor(m_particle[i].intensity));
|
||||
m_renderer->SetTransparency(TransparencyMode::BLACK);
|
||||
}
|
||||
|
||||
//! Returns the height depending on the progress
|
||||
|
@ -3210,8 +3225,8 @@ void CParticle::DrawParticleCylinder(int i)
|
|||
float diam = m_particle[i].dim.y;
|
||||
if (progress >= 1.0f || zoom == 0.0f) return;
|
||||
|
||||
m_engine->SetState(ENG_RSTATE_TTEXTURE_BLACK | ENG_RSTATE_2FACE | ENG_RSTATE_WRAP,
|
||||
IntensityToColor(m_particle[i].intensity));
|
||||
m_renderer->SetColor(IntensityToColor(m_particle[i].intensity));
|
||||
m_renderer->SetTransparency(TransparencyMode::BLACK);
|
||||
|
||||
glm::mat4 mat = glm::mat4(1.0f);
|
||||
mat[0][0] = zoom;
|
||||
|
@ -3221,7 +3236,7 @@ void CParticle::DrawParticleCylinder(int i)
|
|||
mat[3][1] = m_particle[i].pos.y;
|
||||
mat[3][2] = m_particle[i].pos.z;
|
||||
|
||||
m_device->SetTransform(TRANSFORM_WORLD, mat);
|
||||
m_renderer->SetModelMatrix(mat);
|
||||
|
||||
glm::vec2 ts, ti;
|
||||
ts.x = m_particle[i].texSup.x;
|
||||
|
@ -3249,7 +3264,9 @@ void CParticle::DrawParticleCylinder(int i)
|
|||
}
|
||||
}
|
||||
|
||||
Vertex vertex[2*5*(10+1)];
|
||||
std::vector<Vertex3D> vertex(2*5*(10+1));
|
||||
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
int j = 0;
|
||||
for (int ring = 0; ring < numRings; ring++)
|
||||
|
@ -3278,15 +3295,16 @@ void CParticle::DrawParticleCylinder(int i)
|
|||
tu0 = ts.x+(ti.x-ts.x)*tu0;
|
||||
float tu1 = tu0;
|
||||
|
||||
vertex[j++] = { v0, v0, { tu0, tv0 } };
|
||||
vertex[j++] = { v1, v1, { tu1, tv1 } };
|
||||
vertex[j++] = { v0, white, { tu0, tv0 } };
|
||||
vertex[j++] = { v1, white, { tu1, tv1 } };
|
||||
}
|
||||
}
|
||||
|
||||
m_device->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, vertex, j);
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLE_STRIP, j, vertex.data());
|
||||
m_engine->AddStatisticTriangle(j);
|
||||
|
||||
m_engine->SetState(ENG_RSTATE_TTEXTURE_BLACK, IntensityToColor(m_particle[i].intensity));
|
||||
m_renderer->SetColor(IntensityToColor(m_particle[i].intensity));
|
||||
m_renderer->SetTransparency(TransparencyMode::BLACK);
|
||||
}
|
||||
|
||||
void CParticle::DrawParticleText(int i)
|
||||
|
@ -3294,8 +3312,9 @@ void CParticle::DrawParticleText(int i)
|
|||
CharTexture tex = m_engine->GetText()->GetCharTexture(static_cast<UTF8Char>(m_particle[i].text), FONT_STUDIO, FONT_SIZE_BIG*2.0f);
|
||||
if (tex.id == 0) return;
|
||||
|
||||
m_device->SetTexture(0, tex.id);
|
||||
m_engine->SetState(ENG_RSTATE_TTEXTURE_ALPHA, IntensityToColor(m_particle[i].intensity));
|
||||
m_renderer->SetTexture({ tex.id });
|
||||
m_renderer->SetColor(IntensityToColor(m_particle[i].intensity));
|
||||
m_renderer->SetTransparency(TransparencyMode::ALPHA);
|
||||
|
||||
glm::ivec2 fontTextureSize = m_engine->GetText()->GetFontTextureSize();
|
||||
m_particle[i].texSup.x = static_cast<float>(tex.charPos.x) / fontTextureSize.x;
|
||||
|
@ -3312,10 +3331,14 @@ void CParticle::DrawParticleWheel(int i)
|
|||
float dist = Math::DistanceProjected(m_engine->GetEyePt(), m_wheelTrace[i].pos[0]);
|
||||
if (dist > 300.0f) return;
|
||||
|
||||
glm::u8vec4 white(255);
|
||||
|
||||
if (m_wheelTrace[i].color == TraceColor::BlackArrow || m_wheelTrace[i].color == TraceColor::RedArrow)
|
||||
{
|
||||
m_engine->SetTexture("textures/effect03.png");
|
||||
m_engine->SetState(ENG_RSTATE_ALPHA);
|
||||
auto texture = m_engine->LoadTexture("textures/effect03.png");
|
||||
m_renderer->SetTexture(texture);
|
||||
m_renderer->SetTransparency(TransparencyMode::ALPHA);
|
||||
m_renderer->SetColor({ 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
|
||||
glm::vec3 pos[4];
|
||||
pos[0] = m_wheelTrace[i].pos[0];
|
||||
|
@ -3334,16 +3357,16 @@ void CParticle::DrawParticleWheel(int i)
|
|||
ti.x = ti.x-dp;
|
||||
ti.y = ti.y-dp;
|
||||
|
||||
Vertex vertex[4];
|
||||
vertex[0] = { pos[0], n, { ts.x, ts.y } };
|
||||
vertex[1] = { pos[1], n, { ti.x, ts.y } };
|
||||
vertex[2] = { pos[2], n, { ts.x, ti.y } };
|
||||
vertex[3] = { pos[3], n, { ti.x, ti.y } };
|
||||
auto color = ColorToIntColor(TraceColorColor(m_wheelTrace[i].color));
|
||||
|
||||
m_device->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, vertex, 4, TraceColorColor(m_wheelTrace[i].color));
|
||||
Vertex3D 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 } };
|
||||
vertex[3] = { pos[3], color, { ti.x, ti.y } };
|
||||
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLE_STRIP, 4, vertex);
|
||||
m_engine->AddStatisticTriangle(2);
|
||||
|
||||
m_engine->SetState(ENG_RSTATE_OPAQUE_COLOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3353,30 +3376,21 @@ void CParticle::DrawParticleWheel(int i)
|
|||
pos[2] = m_wheelTrace[i].pos[2];
|
||||
pos[3] = m_wheelTrace[i].pos[3];
|
||||
|
||||
glm::vec3 n(0.0f, 1.0f, 0.0f);
|
||||
auto color = ColorToIntColor(TraceColorColor(m_wheelTrace[i].color));
|
||||
|
||||
Vertex vertex[4];
|
||||
vertex[0] = { pos[0], n };
|
||||
vertex[1] = { pos[1], n };
|
||||
vertex[2] = { pos[2], n };
|
||||
vertex[3] = { pos[3], n };
|
||||
Vertex3D vertex[4];
|
||||
vertex[0] = { pos[0], color };
|
||||
vertex[1] = { pos[1], color };
|
||||
vertex[2] = { pos[2], color };
|
||||
vertex[3] = { pos[3], color };
|
||||
|
||||
m_device->DrawPrimitive(PrimitiveType::TRIANGLE_STRIP, vertex, 4, TraceColorColor(m_wheelTrace[i].color));
|
||||
m_renderer->DrawParticle(PrimitiveType::TRIANGLE_STRIP, 4, vertex);
|
||||
m_engine->AddStatisticTriangle(2);
|
||||
}
|
||||
}
|
||||
|
||||
void CParticle::DrawParticle(int sheet)
|
||||
{
|
||||
Material mat;
|
||||
mat.diffuse.r = 1.0f;
|
||||
mat.diffuse.g = 1.0f;
|
||||
mat.diffuse.b = 1.0f; // white
|
||||
mat.ambient.r = 0.5f;
|
||||
mat.ambient.g = 0.5f;
|
||||
mat.ambient.b = 0.5f;
|
||||
m_engine->SetMaterial(mat);
|
||||
|
||||
// Draw the basic particles of triangles.
|
||||
if (m_totalInterface[0][sheet] > 0)
|
||||
{
|
||||
|
@ -3386,8 +3400,11 @@ void CParticle::DrawParticle(int sheet)
|
|||
if (m_particle[i].sheet != sheet) continue;
|
||||
if (m_particle[i].type == PARTIPART) continue;
|
||||
|
||||
m_engine->SetTexture(!m_triangle[i].tex1Name.empty() ? "textures/"+m_triangle[i].tex1Name : "");
|
||||
m_engine->SetState(m_triangle[i].state);
|
||||
auto texture = m_engine->LoadTexture(!m_triangle[i].tex1Name.empty()
|
||||
? "textures/" + m_triangle[i].tex1Name : "");
|
||||
|
||||
m_renderer->SetTexture(texture);
|
||||
//m_engine->SetState(m_triangle[i].state);
|
||||
DrawParticleTriangle(i);
|
||||
}
|
||||
}
|
||||
|
@ -3395,9 +3412,10 @@ void CParticle::DrawParticle(int sheet)
|
|||
// Draw tire marks.
|
||||
if (m_wheelTraceTotal > 0 && sheet == SH_WORLD)
|
||||
{
|
||||
m_engine->SetState(ENG_RSTATE_OPAQUE_COLOR);
|
||||
glm::mat4 matrix = glm::mat4(1.0f);
|
||||
m_device->SetTransform(TRANSFORM_WORLD, matrix);
|
||||
m_renderer->SetModelMatrix(matrix);
|
||||
m_renderer->SetTransparency(TransparencyMode::NONE);
|
||||
m_renderer->SetColor({ 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
|
||||
for (int i = 0; i < m_wheelTraceTotal; i++)
|
||||
DrawParticleWheel(i);
|
||||
|
@ -3409,10 +3427,15 @@ void CParticle::DrawParticle(int sheet)
|
|||
|
||||
bool loadTexture = false;
|
||||
|
||||
int state;
|
||||
if (t == 4) state = ENG_RSTATE_TTEXTURE_WHITE; // effect03.png
|
||||
else state = ENG_RSTATE_TTEXTURE_BLACK; // effect[00..02].png
|
||||
m_engine->SetState(state);
|
||||
TransparencyMode mode = TransparencyMode::ALPHA;
|
||||
|
||||
if (t == 4)
|
||||
mode = TransparencyMode::WHITE;
|
||||
else
|
||||
mode = TransparencyMode::BLACK;
|
||||
|
||||
m_renderer->SetTransparency(mode);
|
||||
m_renderer->SetColor({ 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
|
||||
for (int j = 0; j < MAXPARTICULE; j++)
|
||||
{
|
||||
|
@ -3424,19 +3447,23 @@ void CParticle::DrawParticle(int sheet)
|
|||
{
|
||||
std::string name;
|
||||
NameParticle(name, t);
|
||||
m_engine->SetTexture("textures/"+name);
|
||||
auto texture = m_engine->LoadTexture("textures/" + name);
|
||||
m_renderer->SetTexture(texture);
|
||||
loadTexture = true;
|
||||
}
|
||||
|
||||
int r = m_particle[i].trackRank;
|
||||
if (r != -1)
|
||||
{
|
||||
m_engine->SetState(state);
|
||||
m_renderer->SetTransparency(mode);
|
||||
m_renderer->SetColor({ 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
//m_engine->SetState(state);
|
||||
TrackDraw(r, m_particle[i].type); // draws the drag
|
||||
if (!m_track[r].drawParticle) continue;
|
||||
}
|
||||
|
||||
m_engine->SetState(state, IntensityToColor(m_particle[i].intensity));
|
||||
m_renderer->SetTransparency(mode);
|
||||
m_renderer->SetColor(IntensityToColor(m_particle[i].intensity));
|
||||
|
||||
if (m_particle[i].ray) // ray?
|
||||
{
|
||||
|
|
|
@ -41,6 +41,8 @@ class CSoundInterface;
|
|||
namespace Gfx
|
||||
{
|
||||
|
||||
class CParticleRenderer;
|
||||
|
||||
const short MAXPARTICULE = 500;
|
||||
const short MAXPARTITYPE = 6;
|
||||
const short MAXTRACK = 100;
|
||||
|
@ -339,6 +341,7 @@ protected:
|
|||
CWater* m_water = nullptr;
|
||||
CRobotMain* m_main = nullptr;
|
||||
CSoundInterface* m_sound = nullptr;
|
||||
CParticleRenderer* m_renderer = nullptr;
|
||||
|
||||
Particle m_particle[MAXPARTICULE*MAXPARTITYPE];
|
||||
EngineTriangle m_triangle[MAXPARTICULE]; // triangle if PartiType == 0
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "graphics/opengl/glframebuffer.h"
|
||||
#include "graphics/opengl/gl33renderers.h"
|
||||
#include "graphics/opengl/gl33objectrenderer.h"
|
||||
#include "graphics/opengl/gl33particlerenderer.h"
|
||||
|
||||
#include "math/geometry.h"
|
||||
|
||||
|
@ -434,6 +435,7 @@ bool CGL33Device::Create()
|
|||
m_uiRenderer = std::make_unique<CGL33UIRenderer>(this);
|
||||
m_terrainRenderer = std::make_unique<CGL33TerrainRenderer>(this);
|
||||
m_objectRenderer = std::make_unique<CGL33ObjectRenderer>(this);
|
||||
m_particleRenderer = std::make_unique<CGL33ParticleRenderer>(this);
|
||||
m_shadowRenderer = std::make_unique<CGL33ShadowRenderer>(this);
|
||||
|
||||
glUseProgram(m_normalProgram);
|
||||
|
@ -501,6 +503,9 @@ void CGL33Device::Destroy()
|
|||
|
||||
m_uiRenderer = nullptr;
|
||||
m_terrainRenderer = nullptr;
|
||||
m_objectRenderer = nullptr;
|
||||
m_particleRenderer = nullptr;
|
||||
m_shadowRenderer = nullptr;
|
||||
}
|
||||
|
||||
void CGL33Device::ConfigChanged(const DeviceConfig& newConfig)
|
||||
|
@ -561,6 +566,11 @@ CObjectRenderer* CGL33Device::GetObjectRenderer()
|
|||
return m_objectRenderer.get();
|
||||
}
|
||||
|
||||
CParticleRenderer* CGL33Device::GetParticleRenderer()
|
||||
{
|
||||
return m_particleRenderer.get();
|
||||
}
|
||||
|
||||
CShadowRenderer* CGL33Device::GetShadowRenderer()
|
||||
{
|
||||
return m_shadowRenderer.get();
|
||||
|
|
|
@ -81,6 +81,7 @@ public:
|
|||
class CGL33UIRenderer;
|
||||
class CGL33TerrainRenderer;
|
||||
class CGL33ObjectRenderer;
|
||||
class CGL33ParticleRenderer;
|
||||
class CGL33ShadowRenderer;
|
||||
|
||||
/**
|
||||
|
@ -118,6 +119,7 @@ public:
|
|||
CUIRenderer* GetUIRenderer() override;
|
||||
CTerrainRenderer* GetTerrainRenderer() override;
|
||||
CObjectRenderer* GetObjectRenderer() override;
|
||||
CParticleRenderer* GetParticleRenderer() override;
|
||||
CShadowRenderer* GetShadowRenderer() override;
|
||||
|
||||
void Restore() override;
|
||||
|
@ -300,6 +302,8 @@ private:
|
|||
std::unique_ptr<CGL33TerrainRenderer> m_terrainRenderer;
|
||||
//! Object renderer
|
||||
std::unique_ptr<CGL33ObjectRenderer> m_objectRenderer;
|
||||
//! Particle renderer
|
||||
std::unique_ptr<CGL33ParticleRenderer> m_particleRenderer;
|
||||
//! Shadow renderer
|
||||
std::unique_ptr<CGL33ShadowRenderer> m_shadowRenderer;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,227 @@
|
|||
#include "graphics/opengl/gl33particlerenderer.h"
|
||||
|
||||
#include "graphics/opengl/gl33device.h"
|
||||
#include "graphics/opengl/glutil.h"
|
||||
|
||||
#include "graphics/core/vertex.h"
|
||||
|
||||
#include "common/logger.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
using namespace Gfx;
|
||||
|
||||
CGL33ParticleRenderer::CGL33ParticleRenderer(CGL33Device* device)
|
||||
: m_device(device)
|
||||
{
|
||||
GetLogger()->Info("Creating CGL33ParticleRenderer\n");
|
||||
|
||||
std::string preamble = LoadSource("shaders/gl33/preamble.glsl");
|
||||
std::string shadowSource = LoadSource("shaders/gl33/shadow.glsl");
|
||||
std::string vsSource = LoadSource("shaders/gl33/particle_vs.glsl");
|
||||
std::string fsSource = LoadSource("shaders/gl33/particle_fs.glsl");
|
||||
|
||||
GLint vsShader = CreateShader(GL_VERTEX_SHADER, { preamble, shadowSource, vsSource });
|
||||
if (vsShader == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create vertex shader from file 'particle_vs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
GLint fsShader = CreateShader(GL_FRAGMENT_SHADER, { preamble, shadowSource, fsSource });
|
||||
if (fsShader == 0)
|
||||
{
|
||||
GetLogger()->Error("Cound not create fragment shader from file 'particle_fs.glsl'\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_program = LinkProgram({ vsShader, fsShader });
|
||||
|
||||
glDeleteShader(vsShader);
|
||||
glDeleteShader(fsShader);
|
||||
|
||||
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");
|
||||
m_fogRange = glGetUniformLocation(m_program, "uni_FogRange");
|
||||
m_fogColor = glGetUniformLocation(m_program, "uni_FogColor");
|
||||
m_color = glGetUniformLocation(m_program, "uni_Color");
|
||||
m_alphaScissor = glGetUniformLocation(m_program, "uni_AlphaScissor");
|
||||
|
||||
// Set texture units
|
||||
auto texture = glGetUniformLocation(m_program, "uni_Texture");
|
||||
glUniform1i(texture, 10);
|
||||
|
||||
glUniform1f(m_alphaScissor, 0.5f);
|
||||
|
||||
// White texture
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glGenTextures(1, &m_whiteTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
// Generic buffer
|
||||
glGenBuffers(1, &m_bufferVBO);
|
||||
glBindBuffer(GL_COPY_WRITE_BUFFER, m_bufferVBO);
|
||||
glBufferData(GL_COPY_WRITE_BUFFER, m_bufferCapacity, nullptr, GL_STREAM_DRAW);
|
||||
|
||||
glGenVertexArrays(1, &m_bufferVAO);
|
||||
glBindVertexArray(m_bufferVAO);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
GetLogger()->Info("CGL33ParticleRenderer created successfully\n");
|
||||
}
|
||||
|
||||
CGL33ParticleRenderer::~CGL33ParticleRenderer()
|
||||
{
|
||||
glDeleteProgram(m_program);
|
||||
glDeleteTextures(1, &m_whiteTexture);
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::Begin()
|
||||
{
|
||||
glUseProgram(m_program);
|
||||
|
||||
glActiveTexture(GL_TEXTURE10);
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
|
||||
m_texture = 0;
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glUniform4f(m_color, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
glBindVertexArray(m_bufferVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_bufferVBO);
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::End()
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE10);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
m_texture = 0;
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
m_device->Restore();
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::SetProjectionMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glUniformMatrix4fv(m_projectionMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::SetViewMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glm::mat4 scale(1.0f);
|
||||
scale[2][2] = -1.0f;
|
||||
|
||||
auto viewMatrix = scale * matrix;
|
||||
|
||||
glUniformMatrix4fv(m_viewMatrix, 1, GL_FALSE, value_ptr(viewMatrix));
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::SetModelMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
glUniformMatrix4fv(m_modelMatrix, 1, GL_FALSE, value_ptr(matrix));
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::SetColor(const glm::vec4& color)
|
||||
{
|
||||
glUniform4f(m_color, color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::SetTexture(const Texture& texture)
|
||||
{
|
||||
if (m_texture == texture.id) return;
|
||||
|
||||
m_texture = texture.id;
|
||||
|
||||
glActiveTexture(GL_TEXTURE10);
|
||||
|
||||
if (texture.id == 0)
|
||||
glBindTexture(GL_TEXTURE_2D, m_whiteTexture);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, texture.id);
|
||||
}
|
||||
|
||||
|
||||
void CGL33ParticleRenderer::SetTransparency(TransparencyMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case TransparencyMode::NONE:
|
||||
glDisable(GL_BLEND);
|
||||
glDepthMask(GL_TRUE);
|
||||
break;
|
||||
case TransparencyMode::ALPHA:
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glDepthMask(GL_TRUE);
|
||||
break;
|
||||
case TransparencyMode::BLACK:
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glDepthMask(GL_FALSE);
|
||||
break;
|
||||
case TransparencyMode::WHITE:
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_DST_COLOR, GL_ZERO);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glDepthMask(GL_FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CGL33ParticleRenderer::DrawParticle(PrimitiveType type, int count, const Vertex3D* vertices)
|
||||
{
|
||||
size_t size = count * sizeof(Vertex3D);
|
||||
|
||||
if (m_bufferCapacity < size)
|
||||
m_bufferCapacity = size;
|
||||
|
||||
// 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);
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex3D, position)));
|
||||
|
||||
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex3D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex3D, color)));
|
||||
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D),
|
||||
reinterpret_cast<void*>(offsetof(Vertex3D, uv)));
|
||||
|
||||
glDrawArrays(TranslateGfxPrimitive(type), 0, count);
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file graphics/opengl/gl33objectrenderer.h
|
||||
* \brief OpenGL 3.3 object renderer
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "graphics/core/renderers.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
// Graphics module namespace
|
||||
namespace Gfx
|
||||
{
|
||||
|
||||
class CGL33Device;
|
||||
|
||||
class CGL33ParticleRenderer : public CParticleRenderer
|
||||
{
|
||||
public:
|
||||
CGL33ParticleRenderer(CGL33Device* device);
|
||||
virtual ~CGL33ParticleRenderer();
|
||||
|
||||
virtual void Begin() override;
|
||||
|
||||
virtual void End() override;
|
||||
|
||||
//! Sets projection matrix
|
||||
virtual void SetProjectionMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets view matrix
|
||||
virtual void SetViewMatrix(const glm::mat4& matrix) override;
|
||||
//! Sets model matrix
|
||||
virtual void SetModelMatrix(const glm::mat4& matrix) override;
|
||||
|
||||
//! Sets color
|
||||
virtual void SetColor(const glm::vec4& color) override;
|
||||
//! Sets texture
|
||||
virtual void SetTexture(const Texture& texture) override;
|
||||
|
||||
//! Sets transparency mode
|
||||
virtual void SetTransparency(TransparencyMode mode) override;
|
||||
|
||||
//! Draws particles
|
||||
virtual void DrawParticle(PrimitiveType type, int count, const Vertex3D* vertices) override;
|
||||
|
||||
private:
|
||||
CGL33Device* const m_device;
|
||||
|
||||
// Uniform data
|
||||
GLint m_projectionMatrix = -1;
|
||||
GLint m_viewMatrix = -1;
|
||||
GLint m_modelMatrix = -1;
|
||||
GLint m_fogRange = -1;
|
||||
GLint m_fogColor = -1;
|
||||
GLint m_color = -1;
|
||||
GLint m_alphaScissor = -1;
|
||||
|
||||
// Shader program
|
||||
GLuint m_program = 0;
|
||||
|
||||
// 1x1 white texture
|
||||
GLuint m_whiteTexture = 0;
|
||||
// Currently bound primary texture
|
||||
GLuint m_texture = 0;
|
||||
|
||||
// Vertex buffer object
|
||||
GLuint m_bufferVBO = 0;
|
||||
// Vertex array object
|
||||
GLuint m_bufferVAO = 0;
|
||||
// VBO capacity
|
||||
GLsizei m_bufferCapacity = 8 * sizeof(Vertex3D);
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// FRAGMENT SHADER - PARTICLE RENDERER
|
||||
|
||||
uniform sampler2D uni_Texture;
|
||||
|
||||
uniform float uni_AlphaScissor;
|
||||
|
||||
in VertexData
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 TexCoord;
|
||||
} data;
|
||||
|
||||
out vec4 out_FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture(uni_Texture, data.TexCoord);
|
||||
|
||||
if (color.a < uni_AlphaScissor) discard;
|
||||
|
||||
out_FragColor = data.Color * color;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* This file is part of the Colobot: Gold Edition source code
|
||||
* Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam
|
||||
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://gnu.org/licenses
|
||||
*/
|
||||
|
||||
// VERTEX SHADER - PARTICLE RENDERER
|
||||
|
||||
layout(location = 0) in vec4 in_VertexCoord;
|
||||
layout(location = 1) in vec4 in_Color;
|
||||
layout(location = 2) in vec2 in_TexCoord;
|
||||
|
||||
uniform mat4 uni_ProjectionMatrix;
|
||||
uniform mat4 uni_ViewMatrix;
|
||||
uniform mat4 uni_ModelMatrix;
|
||||
|
||||
out VertexData
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 TexCoord;
|
||||
} data;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = uni_ProjectionMatrix * uni_ViewMatrix * uni_ModelMatrix * in_VertexCoord;
|
||||
|
||||
data.Color = in_Color;
|
||||
data.TexCoord = in_TexCoord;
|
||||
}
|
Loading…
Reference in New Issue