8 #include <unordered_map>
9 #include <unordered_set>
69 using std::make_unique;
75 using std::unique_ptr;
76 using std::unordered_map;
77 using std::unordered_set;
135 constexpr int32_t EntityRenderer::BATCHRENDERER_MAX;
136 constexpr int32_t EntityRenderer::INSTANCEDRENDERING_OBJECTS_MAX;
163 auto created =
false;
165 contexts[i].vboInstancedRenderingIds = vboManaged->getVBOIds();
177 batchRenderer->dispose();
178 batchRenderer->release();
188 if (batchRenderer->acquire())
return batchRenderer.get();
195 batchRenderer->initialize();
196 if (batchRenderer->acquire())
return batchRenderer.get();
199 Console::println(
string(
"EntityRenderer::acquireTrianglesBatchRenderer()::failed"));
213 auto elementsIssued = 0;
216 queueElement->engine =
engine;
217 queueElement->rendering.renderPass = renderPass;
219 queueElement->rendering.renderTypes = renderTypes;
220 for (
auto i = 0; i < objects.size(); i++) {
221 queueElement->objects.push_back(objects[i]);
223 auto queueElementToSubmit = queueElement;
226 queueElement->engine =
engine;
227 queueElement->rendering.renderPass = renderPass;
229 queueElement->rendering.renderTypes = renderTypes;
234 if (queueElement->objects.empty() ==
false) {
240 while (
true ==
true) {
241 auto elementsProcessed = 0;
242 for (
const auto& engineThread:
Engine::engineThreads) elementsProcessed+= engineThread->getProcessedElements();
243 if (elementsProcessed == elementsIssued) {
255 engineThread->transparentRenderFacesPool->reset();
265 if (transparentRenderFaces.size() > 0) {
268 transparentRenderFaces.begin(),
269 transparentRenderFaces.end(),
271 return face1->distanceFromCamera > face2->distanceFromCamera;
292 for (
auto transparentRenderFace: transparentRenderFaces) {
336 auto objectNode = transparentRenderFaces[0]->objectNode;
337 auto object =
static_cast<Object*
>(objectNode->object);
340 if (objectNode->mesh->skinning ==
true) {
343 modelViewMatrix.
set(*objectNode->nodeTransformMatrix).
multiply(object->getTransformMatrix());
346 auto model = objectNode->object->getModel();
347 const auto& facesEntities = objectNode->node->getFacesEntities();
350 const auto& effectColorAdd =
object->getEffectColorAdd();
351 const auto& effectColorMul =
object->getEffectColorMul();
353 auto textureCoordinates =
false;
355 for (
auto i = 0; i < transparentRenderFaces.size(); i++) {
356 auto transparentRenderFace = transparentRenderFaces[i];
357 auto facesEntityIdx = transparentRenderFace->facesEntityIdx;
359 if (facesEntity != &facesEntities[facesEntityIdx]) {
360 facesEntity = &facesEntities[facesEntityIdx];
365 auto transparentRenderFacesNodeKey =
TransparentRenderFacesGroup::createKey(model, objectNode, facesEntityIdx, effectColorAdd, effectColorMul, material, textureCoordinates, object->getUniqueShaderId());
370 trfNode = trfNodeIt->second;
372 if (trfNode ==
nullptr) {
375 trfNode->
set(
this, model, objectNode, facesEntityIdx, effectColorAdd, effectColorMul, material, textureCoordinates, object->getShader());
379 for (
auto vertexIdx = 0; vertexIdx < 3; vertexIdx++) {
380 auto arrayIdx = transparentRenderFace->objectNode->mesh->indices[transparentRenderFace->faceIdx * 3 + vertexIdx];
382 modelViewMatrix.
multiply((*transparentRenderFace->objectNode->mesh->vertices)[arrayIdx]),
383 modelViewMatrix.
multiplyNoTranslation((*transparentRenderFace->objectNode->mesh->normals)[arrayIdx]),
384 transparentRenderFace->objectNode->textureMatricesByEntities[facesEntityIdx].multiply(
385 textureCoordinates.size() > 0?
386 Vector2(textureCoordinates[arrayIdx].getArray()):
396 transparentRenderFacesGroup->render(
engine,
renderer, contextIdx);
413 auto& objectRenderContext =
contexts[0];
422 auto currentFrontFace = -1;
423 string shaderParametersHash;
424 auto firstObject = objects[0];
426 vector<int32_t>* boundVBOBaseIds =
nullptr;
427 vector<int32_t>* boundVBOTangentBitangentIds =
nullptr;
428 vector<int32_t>* boundVBOOrigins =
nullptr;
429 auto currentLODLevel = -1;
430 int32_t boundEnvironmentMappingCubeMapTextureId = -1;
431 Vector3 boundEnvironmentMappingCubeMapPosition;
432 for (
auto objectNodeIdx = 0; objectNodeIdx < firstObject->objectNodes.size(); objectNodeIdx++) {
433 auto objectNode = firstObject->objectNodes[objectNodeIdx];
435 const auto& facesEntities = objectNode->node->getFacesEntities();
437 auto facesEntityIdxCount = facesEntities.size();
438 for (
auto faceEntityIdx = 0; faceEntityIdx < facesEntityIdxCount; faceEntityIdx++) {
439 auto facesEntity = &facesEntities[faceEntityIdx];
440 auto isTextureCoordinatesAvailable = facesEntity->isTextureCoordinatesAvailable();
441 auto faces = facesEntity->getFaces().size() * firstObject->instances;
442 auto facesToRender = facesEntity->getFaces().size() * firstObject->enabledInstances;
444 auto material = facesEntity->getMaterial();
445 auto specularMaterialProperties = material !=
nullptr?material->getSpecularMaterialProperties():
nullptr;
447 auto transparentFacesEntity =
false;
449 if (specularMaterialProperties !=
nullptr) {
450 if (specularMaterialProperties->hasColorTransparency() ==
true || specularMaterialProperties->hasTextureTransparency() ==
true) transparentFacesEntity =
true;
451 if (material->isDoubleSided() ==
true ||
452 (specularMaterialProperties->hasDiffuseTextureTransparency() ==
true && specularMaterialProperties->hasDiffuseTextureMaskedTransparency() ==
true)) {
457 if (transparentFacesEntity ==
true) {
459 auto objectCount = objects.size();
460 for (
auto objectIdx = 0; objectIdx < objectCount; objectIdx++) {
461 auto object = objects[objectIdx];
462 auto _objectNode =
object->objectNodes[objectNodeIdx];
466 if (collectTransparentFaces ==
true) {
468 (_objectNode->mesh->skinning ==
true?
470 modelViewMatrix.
set(*_objectNode->nodeTransformMatrix).
multiply(object->getTransformMatrix())
471 ).multiply(cameraMatrix),
472 object->objectNodes[objectNodeIdx],
484 bool materialUpdateOnly =
false;
485 auto objectCount = objects.size();
486 for (
auto objectIdx = 0; objectIdx < objectCount; objectIdx++) {
487 auto object = objects[objectIdx];
488 auto _objectNode =
object->objectNodes[objectNodeIdx];
490 if (object->effectColorMul.getAlpha() < 1.0f - Math::EPSILON ||
491 object->effectColorAdd.getAlpha() < -Math::EPSILON) {
493 if (collectTransparentFaces ==
true) {
495 (_objectNode->mesh->skinning ==
true ?
497 modelViewMatrix.
set(*_objectNode->nodeTransformMatrix).
multiply(object->getTransformMatrix())
498 ).multiply(cameraMatrix),
515 materialUpdateOnly =
false;
519 if (materialUpdateOnly ==
false ||
checkMaterialChangable(_objectNode, faceEntityIdx, renderTypes) ==
true) {
520 setupMaterial(contextIdx, _objectNode, faceEntityIdx, renderTypes, materialUpdateOnly, materialKey);
522 materialUpdateOnly =
true;
531 auto currentVBOBaseIds = _objectNode->renderer->vboBaseIds;
532 if (boundVBOBaseIds != currentVBOBaseIds) {
533 boundVBOBaseIds = currentVBOBaseIds;
535 if (isTextureCoordinatesAvailable ==
true &&
547 auto currentVBOLods = _objectNode->renderer->vboLods;
548 if (currentVBOLods !=
nullptr) {
549 auto distanceSquared = objectCamFromAxis.
set(object->getWorldBoundingBox()->computeClosestPointInBoundingBox(camera->getLookFrom())).
sub(camera->getLookFrom()).
computeLengthSquared();
552 if (currentVBOLods->size() >= 3 && distanceSquared >= Math::square(_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD3Distance())) {
555 if (currentVBOLods->size() >= 2 && distanceSquared >= Math::square(_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD2Distance())) {
558 if (currentVBOLods->size() >= 1 && distanceSquared >= Math::square(_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD1Distance())) {
567 faces = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD3Indices().size() / 3) * firstObject->instances;
568 facesToRender = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD3Indices().size() / 3) * firstObject->enabledInstances;
571 faces = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD2Indices().size() / 3) * firstObject->instances;
572 facesToRender = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD2Indices().size() / 3) * firstObject->enabledInstances;
575 faces = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD1Indices().size() / 3) * firstObject->instances;
576 facesToRender = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD1Indices().size() / 3) * firstObject->enabledInstances;
581 currentLODLevel = lodLevel;
584 auto currentVBONormalMappingIds = _objectNode->renderer->vboNormalMappingIds;
593 auto currentVBOOrigins = _objectNode->renderer->vboOrigins;
594 if (currentVBOOrigins !=
nullptr && currentVBOOrigins != boundVBOOrigins) {
599 _objectNode->mesh->skinning ==
true?
601 modelViewMatrix.
set(*_objectNode->nodeTransformMatrix).
multiply(object->getTransformMatrix())
606 if (objectFrontFace != currentFrontFace) {
608 currentFrontFace = objectFrontFace;
618 shadowMapping !=
nullptr) {
619 shadowMapping->startObjectTransform(
621 _objectNode->mesh->skinning ==
true ?
623 modelViewMatrix.
set(*_objectNode->nodeTransformMatrix).
multiply(object->getTransformMatrix())
635 if (object->getReflectionEnvironmentMappingId().empty() ==
false) {
636 auto environmentMappingEntityCandidate =
engine->
getEntity(object->getReflectionEnvironmentMappingId());
637 if (environmentMappingEntityCandidate !=
nullptr) {
639 environmentMappingEntity =
static_cast<EnvironmentMapping*
>(environmentMappingEntityCandidate);
643 if (entityHierarchyEnvironmentMappingEntity !=
nullptr) environmentMappingEntity =
static_cast<EnvironmentMapping*
>(entityHierarchyEnvironmentMappingEntity);
646 if (environmentMappingEntity !=
nullptr) {
647 Vector3 environmentMappingTranslation;
648 object->getTransformMatrix().getTranslation(environmentMappingTranslation);
650 Vector3 environmentMappingCubeMapPosition =
object->hasReflectionEnvironmentMappingPosition() ==
true?
object->getReflectionEnvironmentMappingPosition():environmentMappingTranslation;
651 if (environmentMappingCubeMapTextureId != boundEnvironmentMappingCubeMapTextureId || environmentMappingCubeMapPosition.
equals(boundEnvironmentMappingCubeMapPosition) ==
false) {
652 boundEnvironmentMappingCubeMapTextureId = environmentMappingCubeMapTextureId;
653 boundEnvironmentMappingCubeMapPosition = environmentMappingCubeMapPosition;
661 if (environmentMappingEntity ==
nullptr && boundEnvironmentMappingCubeMapTextureId != -1) {
665 boundEnvironmentMappingCubeMapTextureId = -1;
671 shadowMapping !=
nullptr) {
672 shadowMapping->endObjectTransform();
677 if (specularMaterialProperties !=
nullptr) {
678 if (material->isDoubleSided() ==
true ||
679 (specularMaterialProperties->hasDiffuseTextureTransparency() ==
true && specularMaterialProperties->hasDiffuseTextureMaskedTransparency() ==
true)) {
694 auto& objectRenderContext =
contexts[threadIdx];
695 auto contextIdx = threadIdx;
709 auto cullingMode = 1;
712 auto firstObject = objects[0];
715 for (
auto objectNodeIdx = 0; objectNodeIdx < firstObject->objectNodes.size(); objectNodeIdx++) {
716 auto objectNode = firstObject->objectNodes[objectNodeIdx];
718 const auto& facesEntities = objectNode->node->getFacesEntities();
720 auto facesEntityIdxCount = facesEntities.size();
721 for (
auto faceEntityIdx = 0; faceEntityIdx < facesEntityIdxCount; faceEntityIdx++) {
722 auto facesEntity = &facesEntities[faceEntityIdx];
723 auto isTextureCoordinatesAvailable = facesEntity->isTextureCoordinatesAvailable();
724 auto faces = facesEntity->getFaces().size() * firstObject->instances;
725 auto facesToRender = facesEntity->getFaces().size() * firstObject->enabledInstances;
727 auto material = facesEntity->getMaterial();
728 auto specularMaterialProperties = material !=
nullptr?material->getSpecularMaterialProperties():
nullptr;
730 auto transparentFacesEntity =
false;
732 if (specularMaterialProperties !=
nullptr) {
733 if (specularMaterialProperties->hasColorTransparency() ==
true || specularMaterialProperties->hasTextureTransparency() ==
true) transparentFacesEntity =
true;
736 if (transparentFacesEntity ==
true) {
738 auto objectCount = objects.size();
739 for (
auto objectIdx = 0; objectIdx < objectCount; objectIdx++) {
740 auto object = objects[objectIdx];
741 auto _objectNode =
object->objectNodes[objectNodeIdx];
745 if (collectTransparentFaces ==
true) {
747 (_objectNode->mesh->skinning ==
true?
749 modelViewMatrixTemp.
set(*_objectNode->nodeTransformMatrix).
multiply(object->getTransformMatrix())
750 ).multiply(cameraMatrix),
751 object->objectNodes[objectNodeIdx],
763 if (material->isDoubleSided() ==
true ||
764 (specularMaterialProperties->hasDiffuseTextureTransparency() ==
true && specularMaterialProperties->hasDiffuseTextureMaskedTransparency() ==
true)) {
765 if (cullingMode != 0) {
770 if (cullingMode != 1) {
776 if (cullingMode != 1) {
783 objectRenderContext.objectsToRender = objects;
785 auto hadFrontFaceSetup =
false;
786 auto hadShaderSetup =
false;
792 FloatBuffer fbEffectColorMuls = objectRenderContext.bbEffectColorMuls->asFloatBuffer();
793 FloatBuffer fbEffectColorAdds = objectRenderContext.bbEffectColorAdds->asFloatBuffer();
794 FloatBuffer fbMvMatrices = objectRenderContext.bbMvMatrices->asFloatBuffer();
797 string shaderParametersHash;
798 bool materialUpdateOnly =
false;
799 vector<int32_t>* boundVBOBaseIds =
nullptr;
800 vector<int32_t>* boundVBOTangentBitangentIds =
nullptr;
801 vector<int32_t>* boundVBOOrigins =
nullptr;
802 auto currentLODLevel = -1;
803 int32_t boundEnvironmentMappingCubeMapTextureId = -1;
804 Vector3 boundEnvironmentMappingCubeMapPosition;
805 auto objectCount = objectRenderContext.objectsToRender.size();
808 auto textureMatrix = objectRenderContext.objectsToRender[0]->objectNodes[objectNodeIdx]->textureMatricesByEntities[faceEntityIdx];
811 for (
auto objectIdx = 0; objectIdx < objectCount; objectIdx++) {
812 auto object = objectRenderContext.objectsToRender[objectIdx];
813 auto _objectNode =
object->objectNodes[objectNodeIdx];
816 if (object->effectColorMul.getAlpha() < 1.0f - Math::EPSILON ||
817 object->effectColorAdd.getAlpha() < -Math::EPSILON) {
819 if (collectTransparentFaces ==
true) {
821 (_objectNode->mesh->skinning ==
true ?
823 modelViewMatrixTemp.
set(*_objectNode->nodeTransformMatrix).
multiply(object->getTransformMatrix())
824 ).multiply(cameraMatrix),
836 objectRenderContext.objectsNotRendered.push_back(
object);
841 if (_objectNode->textureMatricesByEntities[faceEntityIdx].equals(textureMatrix) ==
false) {
842 objectRenderContext.objectsNotRendered.push_back(
object);
847 if (hadShaderSetup ==
false) {
857 hadShaderSetup =
true;
860 objectRenderContext.objectsNotRendered.push_back(
object);
865 auto materialKeyCurrent = materialKey;
866 if (materialUpdateOnly ==
false ||
checkMaterialChangable(_objectNode, faceEntityIdx, renderTypes) ==
true) {
867 setupMaterial(contextIdx, _objectNode, faceEntityIdx, renderTypes, materialUpdateOnly, materialKeyCurrent, materialKey);
869 if (materialUpdateOnly ==
false) {
870 materialKey = materialKeyCurrent;
871 materialUpdateOnly =
true;
876 if (materialKey != materialKeyCurrent) {
877 objectRenderContext.objectsNotRendered.push_back(
object);
882 if (shaderParametersHash.empty() ==
true) {
888 objectRenderContext.objectsNotRendered.push_back(
object);
892 auto currentVBOBaseIds = _objectNode->renderer->vboBaseIds;
893 if (boundVBOBaseIds ==
nullptr) {
894 boundVBOBaseIds = currentVBOBaseIds;
896 if (isTextureCoordinatesAvailable ==
true &&
911 if (boundVBOBaseIds != currentVBOBaseIds) {
912 objectRenderContext.objectsNotRendered.push_back(
object);
915 auto currentVBOLods = _objectNode->renderer->vboLods;
916 if (currentVBOLods !=
nullptr) {
917 auto distanceSquared = objectCamFromAxis.
set(object->getWorldBoundingBox()->computeClosestPointInBoundingBox(camera->getLookFrom())).
sub(camera->getLookFrom()).
computeLengthSquared();
920 if (currentVBOLods->size() >= 3 && distanceSquared >= Math::square(_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD3Distance())) {
923 if (currentVBOLods->size() >= 2 && distanceSquared >= Math::square(_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD2Distance())) {
926 if (currentVBOLods->size() >= 1 && distanceSquared >= Math::square(_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD1Distance())) {
929 if (currentLODLevel != -1 && lodLevel != currentLODLevel) {
930 objectRenderContext.objectsNotRendered.push_back(
object);
937 faces = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD3Indices().size() / 3) * firstObject->instances;
938 facesToRender = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD3Indices().size() / 3) * firstObject->enabledInstances;
941 faces = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD2Indices().size() / 3) * firstObject->instances;
942 facesToRender = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD2Indices().size() / 3) * firstObject->enabledInstances;
945 faces = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD1Indices().size() / 3) * firstObject->instances;
946 facesToRender = (_objectNode->node->getFacesEntities()[faceEntityIdx].getLOD1Indices().size() / 3) * firstObject->enabledInstances;
951 currentLODLevel = lodLevel;
954 auto currentVBONormalMappingIds = _objectNode->renderer->vboNormalMappingIds;
958 if (boundVBOTangentBitangentIds ==
nullptr) {
964 boundVBOTangentBitangentIds = currentVBONormalMappingIds;
967 if (currentVBONormalMappingIds != boundVBOTangentBitangentIds) {
968 objectRenderContext.objectsNotRendered.push_back(
object);
974 auto currentVBOOrigins = _objectNode->renderer->vboOrigins;
975 if (currentVBOOrigins !=
nullptr) {
977 if (boundVBOOrigins ==
nullptr) {
980 boundVBOOrigins = currentVBOOrigins;
983 if (currentVBOOrigins != boundVBOOrigins) {
984 objectRenderContext.objectsNotRendered.push_back(
object);
991 _objectNode->mesh->skinning ==
true?
993 modelViewMatrixTemp.
set(*_objectNode->nodeTransformMatrix).
994 multiply(object->getTransformMatrix())
1000 if (cullingMode == 1) {
1001 if (hadFrontFaceSetup ==
false) {
1002 hadFrontFaceSetup =
true;
1003 if (objectFrontFace != frontFace) {
1004 frontFace = objectFrontFace;
1008 if (objectFrontFace != frontFace) {
1009 objectRenderContext.objectsNotRendered.push_back(
object);
1015 if (object->getReflectionEnvironmentMappingId().empty() ==
false) {
1018 auto environmentMappingEntityCandidate =
engine->
getEntity(object->getReflectionEnvironmentMappingId());
1019 if (environmentMappingEntityCandidate !=
nullptr) {
1021 environmentMappingEntity =
static_cast<EnvironmentMapping*
>(environmentMappingEntityCandidate);
1025 if (entityHierarchyEnvironmentMappingEntity !=
nullptr) environmentMappingEntity =
static_cast<EnvironmentMapping*
>(entityHierarchyEnvironmentMappingEntity);
1029 if (environmentMappingEntity !=
nullptr) {
1030 Vector3 environmentMappingTranslation;
1031 object->getTransformMatrix().getTranslation(environmentMappingTranslation);
1032 auto environmentMappingCubeMapTextureId = environmentMappingEntity->
getCubeMapTextureId();
1033 Vector3 environmentMappingCubeMapPosition =
object->hasReflectionEnvironmentMappingPosition() ==
true?
object->getReflectionEnvironmentMappingPosition():environmentMappingTranslation;
1034 if (boundEnvironmentMappingCubeMapTextureId == -1) {
1035 boundEnvironmentMappingCubeMapTextureId = environmentMappingCubeMapTextureId;
1036 boundEnvironmentMappingCubeMapPosition = environmentMappingCubeMapPosition;
1042 if (boundEnvironmentMappingCubeMapTextureId != environmentMappingCubeMapTextureId || environmentMappingCubeMapPosition.
equals(boundEnvironmentMappingCubeMapPosition) ==
false) {
1043 objectRenderContext.objectsNotRendered.push_back(
object);
1048 if (boundEnvironmentMappingCubeMapTextureId != -1) {
1049 objectRenderContext.objectsNotRendered.push_back(
object);
1054 fbEffectColorMuls.
put(object->effectColorMul.getArray());
1055 fbEffectColorAdds.
put(object->effectColorAdd.getArray());
1063 auto objectsToRenderIssue = fbMvMatrices.
getPosition() / 16;
1064 if (objectsToRenderIssue > 0) {
1093 objectRenderContext.objectsToRender = objectRenderContext.objectsNotRendered;
1094 objectRenderContext.objectsNotRendered.clear();
1097 if (boundEnvironmentMappingCubeMapTextureId != -1) {
1102 }
while (objectRenderContext.objectsToRender.size() > 0);
1110 if (cullingMode != 1) {
1119 objectRenderContext.objectsToRender.clear();
1120 objectRenderContext.objectsNotRendered.clear();
1126 auto material = facesEntities[facesEntityIdx].getMaterial();
1128 if (material ==
nullptr) material = Material::getDefaultMaterial();
1129 auto specularMaterialProperties = material->getSpecularMaterialProperties();
1130 auto pbrMaterialProperties = material->getPBRMaterialProperties();
1133 materialKey = material->getId();
1139 if (updateOnly ==
false) {
1144 rendererMaterial.
ambient = specularMaterialProperties->getAmbientColor().getArray();
1145 rendererMaterial.diffuse = specularMaterialProperties->getDiffuseColor().getArray();
1146 rendererMaterial.specular = specularMaterialProperties->getSpecularColor().getArray();
1147 rendererMaterial.emission = specularMaterialProperties->getEmissionColor().getArray();
1148 rendererMaterial.shininess = specularMaterialProperties->getShininess();
1149 rendererMaterial.reflection = specularMaterialProperties->getReflection();
1150 rendererMaterial.diffuseTextureMaskedTransparency = specularMaterialProperties->hasDiffuseTextureMaskedTransparency() ==
true?1:0;
1151 rendererMaterial.diffuseTextureMaskedTransparencyThreshold = specularMaterialProperties->getDiffuseTextureMaskedTransparencyThreshold();
1173 if (pbrMaterialProperties ==
nullptr) {
1175 rendererMaterial.metallicFactor = 1.0f;
1176 rendererMaterial.roughnessFactor = 1.0f;
1177 rendererMaterial.normalScale = 1.0f;
1178 rendererMaterial.emissiveFactor = {{ 1.0f, 1.0f, 1.0f }};
1179 rendererMaterial.exposure = 1.0f;
1180 rendererMaterial.baseColorTextureMaskedTransparency = 0;
1181 rendererMaterial.baseColorTextureMaskedTransparencyThreshold = 0.0f;
1183 rendererMaterial.baseColorFactor = pbrMaterialProperties->getBaseColorFactor().getArray();
1184 rendererMaterial.metallicFactor = pbrMaterialProperties->getMetallicFactor();
1185 rendererMaterial.roughnessFactor = pbrMaterialProperties->getRoughnessFactor();
1186 rendererMaterial.normalScale = pbrMaterialProperties->getNormalScale();
1187 rendererMaterial.emissiveFactor =
1189 pbrMaterialProperties->getEmissiveFactor()[0],
1190 pbrMaterialProperties->getEmissiveFactor()[1],
1191 pbrMaterialProperties->getEmissiveFactor()[2]
1193 rendererMaterial.exposure = pbrMaterialProperties->getExposure();
1194 rendererMaterial.baseColorTextureMaskedTransparency = pbrMaterialProperties->hasBaseColorTextureMaskedTransparency() ==
true?1:0;
1195 rendererMaterial.baseColorTextureMaskedTransparencyThreshold = pbrMaterialProperties->getBaseColorTextureMaskedTransparencyThreshold();
1220 auto diffuseTexture = specularMaterialProperties->getDiffuseTexture();
1222 rendererMaterial.diffuseTextureMaskedTransparencyThreshold = specularMaterialProperties->getDiffuseTextureMaskedTransparencyThreshold();
1223 rendererMaterial.textureAtlasSize = specularMaterialProperties->getTextureAtlasSize();
1224 rendererMaterial.textureAtlasPixelDimension = { 0.0f, 0.0f };
1225 if (rendererMaterial.textureAtlasSize > 1 && diffuseTexture !=
nullptr) {
1226 rendererMaterial.textureAtlasPixelDimension[0] = 1.0f / diffuseTexture->getTextureWidth();
1227 rendererMaterial.textureAtlasPixelDimension[1] = 1.0f / diffuseTexture->getTextureHeight();
1231 specularMaterialProperties->hasDiffuseTextureMaskedTransparency() ==
true) {
1232 auto diffuseTextureId =
1237 materialKey.append((
const char*)&diffuseTextureId,
sizeof(diffuseTextureId));
1238 if (updateOnly ==
false || currentMaterialKey.empty() ==
true) {
1246 if (pbrMaterialProperties ==
nullptr) {
1248 rendererMaterial.baseColorTextureMaskedTransparencyThreshold = 0.0f;
1250 rendererMaterial.baseColorTextureMaskedTransparency = pbrMaterialProperties->hasBaseColorTextureMaskedTransparency() ==
true?1:0;
1251 rendererMaterial.baseColorTextureMaskedTransparencyThreshold = pbrMaterialProperties->getBaseColorTextureMaskedTransparencyThreshold();
1301 if (pses.size() == 0)
return;
1304 struct PseParameters {
1305 const Color4* effectColorAdd;
1306 const Color4* effectColorMul;
1307 int32_t textureHorizontalSprites;
1308 int32_t textureVerticalSprites;
1310 int32_t atlasTextureIndex;
1312 unordered_map<void*, PseParameters> rendererPseParameters;
1332 for (
auto entity: pses) {
1333 if (entity->getRenderPass() != renderPass)
continue;
1335 if (ppse !=
nullptr) {
1337 if (atlasTextureIndex == TextureAtlas::TEXTURE_IDX_NONE)
continue;
1338 rendererPseParameters[ppse] = {
1339 .effectColorAdd = &ppse->getEffectColorAdd(),
1340 .effectColorMul = &ppse->getEffectColorMul(),
1341 .textureHorizontalSprites = ppse->getTextureHorizontalSprites(),
1342 .textureVerticalSprites = ppse->getTextureVerticalSprites(),
1343 .pointSize = ppse->getPointSize(),
1344 .atlasTextureIndex = atlasTextureIndex
1349 if (fpse !=
nullptr) {
1351 if (atlasTextureIndex == TextureAtlas::TEXTURE_IDX_NONE)
continue;
1352 rendererPseParameters[fpse] = {
1353 .effectColorAdd = &fpse->getEffectColorAdd(),
1354 .effectColorMul = &fpse->getEffectColorMul(),
1355 .textureHorizontalSprites = fpse->getTextureHorizontalSprites(),
1356 .textureVerticalSprites = fpse->getTextureVerticalSprites(),
1357 .pointSize = fpse->getPointSize(),
1358 .atlasTextureIndex = atlasTextureIndex
1368 auto pseParameters = &rendererPseParameters.find(points[0]->particleSystem)->second;
1369 auto currentPpse =
static_cast<void*
>(points[0]->particleSystem);
1372 auto point = points[i];
1373 if (point->particleSystem != (
void*)currentPpse) {
1374 pseParameters = &rendererPseParameters.find(point->particleSystem)->second;
1375 currentPpse = point->particleSystem;
1379 pseParameters->atlasTextureIndex,
1380 pseParameters->pointSize,
1381 *pseParameters->effectColorMul,
1382 *pseParameters->effectColorAdd,
1383 pseParameters->textureHorizontalSprites,
1384 pseParameters->textureVerticalSprites
1389 auto point = points[i];
1390 if (point->particleSystem != (
void*)currentPpse) {
1391 pseParameters = &rendererPseParameters.find(point->particleSystem)->second;
1392 currentPpse = point->particleSystem;
1396 pseParameters->atlasTextureIndex,
1397 pseParameters->pointSize,
1398 *pseParameters->effectColorMul,
1399 *pseParameters->effectColorAdd,
1400 pseParameters->textureHorizontalSprites,
1401 pseParameters->textureVerticalSprites
1427 if (linesEntities.size() == 0)
return;
1443 for (
auto entity: linesEntities) {
1444 if (entity->getRenderPass() != renderPass)
continue;
Color 4 definition class.
TextureAtlas & getPointParticleSystemTextureAtlas()
ShadowMapping * getShadowMapping()
TextureAtlas ppsTextureAtlas
static Engine * getInstance()
Returns engine instance.
static ParticlesShader * getParticlesShader()
static STATIC_DLL_IMPEXT unique_ptr< Queue< EngineThreadQueueElement > > engineThreadsQueue
static VBOManager * getVBOManager()
static STATIC_DLL_IMPEXT EngineThreadQueueElementPool engineThreadQueueElementPool
Entity * getEntity(const string &id)
Returns a entity by given id.
static int getThreadCount()
unique_ptr< Camera > camera
static STATIC_DLL_IMPEXT vector< unique_ptr< EngineThread > > engineThreads
static LinesShader * getLinesShader()
static constexpr int ENGINETHREADSQUEUE_RENDER_DISPATCH_COUNT
array< unique_ptr< Light >, LIGHTS_MAX > lights
Entity hierarchy to be used with engine class.
const string & getShaderParametersHash() const
@ ENTITYTYPE_ENVIRONMENTMAPPING
@ ENTITYTYPE_ENTITYHIERARCHY
Environment mapping entity.
int32_t getCubeMapTextureId()
Fog particle system entity to be used with engine class.
Lines entity to be used with engine class.
Object to be used with engine class.
Point particle system entity to be used with engine class.
Represents a model face, consisting of vertex, normal, tangent and bitangent vectors,...
Node faces entity A node can have multiple entities containing faces and a applied material.
bool isTextureCoordinatesAvailable() const
const Material * getMaterial() const
Representation of a 3D model.
const vector< Vector2 > & getTextureCoordinates() const
const vector< FacesEntity > & getFacesEntities() const
Represents specular material properties.
Represents specular material properties.
Interface to lighting shader program.
void setParameters(int contextIdx, int32_t textureId, float lineWidth)
Set parameters.
VBOManager_VBOManaged * addVBO(const string &vboId, int32_t ids, bool useGPUMemory, bool shared, bool &created)
Adds a VBO to manager or retrieve VBO if existing.
void removeVBO(const string &vboId)
Removes a VBO from manager.
Particles shader program.
void setTextureAtlas(int contextIdx, TextureAtlas *textureAtlas)
Set texture atlas.
virtual void setTextureUnit(int contextIdx, int32_t textureUnit)=0
Sets up texture unit.
virtual void bindCubeMapTexture(int contextIdx, int32_t textureId)=0
Binds a cube map texture with given id or unbinds when using ID_NONE.
virtual void onUpdateProjectionMatrix(int contextIdx)=0
Update projection matrix event.
void setEnvironmentMappingCubeMapPosition(int contextIdx, const array< float, 3 > &position)
Set environment mapping cube map position.
array< float, 4 > & getEffectColorAdd(int contextIdx)
Get effect color add.
virtual void bindEffectColorMulsBufferObject(int contextIdx, int32_t bufferObjectId, int32_t divisor)=0
Bind effect color muls buffer object.
Matrix3x3 & getTextureMatrix(int contextIdx)
Get texture matrix.
virtual void drawInstancedIndexedTrianglesFromBufferObjects(int contextIdx, int32_t triangles, int32_t trianglesOffset, int32_t instances)=0
Draw instanced indexed triangles from buffer objects.
virtual void enableCulling(int contextIdx)=0
Enable culling.
virtual void drawLinesFromBufferObjects(int contextIdx, int32_t points, int32_t pointsOffset)=0
Draw lines from buffer objects.
virtual void onUpdateCameraMatrix(int contextIdx)=0
Update camera matrix event.
virtual bool isSupportingMultithreadedRendering()=0
virtual void bindTangentsBufferObject(int contextIdx, int32_t bufferObjectId)=0
Bind tangents buffer object.
int32_t LIGHTING_SPECULAR
virtual void onUpdateShader(int contextIdx)=0
On update shader.
virtual bool isSupportingIntegerProgramAttributes()=0
array< float, 4 > & getEffectColorMul(int contextIdx)
Get effect color mul.
virtual void unbindBufferObjects(int contextIdx)=0
Unbind buffer objects.
const string & getShader(int contextIdx)
Get shader.
virtual void enableBlending()=0
Enables blending.
virtual void disableBlending()=0
Disables blending.
const EntityShaderParameters & getShaderParameters(int contextIdx)
Get shader parameters.
virtual void onUpdateTextureMatrix(int contextIdx)=0
Update texture matrix for active texture unit event.
virtual void bindTexture(int contextIdx, int32_t textureId)=0
Binds a texture with given id or unbinds when using ID_NONE.
virtual void bindModelMatricesBufferObject(int contextIdx, int32_t bufferObjectId)=0
Bind model matrices buffer object.
virtual void bindIndicesBufferObject(int contextIdx, int32_t bufferObjectId)=0
Bind indices buffer object.
Renderer_SpecularMaterial & getSpecularMaterial(int contextIdx)
Get specular material.
virtual void setFrontFace(int contextIdx, int32_t frontFace)=0
Set up clock wise or counter clock wise faces as front face.
virtual bool isInstancedRenderingAvailable()=0
Checks if instanced rendering is available.
void setShader(int contextIdx, const string &id)
Set shader.
Matrix4x4 & getModelViewMatrix()
virtual void onUpdateModelViewMatrix(int contextIdx)=0
Update model view matrix event.
virtual void bindBitangentsBufferObject(int contextIdx, int32_t bufferObjectId)=0
Bind bitangents buffer object.
virtual void onUpdateShaderParameters(int contextIdx)=0
On update shader parameters.
int32_t getLighting(int contextIdx)
Get current lighting model.
virtual void disableCulling(int contextIdx)=0
Disable culling.
virtual void drawIndexedTrianglesFromBufferObjects(int contextIdx, int32_t triangles, int32_t trianglesOffset)=0
Draw indexed triangles from buffer objects.
int32_t CONTEXTINDEX_DEFAULT
virtual bool isNormalMappingAvailable()=0
virtual bool isSpecularMappingAvailable()=0
virtual void uploadBufferObject(int contextIdx, int32_t bufferObjectId, int32_t size, FloatBuffer *data)=0
Uploads buffer data to buffer object.
virtual void bindTextureCoordinatesBufferObject(int contextIdx, int32_t bufferObjectId)=0
Bind texture coordinates buffer object.
virtual void onUpdateEffect(int contextIdx)=0
Update material.
Matrix4x4 & getCameraMatrix()
Renderer_PBRMaterial & getPBRMaterial(int contextIdx)
Get PBR material.
virtual void onUpdateMaterial(int contextIdx)=0
On update material.
virtual void bindColorsBufferObject(int contextIdx, int32_t bufferObjectId)=0
Bind colors buffer object.
virtual void bindVerticesBufferObject(int contextIdx, int32_t bufferObjectId)=0
Bind vertices buffer object.
void setShaderParameters(int contextIdx, const EntityShaderParameters ¶meters)
Set shader parameters.
virtual void bindEffectColorAddsBufferObject(int contextIdx, int32_t bufferObjectId, int32_t divisor)=0
Bind effect color adds buffer object.
virtual void bindNormalsBufferObject(int contextIdx, int32_t bufferObjectId)=0
Bind normals buffer object.
virtual void bindOriginsBufferObject(int contextIdx, int32_t bufferObjectId)=0
Bind origins buffer object.
Batch renderer for points.
Batch renderer for transparent triangles.
Simple class to determine if a transform matrix is right handed.
bool isRightHanded(Matrix4x4 &matrix)
Check if matrix is right handed.
Entity renderer transparent render faces node pool.
static constexpr int32_t RENDERTYPE_TEXTUREARRAYS_DIFFUSEMASKEDTRANSPARENCY
static constexpr int32_t INSTANCEDRENDERING_OBJECTS_MAX
void prepareTransparentFaces(const vector< TransparentRenderFace * > &transparentRenderFaces)
Renders transparent faces TODO: guess this should be optimized regarding GL commands skinned mesh is ...
bool checkMaterialChangable(ObjectNode *objectNode, int32_t facesEntityIdx, int32_t renderTypes)
Checks if a material could change when having multiple objects but same model.
void render(Entity::RenderPass renderPass, const vector< Object * > &objects, bool renderTransparentFaces, int32_t renderTypes)
Renders all given objects.
unique_ptr< RenderTransparentRenderPointsPool > renderTransparentRenderPointsPool
static constexpr int32_t RENDERTYPE_TEXTUREARRAYS
void renderFunction(int threadIdx, Entity::RenderPass renderPass, const vector< Object * > &objects, array< vector< Object * >, Engine::UNIQUEMODELID_MAX > &objectsByModels, bool renderTransparentFaces, int renderTypes, TransparentRenderFacesPool *transparentRenderFacesPool)
Render function.
unique_ptr< EntityRenderer_TransparentRenderFacesGroupPool > transparentRenderFacesGroupPool
array< vector< Object * >, Engine::UNIQUEMODELID_MAX > objectsByModels
static constexpr int32_t RENDERTYPE_NORMALS
BatchRendererTriangles * acquireTrianglesBatchRenderer()
static constexpr int32_t RENDERTYPE_TEXTURES_DIFFUSEMASKEDTRANSPARENCY
unique_ptr< TransparentRenderFacesPool > transparentRenderFacesPool
static constexpr int32_t RENDERTYPE_TEXTURES
static constexpr int32_t RENDERTYPE_MATERIALS
static constexpr int32_t RENDERTYPE_SHADOWMAPPING
void setupMaterial(int contextIdx, ObjectNode *objectNode, int32_t facesEntityIdx, int32_t renderTypes, bool updateOnly, string &materialKey, const string ¤tMaterialKey=string())
Set ups a material for rendering.
void renderObjectsOfSameTypeInstanced(int threadIdx, const vector< Object * > &objects, bool collectTransparentFaces, int32_t renderTypes, TransparentRenderFacesPool *transparentRenderFacesPool)
Renders multiple objects of same type(with same model) using instancing.
void releaseTransparentFacesGroups()
Release transparent faces groups.
unordered_map< tuple< Model *, ObjectNode *, int32_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, int32_t, const Material *, bool, uint8_t >, TransparentRenderFacesGroup *, TransparentRenderFacesGroup_Hash > transparentRenderFacesGroups
vector< ObjectRenderContext > contexts
vector< unique_ptr< BatchRendererTriangles > > trianglesBatchRenderers
static constexpr int32_t RENDERTYPE_EFFECTCOLORS
unique_ptr< BatchRendererPoints > psePointBatchRenderer
void renderTransparentFacesGroups(int contextIdx)
Render transparent faces groups.
vector< TransparentRenderFace * > nodeTransparentRenderFaces
void clearMaterial(int contextIdx)
Clear material for rendering.
static constexpr int32_t BATCHRENDERER_MAX
void reset()
Resets the object renderer.
~EntityRenderer()
Destructor.
void renderObjectsOfSameTypeNonInstanced(const vector< Object * > &objects, bool collectTransparentFaces, int32_t renderTypes)
Renders multiple objects of same type(with same model) not using instancing.
void renderTransparentFaces()
Renders collected transparent faces.
Buffers used to transfer data between main memory to graphics board memory.
Object node mesh specifically for rendering.
Object node VBO renderer.
Object node specifically for rendering.
vector< int32_t > pbrMaterialBaseColorTextureIdsByEntities
vector< int32_t > specularMaterialDiffuseTextureIdsByEntities
vector< int32_t > specularMaterialDynamicDiffuseTextureIdsByEntities
vector< int32_t > pbrMaterialMetallicRoughnessTextureIdsByEntities
vector< int32_t > specularMaterialNormalTextureIdsByEntities
vector< int32_t > specularMaterialSpecularTextureIdsByEntities
vector< int32_t > pbrMaterialNormalTextureIdsByEntities
vector< int32_t > pbrMaterialEmissiveTextureIdsByEntities
static constexpr int32_t TEXTUREID_NONE
static void setupTextures(Renderer *renderer, int contextIdx, ObjectNode *objectNode, int32_t facesEntityIdx)
Set up textures for given object node and faces entity.
Render transparent render points pool.
Transparent render faces group.
void addVertex(const Vector3 &vertex, const Vector3 &normal, const Vector2 &textureCoordinate)
Adds a vertex to this transparent render faces group.
void set(EntityRenderer *objectRenderer, Model *model, ObjectNode *objectNode, int32_t facesEntityIdx, const Color4 &effectColorAdd, const Color4 &effectColorMul, const Material *material, bool textureCoordinates, const string &shader)
Set transparent render faces group.
static const tuple< Model *, ObjectNode *, int32_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, int32_t, const Material *, bool, uint8_t > createKey(Model *model, ObjectNode *objectNode, int32_t facesEntityIdx, const Color4 &effectColorAdd, const Color4 &effectColorMul, const Material *material, bool textureCoordinates, uint8_t uniqueShaderId)
Creates a key for given transparent render faces group attributes.
Transparent render faces pool.
Transparent render points pool.
Matrix3x3 & identity()
Creates identity matrix.
Matrix3x3 & set(float r0c0, float r0c1, float r0c2, float r1c0, float r1c1, float r1c2, float r2c0, float r2c1, float r2c2)
Sets this matrix by its components.
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Matrix4x4 & identity()
Creates identity matrix.
Vector3 multiply(const Vector3 &vector3) const
Multiplies this matrix with vector3.
Matrix4x4 & set(float r0c0, float r0c1, float r0c2, float r0c3, float r1c0, float r1c1, float r1c2, float r1c3, float r2c0, float r2c1, float r2c2, float r2c3, float r3c0, float r3c1, float r3c2, float r3c3)
Sets this matrix by its components.
const array< float, 16 > & getArray() const
Vector3 multiplyNoTranslation(const Vector3 &vector3) const
Multiplies this matrix with vector3 while ignoring translation.
Vector2 class representing vector2 mathematical structure and operations with x, y components.
Vector3 class representing vector3 mathematical structure and operations with x, y,...
const array< float, 3 > & getArray() const
float computeLengthSquared() const
Vector3 & sub(float scalar)
Subtracts a scalar.
Vector3 & set(float x, float y, float z)
Sets this vector3 by its components.
bool equals(const Vector3 &vector3, float tolerance=Math::EPSILON) const
Compares this vector3 with given vector3.
FloatBuffer * put(float value)
Put a float value into float buffer.
virtual int64_t getPosition()
T * allocate()
Allocate a new element from pool.
void reset()
Reset this pool.
int getTextureIdx(Texture *texture)
Returns specific atlas texture index within atlas.
Lighting shader constants.
Particle emitter interface.
array< float, 4 > baseColorFactor
int baseColorTextureMaskedTransparency
array< float, 4 > ambient
int diffuseTextureMaskedTransparency
Entity renderer parameters.
Transparent face to be rendered.
Transparent point to be rendered.