OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
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::C4ParticleChunk ( )
inline

Definition at line 363 of file C4Particles.h.

363  : sourceDefinition(0), blitMode(0), attachment(C4ATTACH_None), particleCount(0), drawingDataVertexBufferObject(0), drawingDataVertexArraysObject(0)
364  {
365 
366  }
C4ParticleChunk::C4ParticleChunk ( const C4ParticleChunk )
delete
C4ParticleChunk::~C4ParticleChunk ( )
inline

Definition at line 370 of file C4Particles.h.

References Clear().

371  {
372  Clear();
373  }

Here is the call graph for this function:

Member Function Documentation

C4Particle * C4ParticleChunk::AddNewParticle ( )

Definition at line 1119 of file C4Particles.cpp.

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

Referenced by C4ParticleSystem::Create().

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

Here is the call graph for this function:

Here is the caller graph for this function:

void C4ParticleChunk::Clear ( )

Definition at line 962 of file C4Particles.cpp.

Referenced by ~C4ParticleChunk().

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

Here is the caller graph for this function:

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

Definition at line 1003 of file C4Particles.cpp.

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(), and C4TexRef::texName.

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

Here is the call graph for this function:

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

Definition at line 990 of file C4Particles.cpp.

References C4Particle::Exec().

Referenced by C4ParticleList::Exec().

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

Here is the call graph for this function:

Here is the caller graph for this function:

bool C4ParticleChunk::IsEmpty ( ) const
inline

Definition at line 379 of file C4Particles.h.

379 { return !particleCount; }
bool C4ParticleChunk::IsOfType ( C4ParticleDef def,
uint32_t  _blitMode,
uint32_t  attachment 
) const

Definition at line 1085 of file C4Particles.cpp.

Referenced by C4ParticleList::GetFittingParticleChunk().

1086 {
1087  return def == sourceDefinition && blitMode == _blitMode && attachment == _attachment;
1088 }

Here is the caller graph for this function:

C4ParticleChunk& C4ParticleChunk::operator= ( const C4ParticleChunk )
delete
void C4ParticleChunk::ReserveSpace ( uint32_t  forAmount)

Definition at line 1101 of file C4Particles.cpp.

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

Referenced by C4ParticleSystem::Create().

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

Here is the call graph for this function:

Here is the caller graph for this function:

Friends And Related Function Documentation

friend class C4ParticleList
friend

Definition at line 386 of file C4Particles.h.


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