OpenClonk
C4ParticleChunk Class Reference

#include <C4Particles.h>

Public Member Functions

 C4ParticleChunk ()
 
 C4ParticleChunk (const C4ParticleChunk &)=delete
 
C4ParticleChunkoperator= (const C4ParticleChunk &)=delete
 
 ~C4ParticleChunk ()
 
void Clear ()
 
bool Exec (C4Object *obj, float timeDelta)
 
void Draw (C4TargetFacet cgo, C4Object *obj, C4ShaderCall &call, int texUnit, const StdProjectionMatrix &modelview)
 
bool IsOfType (C4ParticleDef *def, uint32_t _blitMode, uint32_t attachment) const
 
bool IsEmpty () const
 
C4ParticleAddNewParticle ()
 
void ReserveSpace (uint32_t forAmount)
 

Friends

class C4ParticleList
 

Detailed Description

Definition at line 340 of file C4Particles.h.

Constructor & Destructor Documentation

◆ C4ParticleChunk() [1/2]

C4ParticleChunk::C4ParticleChunk ( )
inline

Definition at line 363 of file C4Particles.h.

363  : sourceDefinition(nullptr), blitMode(0), attachment(C4ATTACH_None), particleCount(0), drawingDataVertexBufferObject(0), drawingDataVertexArraysObject(0)
364  {
365 
366  }
@ C4ATTACH_None
Definition: C4Particles.h:48

◆ C4ParticleChunk() [2/2]

C4ParticleChunk::C4ParticleChunk ( const C4ParticleChunk )
delete

◆ ~C4ParticleChunk()

C4ParticleChunk::~C4ParticleChunk ( )
inline

Definition at line 370 of file C4Particles.h.

371  {
372  Clear();
373  }

References Clear().

Here is the call graph for this function:

Member Function Documentation

◆ AddNewParticle()

C4Particle * C4ParticleChunk::AddNewParticle ( )

Definition at line 1117 of file C4Particles.cpp.

1118 {
1119  size_t currentIndex = particleCount++;
1120 
1121  if (currentIndex < particles.size())
1122  {
1123  particles[currentIndex] = new C4Particle();
1124  }
1125  else
1126  {
1127  particles.push_back(new C4Particle());
1128  vertexCoordinates.resize(vertexCoordinates.size() + C4Particle::DrawingData::vertexCountPerParticle);
1129  }
1130 
1131  C4Particle *newParticle = particles[currentIndex];
1132  newParticle->drawingData.SetPointer(&vertexCoordinates[currentIndex * C4Particle::DrawingData::vertexCountPerParticle], true);
1133  return newParticle;
1134 }
struct C4Particle::DrawingData drawingData
static const int vertexCountPerParticle
Definition: C4Particles.h:241
void SetPointer(Vertex *startingVertex, bool initial=false)
Definition: C4Particles.h:273

References C4Particle::C4Particle(), C4Particle::drawingData, C4Particle::DrawingData::SetPointer(), and C4Particle::DrawingData::vertexCountPerParticle.

Referenced by C4ParticleSystem::Create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Clear()

void C4ParticleChunk::Clear ( )

Definition at line 960 of file C4Particles.cpp.

961 {
962  for (size_t i = 0; i < particleCount; ++i)
963  {
964  delete particles[i];
965  }
966  particleCount = 0;
967  particles.clear();
968  vertexCoordinates.clear();
969 
970  ClearBufferObjects();
971 }

Referenced by ~C4ParticleChunk().

Here is the caller graph for this function:

◆ Draw()

void C4ParticleChunk::Draw ( C4TargetFacet  cgo,
C4Object obj,
C4ShaderCall call,
int  texUnit,
const StdProjectionMatrix modelview 
)

Definition at line 1001 of file C4Particles.cpp.

