52 return CompileFromBuf_LogWarn<StdCompilerINIRead>(
mkNamingAdapt(*
this,
"Particle"),
94 char *particle_source;
100 delete [] particle_source;
return false;
102 delete [] particle_source;
127 {
char ostr[250];
sprintf(ostr,
LoadResStr(
"IDS_PRC_DEFOVERLOAD"),def_overload->Name.getData(),
"<particle>");
Log(ostr); }
175 float sine = sinf(rotation);
176 float cosine = cosf(rotation);
192 phase = phase % sourceDef->
Length;
193 int offsetY = phase / sourceDef->
PhasesX;
194 int offsetX = phase % sourceDef->
PhasesX;
195 float wdt = 1.0f / (float)sourceDef->
PhasesX;
197 float hgt = 1.0f / (
float)numOfLines;
199 float x = wdt * (float)offsetX;
200 float y = hgt * (float)offsetY;
204 vertices[0].u = x; vertices[0].v = yr;
205 vertices[1].u = x; vertices[1].v = y;
206 vertices[2].u = xr; vertices[2].v = yr;
207 vertices[3].u = xr; vertices[3].v = y;
212 startValue = other.startValue;
213 endValue = other.endValue;
214 currentValue = other.currentValue;
215 rerollInterval = other.rerollInterval;
216 smoothing = other.smoothing;
217 valueFunction = other.valueFunction;
218 isConstant = other.isConstant;
219 keyFrameCount = other.keyFrameCount;
222 if (keyFrameCount > 0)
224 keyFrames.reserve(2 * keyFrameCount);
225 keyFrames.assign(other.keyFrames.begin(), other.keyFrames.end());
228 typeOfValueToChange = other.typeOfValueToChange;
229 switch (typeOfValueToChange)
232 floatValueToChange = other.floatValueToChange;
235 intValueToChange = other.intValueToChange;
237 case VAL_TYPE_KEYFRAMES:
238 keyFrameIndex = other.keyFrameIndex;
241 assert (
false &&
"Trying to copy C4ParticleValueProvider with invalid value type");
246 for (std::vector<C4ParticleValueProvider*>::const_iterator iter = other.childrenValueProviders.begin(); iter != other.childrenValueProviders.end(); ++iter)
258 if (
type == VAL_TYPE_FLOAT)
259 this->*floatVal = (float)value.
getInt();
260 else if (
type == VAL_TYPE_INT)
261 this->*intVal = value.
getInt();
262 else if (
type == VAL_TYPE_KEYFRAMES)
263 this->keyFrames[keyFrameIndex] = (float)value.
getInt();
269 childrenValueProviders.push_back(child);
272 child->typeOfValueToChange =
type;
274 if (
type == VAL_TYPE_FLOAT)
276 child->floatValueToChange = floatVal;
278 else if (
type == VAL_TYPE_INT)
280 child->intValueToChange = intVal;
282 else if (
type == VAL_TYPE_KEYFRAMES)
284 child->keyFrameIndex = keyFrameIndex;
290 if (
type == VAL_TYPE_FLOAT)
291 this->*floatVal = 0.f;
292 else if (
type == VAL_TYPE_INT)
294 else if (
type == VAL_TYPE_KEYFRAMES)
295 this->keyFrames[keyFrameIndex] = 0.f;
301 switch (typeOfValueToChange)
304 parent->*floatValueToChange = GetValue(particle);
307 parent->*intValueToChange = (int) GetValue(particle);
309 case VAL_TYPE_KEYFRAMES:
310 parent->keyFrames[keyFrameIndex] = GetValue(particle);
317 void C4ParticleValueProvider::UpdateChildren(
C4Particle *particle)
319 for (std::vector<C4ParticleValueProvider*>::iterator iter = childrenValueProviders.begin(); iter != childrenValueProviders.end(); ++iter)
321 (*iter)->UpdatePointerValue(particle,
this);
325 void C4ParticleValueProvider::FloatifyParameterValue(
float C4ParticleValueProvider::*value,
float denominator,
size_t keyFrameIndex)
328 this->keyFrames[keyFrameIndex] /= denominator;
330 this->*value /= denominator;
332 for (std::vector<C4ParticleValueProvider*>::iterator iter = childrenValueProviders.begin(); iter != childrenValueProviders.end(); ++iter)
337 if (child->typeOfValueToChange == VAL_TYPE_KEYFRAMES && child->keyFrameIndex == keyFrameIndex)
342 if (child->floatValueToChange == value)
351 assert (denominator != 0.f &&
"Trying to floatify C4ParticleValueProvider with denominator of 0");
353 if (valueFunction == &C4ParticleValueProvider::Direction)
355 FloatifyParameterValue(&C4ParticleValueProvider::startValue, 1000.f);
359 FloatifyParameterValue(&C4ParticleValueProvider::startValue, denominator);
360 FloatifyParameterValue(&C4ParticleValueProvider::endValue, denominator);
361 FloatifyParameterValue(&C4ParticleValueProvider::currentValue, denominator);
364 if (valueFunction == &C4ParticleValueProvider::KeyFrames)
366 for (
size_t i = 0; i < keyFrameCount; ++i)
368 FloatifyParameterValue(0, 1000.f, 2 * i);
369 FloatifyParameterValue(0, denominator, 2 * i + 1);
372 else if (valueFunction == &C4ParticleValueProvider::Speed || valueFunction == &C4ParticleValueProvider::Wind || valueFunction == &C4ParticleValueProvider::Gravity)
374 FloatifyParameterValue(&C4ParticleValueProvider::speedFactor, 1000.0f);
376 else if (valueFunction == &C4ParticleValueProvider::Step)
378 FloatifyParameterValue(&C4ParticleValueProvider::maxValue, denominator);
380 else if (valueFunction == &C4ParticleValueProvider::Sin || valueFunction == &C4ParticleValueProvider::Cos)
382 FloatifyParameterValue(&C4ParticleValueProvider::parameterValue, 1.0f);
383 FloatifyParameterValue(&C4ParticleValueProvider::maxValue, denominator);
389 UpdateChildren(forParticle);
390 return (this->*valueFunction)(forParticle);
393 float C4ParticleValueProvider::Linear(
C4Particle *forParticle)
395 return startValue + (endValue - startValue) * forParticle->
GetRelativeAge();
398 float C4ParticleValueProvider::Const(
C4Particle *forParticle)
403 float C4ParticleValueProvider::Random(
C4Particle *forParticle)
406 const bool needToReevaluate =
412 || (rerollInterval != 0 && ((
int)forParticle->
GetAge() % rerollInterval == 0));
414 if (needToReevaluate)
420 const std::uintptr_t ourAddress =
reinterpret_cast<std::uintptr_t
>(forParticle);
421 rng.set_stream(ourAddress);
424 std::uniform_real_distribution<float> distribution(std::min(startValue, endValue), std::max(startValue, endValue));
425 currentValue = distribution(rng);
430 float C4ParticleValueProvider::Direction(
C4Particle *forParticle)
435 if (distX == 0.f)
return distY > 0.f ? M_PI : 0.f;
436 if (distY == 0.f)
return distX < 0.f ? 3.0f * M_PI_2 : M_PI_2;
438 return startValue * (atan2(distY, distX) + (float)M_PI_2);
441 float C4ParticleValueProvider::Step(
C4Particle *forParticle)
443 float value = currentValue + startValue * forParticle->
GetAge() / delay;
444 if (maxValue != 0.0f && value > maxValue) value = maxValue;
448 float C4ParticleValueProvider::KeyFrames(
C4Particle *forParticle)
454 for (
size_t i = 0; i < keyFrameCount; ++i)
456 if (age > keyFrames[i * 2])
continue;
459 float x1 = keyFrames[(i - 1) * 2];
460 float x2 = keyFrames[i * 2];
461 float y1 = keyFrames[(i - 1) * 2 + 1];
462 float y2 = keyFrames[i * 2 + 1];
463 float position = (age - x1) / (x2 - x1);
464 float totalRange = (y2 - y1);
466 float value = position * totalRange + y1;
474 float C4ParticleValueProvider::Sin(
C4Particle *forParticle)
476 return sin(parameterValue * M_PI / 180.0f) * maxValue + startValue;
479 float C4ParticleValueProvider::Cos(
C4Particle *forParticle)
481 return cos(parameterValue * M_PI / 180.0f) * maxValue + startValue;
484 float C4ParticleValueProvider::Speed(
C4Particle *forParticle)
488 float speed = sqrtf((distX * distX) + (distY * distY));
490 return startValue + speedFactor * speed;
493 float C4ParticleValueProvider::Wind(
C4Particle *forParticle)
498 float C4ParticleValueProvider::Gravity(
C4Particle *forParticle)
508 valueFunction = &C4ParticleValueProvider::Const;
511 valueFunction = &C4ParticleValueProvider::Linear;
514 valueFunction = &C4ParticleValueProvider::Random;
517 valueFunction = &C4ParticleValueProvider::Direction;
520 valueFunction = &C4ParticleValueProvider::Step;
523 valueFunction = &C4ParticleValueProvider::KeyFrames;
526 valueFunction = &C4ParticleValueProvider::Sin;
529 valueFunction = &C4ParticleValueProvider::Cos;
532 valueFunction = &C4ParticleValueProvider::Speed;
535 valueFunction = &C4ParticleValueProvider::Wind;
538 valueFunction = &C4ParticleValueProvider::Gravity;
541 assert(
false &&
"Invalid C4ParticleValueProvider ID passed");
552 startValue = endValue = 1.0f;
553 valueFunction = &C4ParticleValueProvider::Const;
555 size_t arraySize = (size_t) fromArray.
GetSize();
556 if (arraySize < 2)
return;
558 int type = fromArray[0].getInt();
566 SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue);
574 SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue);
575 SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::endValue);
582 SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue);
583 SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::endValue);
585 SetParameterValue(VAL_TYPE_INT, fromArray[3], 0, &C4ParticleValueProvider::rerollInterval);
590 SetParameterValue(VAL_TYPE_INT, fromArray[4], 0, &C4ParticleValueProvider::alreadyRolled);
591 rng.seed(alreadyRolled);
604 SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue);
611 SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::startValue);
612 SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::currentValue);
613 SetParameterValue(VAL_TYPE_FLOAT, fromArray[3], &C4ParticleValueProvider::delay);
614 SetParameterValue(VAL_TYPE_FLOAT, fromArray[4], &C4ParticleValueProvider::maxValue);
615 if (delay == 0.f) delay = 1.f;
622 SetParameterValue(VAL_TYPE_INT, fromArray[1], 0, &C4ParticleValueProvider::smoothing);
623 keyFrames.resize(arraySize + 4 - 1);
626 const size_t startingOffset = 2;
627 size_t i = startingOffset;
628 for (; i < arraySize; ++i)
630 SetParameterValue(VAL_TYPE_KEYFRAMES, fromArray[(int32_t)i], 0, 0, 2 + i - startingOffset);
632 keyFrameCount = (i - startingOffset) / 2 + 2;
634 startValue = keyFrames[2 + 1];
635 endValue = keyFrames[2 * keyFrameCount - 1];
638 keyFrames[0] = -500.f;
639 keyFrames[1] = keyFrames[2 + 1];
640 keyFrames[2 * keyFrameCount - 2] = 1500.f;
641 keyFrames[2 * keyFrameCount - 1] = keyFrames[keyFrameCount - 1 - 2];
650 SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::parameterValue);
651 SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::maxValue);
652 SetParameterValue(VAL_TYPE_FLOAT, fromArray[3], &C4ParticleValueProvider::startValue);
659 SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::speedFactor);
660 SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::startValue);
667 SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::speedFactor);
668 SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::startValue);
675 SetParameterValue(VAL_TYPE_FLOAT, fromArray[1], &C4ParticleValueProvider::speedFactor);
676 SetParameterValue(VAL_TYPE_FLOAT, fromArray[2], &C4ParticleValueProvider::startValue);
692 Set((
float)value.
getInt());
698 startValue = endValue = to;
705 hasConstantColor =
false;
706 hasCollisionVertex =
false;
707 collisionCallback = 0;
711 collisionDensity.Set(
static_cast<float>(
C4M_Solid));
712 collisionVertex.Set(0.f);
717 speedDampingX.Set(1000.f);
718 speedDampingY.Set(1000.f);
722 colorAlpha.Set(255.f);
729 bouncyness /= 1000.f;
731 collisionDensity.Floatify(1.f);
732 collisionVertex.Floatify(1000.f);
734 stretch.Floatify(1000.f);
735 forceX.Floatify(100.f);
736 forceY.Floatify(100.f);
737 speedDampingX.Floatify(1000.f);
738 speedDampingY.Floatify(1000.f);
739 colorR.Floatify(255.f);
740 colorG.Floatify(255.f);
741 colorB.Floatify(255.f);
742 colorAlpha.Floatify(255.f);
743 rotation.Floatify(180.0f / (
float)M_PI);
746 hasConstantColor = colorR.IsConstant() && colorG.IsConstant() && colorB.IsConstant() && colorAlpha.IsConstant();
751 if (!dataSource)
return;
755 for (;iter != end; ++iter)
759 assert(key &&
"PropList returns non-string as key");
764 colorR.
Set(property);
768 colorG.Set(property);
772 colorB.Set(property);
776 colorAlpha.Set(property);
780 forceX.Set(property);
784 forceY.Set(property);
788 speedDampingX.Set(property);
792 speedDampingY.Set(property);
800 stretch.Set(property);
804 rotation.Set(property);
809 blitMode = (uint32_t) property.getInt();
814 attachment = (uint32_t) property.getInt();
822 collisionVertex.Set(property);
823 if (property.GetType() !=
C4V_Nil)
824 hasCollisionVertex =
true;
828 collisionDensity.Set(property);
832 SetCollisionFunc(property);
841 if (!(valueArray = source.
getArray()))
return;
843 int arraySize = valueArray->
GetSize();
844 if (arraySize < 1)
return;
846 int type = (*valueArray)[0].getInt();
857 bouncyness = ((float)(*valueArray)[1].getInt());
918 bool collided =
false;
922 float size_x = (
currentSpeedX > 0.f ? size : -size) * 0.5f * collisionPoint;
923 float size_y = (
currentSpeedY > 0.f ? size : -size) * 0.5f * collisionPoint;
962 for (
size_t i = 0; i < particleCount; ++i)
968 vertexCoordinates.clear();
970 ClearBufferObjects();
973 void C4ParticleChunk::DeleteAndReplaceParticle(
size_t indexToReplace,
size_t indexFrom)
975 C4Particle *oldParticle = particles[indexToReplace];
978 if (indexFrom != indexToReplace)
981 particles[indexToReplace] = particles[indexFrom];
990 for (
size_t i = 0; i < particleCount; ++i)
992 if (!particles[i]->
Exec(obj, timeDelta, sourceDefinition))
994 DeleteAndReplaceParticle(i, particleCount - 1);
998 return particleCount > 0;
1003 if (particleCount == 0)
return;
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.");
1023 glBlendFunc(GL_SRC_ALPHA, (blitMode &
C4GFXBLIT_ADDITIVE) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA);
1025 glActiveTexture(texUnit);
1026 glBindTexture(GL_TEXTURE_2D, textureRef->
texName);
1029 if (drawingDataVertexBufferObject == 0)
1032 ClearBufferObjects();
1034 glGenBuffers(1, &drawingDataVertexBufferObject);
1035 assert (drawingDataVertexBufferObject != 0 &&
"Could not generate OpenGL buffer object.");
1038 glBindBuffer(GL_ARRAY_BUFFER, drawingDataVertexBufferObject);
1040 pGL->
ObjectLabel(GL_BUFFER, drawingDataVertexBufferObject, -1,
"<particles>/VBO");
1044 assert (drawingDataVertexArraysObject != 0 &&
"Could not generate a VAO ID.");
1049 glBindBuffer(GL_ARRAY_BUFFER, drawingDataVertexBufferObject);
1051 glBindBuffer(GL_ARRAY_BUFFER, 0);
1055 const bool has_vao =
pGL->
GetVAO(drawingDataVertexArraysObject, vao);
1056 glBindVertexArray(vao);
1058 assert ((drawingDataVertexBufferObject != 0) &&
"No buffer object has been created yet.");
1059 assert ((drawingDataVertexArraysObject != 0) &&
"No vertex arrays object has been created yet.");
1063 glBindBuffer(GL_ARRAY_BUFFER, drawingDataVertexBufferObject);
1075 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ::
Particles.
GetIBO(particleCount));
1077 glDrawElements(GL_TRIANGLE_STRIP,
static_cast<GLsizei
> (5 * particleCount), GL_UNSIGNED_INT, 0);
1080 glBindVertexArray(0);
1085 return def == sourceDefinition && blitMode == _blitMode && attachment == _attachment;
1088 void C4ParticleChunk::ClearBufferObjects()
1090 if (drawingDataVertexBufferObject != 0)
1091 glDeleteBuffers(1, &drawingDataVertexBufferObject);
1092 if (drawingDataVertexArraysObject != 0)
1095 drawingDataVertexArraysObject = 0;
1096 drawingDataVertexBufferObject = 0;
1101 uint32_t newSize =
static_cast<uint32_t
>(particleCount) + forAmount + 1;
1103 if (particles.capacity() < newSize)
1104 particles.reserve(std::max<uint32_t>(newSize, particles.capacity() * 2));
1112 for (
size_t i = 0; i < particleCount; ++i)
1119 size_t currentIndex = particleCount++;
1121 if (currentIndex < particles.size())
1131 C4Particle *newParticle = particles[currentIndex];
1138 if (particleChunks.empty())
return;
1140 accessMutex.Enter();
1142 for (std::list<C4ParticleChunk*>::iterator iter = particleChunks.begin(); iter != particleChunks.end();++iter)
1145 chunk->
Exec(targetObject, timeDelta);
1148 accessMutex.Leave();
1153 if (particleChunks.empty())
return;
1158 glPrimitiveRestartIndex(0xffffffff);
1159 glEnable(GL_PRIMITIVE_RESTART);
1174 accessMutex.Enter();
1176 for (std::list<C4ParticleChunk*>::iterator iter = particleChunks.begin(); iter != particleChunks.end(); )
1178 if ((*iter)->IsEmpty())
1181 iter = particleChunks.erase(iter);
1182 lastAccessedChunk = 0;
1186 (*iter)->Draw(cgo, obj, call, texUnit, modelview);
1191 accessMutex.Leave();
1193 glDisable(GL_PRIMITIVE_RESTART);
1198 accessMutex.Enter();
1200 for (std::list<C4ParticleChunk*>::iterator iter = particleChunks.begin(); iter != particleChunks.end(); ++iter)
1202 particleChunks.clear();
1206 if (
this == targetObject->FrontParticles) targetObject->FrontParticles =
nullptr;
1207 else if (
this == targetObject->BackParticles) targetObject->BackParticles =
nullptr;
1212 accessMutex.Leave();
1218 accessMutex.Enter();
1222 if (lastAccessedChunk && lastAccessedChunk->IsOfType(def, blitMode, attachment))
1223 chunk = lastAccessedChunk;
1226 for (std::list<C4ParticleChunk*>::iterator iter = particleChunks.begin(); iter != particleChunks.end(); ++iter)
1229 if (!current->
IsOfType(def, blitMode, attachment))
continue;
1239 chunk = particleChunks.back();
1240 chunk->sourceDefinition = def;
1241 chunk->blitMode = blitMode;
1242 chunk->attachment = attachment;
1245 assert(chunk &&
"No suitable particle chunk could be found or created.");
1246 lastAccessedChunk = chunk;
1249 accessMutex.Leave();
1254 void C4ParticleSystem::CalculationThread::Execute()
1261 currentSimulationTime = 0;
1262 globalParticles = 0;
1271 calculationThread.SignalStop();
1275 void C4ParticleSystem::ExecuteCalculation()
1278 frameCounterAdvancedEvent.
Reset();
1281 if (currentSimulationTime < gameTime)
1283 float timeDelta = 1.f;
1284 if (currentSimulationTime != 0)
1285 timeDelta = (float)(gameTime - currentSimulationTime);
1286 currentSimulationTime = gameTime;
1288 particleListAccessMutex.
Enter();
1290 for (std::list<C4ParticleList>::iterator iter = particleLists.begin(); iter != particleLists.end(); ++iter)
1292 iter->Exec(timeDelta);
1295 particleListAccessMutex.
Leave();
1307 particleListAccessMutex.
Enter();
1308 particleLists.emplace_back(forObject);
1309 newList = &particleLists.back();
1310 particleListAccessMutex.
Leave();
1319 particleListAccessMutex.
Enter();
1321 for(std::list<C4ParticleList>::iterator iter = particleLists.begin(); iter != particleLists.end();)
1324 if (list == first || list == second)
1326 iter = particleLists.erase(iter);
1334 particleListAccessMutex.
Leave();
1349 particleProperties.
Set(properties);
1355 float xoff(0.f), yoff(0.f);
1358 float drawingOffsetX(0.f), drawingOffsetY(0.f);
1363 xoff =
object->GetX();
1364 yoff =
object->GetY();
1368 drawingOffsetX = -xoff;
1369 drawingOffsetY = -yoff;
1381 pxList =
object->FrontParticles;
1386 pxList =
object->BackParticles;
1394 pxList = globalParticles;
1422 const float lifetime_value = lifetime.
GetValue(particle);
1424 if (lifetime_value >= 0.0f)
1441 PreparePrimitiveRestartIndices(forParticleAmount);
1445 void C4ParticleSystem::PreparePrimitiveRestartIndices(uint32_t forAmount)
1447 if (ibo == 0) glGenBuffers(1, &ibo);
1449 const size_t neededEntryAmount = 5 * forAmount;
1450 const size_t neededIboSize = neededEntryAmount *
sizeof(GLuint);
1452 if (ibo_size >= neededIboSize)
return;
1454 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
1457 const uint32_t PRI = 0xffffffff;
1459 std::vector<GLuint> ibo_data;
1460 ibo_data.reserve(neededEntryAmount);
1462 unsigned int index = 0;
1463 for (
unsigned int i = 0; i < neededEntryAmount; ++i)
1466 ibo_data.push_back(PRI);
1468 ibo_data.push_back(index++);
1471 ibo_size = neededEntryAmount *
sizeof(GLuint);
1472 glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibo_size, &ibo_data[0], GL_STATIC_DRAW);
1473 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1480 if (ibo != 0) glDeleteBuffers(1, &ibo);
1481 ibo = 0; ibo_size = 0;
1483 currentSimulationTime = 0;
1493 particleListAccessMutex.
Enter();
1494 particleLists.clear();
1495 particleListAccessMutex.
Leave();
1504 if (def != exclude && def->
Name == name)
#define C4CFN_ParticleCore
#define C4CFN_DefGraphics
int32_t GBackDensity(int32_t x, int32_t y)
const char * LoadResStr(const char *id)
bool Log(const char *szMessage)
bool DebugLogF(const char *strMessage ...)
C4ParticleSystem Particles
C4ParticleValueProviderID
uint32_t UnsyncedRandom()
float fixtof(const C4Fixed &x)
#define C4GFXBLIT_ADDITIVE
#define toC4CStrBuf(rBuf)
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
void Translate(MatrixType &mat, float dx, float dy, float dz)
int32_t VerboseObjectLoading
C4ConfigGraphics Graphics
void DeactivateBlitModulation()
bool GetPhaseNum(int32_t &rX, int32_t &rY)
bool Load(C4Group &hGroup, const char *szName, int iWdt, int iHgt, bool fNoErrIfNotFound, int iFlags)
void Set(const C4Facet &cpy)
StdStrBuf GetFullName() const
bool LoadEntry(const char *entry_name, char **buffer, size_t *size_info=nullptr, int zeros_to_append=0)
bool Open(const char *group_name, bool do_create=false)
C4Real GetGravity() const
class C4ParticleList * BackParticles
class C4ParticleList * FrontParticles
C4Particle * AddNewParticle()
bool Exec(C4Object *obj, float timeDelta)
bool IsOfType(C4ParticleDef *def, uint32_t _blitMode, uint32_t attachment) const
void ReserveSpace(uint32_t forAmount)
void Draw(C4TargetFacet cgo, C4Object *obj, C4ShaderCall &call, int texUnit, const StdProjectionMatrix &modelview)
bool Compile(char *particle_source, const char *name)
void CompileFunc(StdCompiler *compiler)
bool Load(C4Group &group)
struct C4Particle::DrawingData drawingData
friend class C4ParticleValueProvider
bool Exec(C4Object *obj, float timeDelta, C4ParticleDef *sourceDef)
void SetPosition(float x, float y)
friend class C4ParticleChunk
C4ParticleProperties properties
float GetRelativeAge() const
void Draw(C4TargetFacet cgo, C4Object *obj)
C4ParticleChunk * GetFittingParticleChunk(C4ParticleDef *def, uint32_t blitMode, uint32_t attachment, bool alreadyLocked)
void Exec(float timeDelta=1.f)
bool CollisionDie(C4Particle *forParticle)
C4ParticleValueProvider rotation
void SetCollisionFunc(const C4Value &source)
C4ParticleValueProvider collisionDensity
C4ParticleCollisionCallback collisionCallback
void Set(C4PropList *dataSource)
C4ParticleValueProvider speedDampingX
C4ParticleValueProvider collisionVertex
C4ParticleValueProvider speedDampingY
C4ParticleValueProvider phase
C4ParticleValueProvider size
C4ParticleValueProvider colorG
C4ParticleValueProvider forceY
bool CollisionBounce(C4Particle *forParticle)
C4ParticleValueProvider stretch
C4ParticleValueProvider colorAlpha
C4ParticleValueProvider colorR
C4ParticleValueProvider colorB
C4ParticleValueProvider forceX
bool CollisionStop(C4Particle *forParticle)
C4ParticleDef * GetDef(const char *name, C4ParticleDef *exclude=nullptr)
C4ParticleList * GetNewParticleList(C4Object *forTarget=nullptr)
C4ParticleSystemDefinitionList definitions
GLuint GetIBO(size_t forParticleAmount)
void Create(C4ParticleDef *of_def, C4ParticleValueProvider &x, C4ParticleValueProvider &y, C4ParticleValueProvider &speedX, C4ParticleValueProvider &speedY, C4ParticleValueProvider &lifetime, C4PropList *properties, int amount=1, C4Object *object=nullptr)
void ReleaseParticleList(C4ParticleList *first, C4ParticleList *second=nullptr)
float GetValue(C4Particle *forParticle)
void Set(const C4Value &value)
void Floatify(float denominator)
C4ParticleValueProvider & operator=(const C4ParticleValueProvider &other)
void SetUniformMatrix4x4(int iUniform, const StdMeshMatrix &matrix)
GLint AllocTexUnit(int iUniform)
GLint GetAttribute(int iAttribute) const
C4ValueArray * getArray() const
void Set(const C4Value &nValue)
int32_t GetWind(int32_t x, int32_t y)
void SetupMultiBlt(C4ShaderCall &call, const C4BltTransform *pTransform, GLuint baseTex, GLuint overlayTex, GLuint normalTex, DWORD dwOverlayModClr, StdProjectionMatrix *out_modelview)
void ObjectLabel(uint32_t identifier, uint32_t name, int32_t length, const char *label)
void FreeVAOID(unsigned int vaoid)
bool GetVAO(unsigned int vaoid, GLuint &vao)
C4Shader * GetSpriteShader(int ssc)
void Value(const T &rStruct)
static StdProjectionMatrix Identity()
const char * getData() const
void SetPosition(float x, float y, float size, float rotation=0.f, float stretch=1.f)
void SetColor(float r, float g, float b, float a=1.0f)
void SetPhase(int phase, C4ParticleDef *sourceDef)
static const int vertexCountPerParticle
void SetPointer(Vertex *startingVertex, bool initial=false)
void SetOffset(float x, float y)