1002 {
1003  if (particleCount == 0) return;
1004  const int stride = sizeof(C4Particle::DrawingData::Vertex);
1005  assert(sourceDefinition && "No source definition assigned to particle chunk.");
1006  C4TexRef *textureRef = sourceDefinition->Gfx.GetFace().texture.get();
1007  assert(textureRef != 0 && "Particle definition had no texture assigned.");
1008 
1009  // use a relative offset?
1010  // (note the normal matrix is unaffected by this)
1011  if ((attachment & C4ATTACH_MoveRelative) && (obj != 0))
1012  {
1013  StdProjectionMatrix new_modelview(modelview);
1014  Translate(new_modelview, fixtof(obj->GetFixedX()), fixtof(obj->GetFixedY()), 0.0f);
1015  call.SetUniformMatrix4x4(C4SSU_ModelViewMatrix, new_modelview);
1016  }
1017  else
1018  {
1019  call.SetUniformMatrix4x4(C4SSU_ModelViewMatrix, modelview);
1020  }
1021 
1022  // enable additive blending for particles with that blit mode
1023  glBlendFunc(GL_SRC_ALPHA, (blitMode & C4GFXBLIT_ADDITIVE) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA);
1024 
1025  glActiveTexture(texUnit);
1026  glBindTexture(GL_TEXTURE_2D, textureRef->texName);
1027 
1028  // generate the buffer as necessary
1029  if (drawingDataVertexBufferObject == 0)
1030  {
1031  // clear up old data
1032  ClearBufferObjects();
1033  // generate new buffer objects
1034  glGenBuffers(1, &drawingDataVertexBufferObject);
1035  assert (drawingDataVertexBufferObject != 0 && "Could not generate OpenGL buffer object.");
1036  // Immediately bind the buffer.
1037  // glVertexAttribPointer requires a valid GL_ARRAY_BUFFER to be bound and we need the buffer to be created for glObjectLabel.
1038  glBindBuffer(GL_ARRAY_BUFFER, drawingDataVertexBufferObject);
1039 
1040  pGL->ObjectLabel(GL_BUFFER, drawingDataVertexBufferObject, -1, "<particles>/VBO");
1041 
1042  // generate new VAO ID
1043  drawingDataVertexArraysObject = pGL->GenVAOID();
1044  assert (drawingDataVertexArraysObject != 0 && "Could not generate a VAO ID.");
1045  }
1046 
1047 
1048  // Push the new vertex data
1049  glBindBuffer(GL_ARRAY_BUFFER, drawingDataVertexBufferObject);
1050  glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(C4Particle::DrawingData::Vertex) * particleCount, &vertexCoordinates[0], GL_DYNAMIC_DRAW);
1051  glBindBuffer(GL_ARRAY_BUFFER, 0);
1052 
1053  // set up the vertex array structure
1054  GLuint vao;
1055  const bool has_vao = pGL->GetVAO(drawingDataVertexArraysObject, vao);
1056  glBindVertexArray(vao);
1057 
1058  assert ((drawingDataVertexBufferObject != 0) && "No buffer object has been created yet.");
1059  assert ((drawingDataVertexArraysObject != 0) && "No vertex arrays object has been created yet.");
1060 
1061  if (!has_vao)
1062  {
1063  glBindBuffer(GL_ARRAY_BUFFER, drawingDataVertexBufferObject);
1064  pGL->ObjectLabel(GL_VERTEX_ARRAY, vao, -1, "<particles>/VAO");
1065 
1066  glEnableVertexAttribArray(call.GetAttribute(C4SSA_Position));
1067  glEnableVertexAttribArray(call.GetAttribute(C4SSA_Color));
1068  glEnableVertexAttribArray(call.GetAttribute(C4SSA_TexCoord));
1069  glVertexAttribPointer(call.GetAttribute(C4SSA_Position), 2, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<GLvoid*>(offsetof(C4Particle::DrawingData::Vertex, x)));
1070  glVertexAttribPointer(call.GetAttribute(C4SSA_TexCoord), 2, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<GLvoid*>(offsetof(C4Particle::DrawingData::Vertex, u)));
1071  glVertexAttribPointer(call.GetAttribute(C4SSA_Color), 4, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<GLvoid*>(offsetof(C4Particle::DrawingData::Vertex, r)));
1072  }
1073 
1074  // We need to always bind the ibo, because it might change its size.
1075  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ::Particles.GetIBO(particleCount));
1076 
1077  glDrawElements(GL_TRIANGLE_STRIP, static_cast<GLsizei> (5 * particleCount), GL_UNSIGNED_INT, 0);
1078 
1079  // reset buffer data
1080  glBindVertexArray(0);
1081 }
CStdGL * pGL
Definition: C4DrawGL.cpp:907
@ C4SSA_TexCoord
Definition: C4DrawGL.h:91
@ C4SSA_Color
Definition: C4DrawGL.h:92
@ C4SSA_Position
Definition: C4DrawGL.h:89
@ C4SSU_ModelViewMatrix
Definition: C4DrawGL.h:53
C4ParticleSystem Particles
@ C4ATTACH_MoveRelative
Definition: C4Particles.h:51
float fixtof(const C4Fixed &x)
Definition: C4Real.h:257
#define C4GFXBLIT_ADDITIVE
Definition: C4Surface.h:26
void Translate(MatrixType &mat, float dx, float dy, float dz)
Definition: StdMeshMath.h:185
C4Surface & GetFace()
Definition: C4FacetEx.h:52
C4Real GetFixedX() const
Definition: C4Object.h:288
C4Real GetFixedY() const
Definition: C4Object.h:289
C4FacetSurface Gfx
Definition: C4Particles.h:90
GLuint GetIBO(size_t forParticleAmount)
void SetUniformMatrix4x4(int iUniform, const StdMeshMatrix &matrix)
Definition: C4Shader.h:351
GLint GetAttribute(int iAttribute) const
Definition: C4Shader.h:194
std::unique_ptr< C4TexRef > texture
Definition: C4Surface.h:78
unsigned int texName
Definition: C4Surface.h:155
void ObjectLabel(uint32_t identifier, uint32_t name, int32_t length, const char *label)
Definition: C4DrawGL.cpp:267
unsigned int GenVAOID()
Definition: C4DrawGL.cpp:927
bool GetVAO(unsigned int vaoid, GLuint &vao)
Definition: C4DrawGL.cpp:1015

References C4ATTACH_MoveRelative, C4GFXBLIT_ADDITIVE, C4SSA_Color, C4SSA_Position, C4SSA_TexCoord, C4SSU_ModelViewMatrix, fixtof(), CStdGL::GenVAOID(), C4ShaderCall::GetAttribute(), C4Object::GetFixedX(), C4Object::GetFixedY(), C4ParticleSystem::GetIBO(), CStdGL::GetVAO(), CStdGL::ObjectLabel(), Particles, pGL, C4ShaderCall::SetUniformMatrix4x4(), C4TexRef::texName, and Translate().

Here is the call graph for this function:

◆ Exec()

bool C4ParticleChunk::Exec ( C4Object obj,
float  timeDelta 
)

Definition at line 988 of file C4Particles.cpp.

989 {
990  for (size_t i = 0; i < particleCount; ++i)
991  {
992  if (!particles[i]->Exec(obj, timeDelta, sourceDefinition))
993  {
994  DeleteAndReplaceParticle(i, particleCount - 1);
995  --particleCount;
996  }
997  }
998  return particleCount > 0;
999 }
bool Exec(C4Object *obj, float timeDelta)

References C4Particle::Exec().

Referenced by C4ParticleList::Exec().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsEmpty()

bool C4ParticleChunk::IsEmpty ( ) const
inline

Definition at line 379 of file C4Particles.h.

379 { return !particleCount; }

◆ IsOfType()

bool C4ParticleChunk::IsOfType ( C4ParticleDef def,
uint32_t  _blitMode,
uint32_t  attachment 
) const

Definition at line 1083 of file C4Particles.cpp.

1084 {
1085  return def == sourceDefinition && blitMode == _blitMode && attachment == _attachment;
1086 }

Referenced by C4ParticleList::GetFittingParticleChunk().

Here is the caller graph for this function:

◆ operator=()

C4ParticleChunk& C4ParticleChunk::operator= ( const C4ParticleChunk )
delete

◆ ReserveSpace()

void C4ParticleChunk::ReserveSpace ( uint32_t  forAmount)

Definition at line 1099 of file C4Particles.cpp.

1100 {
1101  uint32_t newSize = static_cast<uint32_t>(particleCount) + forAmount + 1;
1102 
1103  if (particles.capacity() < newSize)
1104  particles.reserve(std::max<uint32_t>(newSize, particles.capacity() * 2));
1105 
1106  // resizing the points vector is relatively costly, hopefully we only do it rarely
1107  while (vertexCoordinates.capacity() <= newSize * C4Particle::DrawingData::vertexCountPerParticle)
1108  {
1109  vertexCoordinates.reserve(std::max<uint32_t>(C4Particle::DrawingData::vertexCountPerParticle * newSize, vertexCoordinates.capacity() * 2));
1110 
1111  // update all existing particles' pointers..
1112  for (size_t i = 0; i < particleCount; ++i)
1113  particles[i]->drawingData.SetPointer(&vertexCoordinates[i * C4Particle::DrawingData::vertexCountPerParticle]);
1114  }
1115 }

References C4Particle::drawingData, C4Particle::DrawingData::SetPointer(), and C4Particle::DrawingData::vertexCountPerParticle.

Referenced by C4ParticleSystem::Create().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ C4ParticleList

friend class C4ParticleList
friend

Definition at line 386 of file C4Particles.h.


The documentation for this class was generated from the following files: