Skip to content

Commit

Permalink
UPBGE: Fix conversion of realtime maps. (#857)
Browse files Browse the repository at this point in the history
The issue #855 reports a bug related to the cube and planar map, this is explained
by the fact that the texture renderers try to convert before the textures are
available.
The texture are converted in reload material step which is proceeded after conversion
and post conversion. In the same time leaving texture renderer conversion the ability
to be mutlithread could be very dangerous as they could create FBO and manipulate
any other OpenGL setting for initialization.

The issue is solved by making KX_BlenderMaterial::InitTextures public and call it
into post conversion step and move after in the same step the conversion of
texture renderers.

As the scene converter is constant in post conversion (it's forbidden to create
data but allowed to modify) the function starting with Find are now constant and
their bodies is adapted to avoid implicit insert in std::map.

Fix issue #855.
  • Loading branch information
panzergame committed Oct 3, 2018
1 parent 607351f commit eebb46f
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 57 deletions.
12 changes: 6 additions & 6 deletions source/gameengine/Common/CM_Map.h
Expand Up @@ -24,26 +24,26 @@
* \ingroup common
*/

#ifndef __CM_LIST_H__
#define __CM_LIST_H__
#ifndef __CM_MAP_H__
#define __CM_MAP_H__

#include <map>
#include <unordered_map>

template <class Item, class Key, class ... Args>
inline const Item& CM_MapGetItemNoInsert(const std::map<Key, Item, Args ...>& map, const Key& key, const Item defaultItem = nullptr)
inline const Item CM_MapGetItemNoInsert(const std::map<Key, Item, Args ...>& map, const Key& key, const Item defaultItem = nullptr)
{
const typename std::map<Key, Item, Args ...>::iterator it = map.find(key);
const typename std::map<Key, Item, Args ...>::const_iterator it = map.find(key);
if (it != map.end()) {
return it->second;
}
return defaultItem;
}

template <class Item, class Key, class ... Args>
inline const Item& CM_MapGetItemNoInsert(const std::unordered_map<Key, Item, Args ...>& map, const Key& key, const Item defaultItem = nullptr)
inline const Item CM_MapGetItemNoInsert(const std::unordered_map<Key, Item, Args ...>& map, const Key& key, const Item defaultItem = nullptr)
{
const typename std::map<Key, Item, Args ...>::iterator it = map.find(key);
const typename std::map<Key, Item, Args ...>::const_iterator it = map.find(key);
if (it != map.end()) {
return it->second;
}
Expand Down
69 changes: 37 additions & 32 deletions source/gameengine/Converter/BL_BlenderDataConversion.cpp
Expand Up @@ -1688,38 +1688,6 @@ void BL_ConvertBlenderObjects(struct Main *maggie,
}
}

// Look at every material texture and ask to create realtime cube map.
for (KX_GameObject *gameobj : sumolist) {
for (KX_Mesh *mesh : gameobj->GetMeshList()) {
for (RAS_MeshMaterial *meshmat : mesh->GetMeshMaterialList()) {
RAS_IMaterial *mat = meshmat->GetBucket()->GetMaterial();

for (unsigned short k = 0; k < RAS_Texture::MaxUnits; ++k) {
RAS_Texture *tex = mat->GetTexture(k);
if (!tex || !tex->Ok()) {
continue;
}

EnvMap *env = tex->GetTex()->env;
if (!env || env->stype != ENV_REALT) {
continue;
}

KX_GameObject *viewpoint = gameobj;
if (env->object) {
KX_GameObject *obj = converter.FindGameObject(env->object);
if (obj) {
viewpoint = obj;
}
}

KX_TextureRendererManager::RendererType type = tex->IsCubeMap() ? KX_TextureRendererManager::CUBE : KX_TextureRendererManager::PLANAR;
kxscene->GetTextureRendererManager()->AddRenderer(type, tex, viewpoint);
}
}
}
}

// Create and set bounding volume.
for (KX_GameObject *gameobj : sumolist) {
Object *blenderobject = gameobj->GetBlenderObject();
Expand Down Expand Up @@ -1905,5 +1873,42 @@ void BL_PostConvertBlenderObjects(KX_Scene *kxscene, const BL_SceneConverter& sc
}

#endif // WITH_PYTHON

// Init textures for all materials.
for (KX_BlenderMaterial *mat : sceneconverter.GetMaterials()) {
mat->InitTextures();
}

// Look at every material texture and ask to create realtime map.
for (KX_GameObject *gameobj : sumolist) {
for (KX_Mesh *mesh : gameobj->GetMeshList()) {
for (RAS_MeshMaterial *meshmat : mesh->GetMeshMaterialList()) {
RAS_IMaterial *mat = meshmat->GetBucket()->GetMaterial();

for (unsigned short k = 0; k < RAS_Texture::MaxUnits; ++k) {
RAS_Texture *tex = mat->GetTexture(k);
if (!tex || !tex->Ok()) {
continue;
}

EnvMap *env = tex->GetTex()->env;
if (!env || env->stype != ENV_REALT) {
continue;
}

KX_GameObject *viewpoint = gameobj;
if (env->object) {
KX_GameObject *obj = sceneconverter.FindGameObject(env->object);
if (obj) {
viewpoint = obj;
}
}

KX_TextureRendererManager::RendererType type = tex->IsCubeMap() ? KX_TextureRendererManager::CUBE : KX_TextureRendererManager::PLANAR;
kxscene->GetTextureRendererManager()->AddRenderer(type, tex, viewpoint);
}
}
}
}
}

26 changes: 16 additions & 10 deletions source/gameengine/Converter/BL_SceneConverter.cpp
Expand Up @@ -37,6 +37,7 @@
#include "KX_BlenderMaterial.h"

#include "CM_List.h"
#include "CM_Map.h"

BL_SceneConverter::BL_SceneConverter(KX_Scene *scene, const BL_Resource::Library& libraryId)
:m_scene(scene),
Expand Down Expand Up @@ -90,9 +91,9 @@ void BL_SceneConverter::UnregisterGameObject(KX_GameObject *gameobject)
CM_ListRemoveIfFound(m_objects, gameobject);
}

KX_GameObject *BL_SceneConverter::FindGameObject(Object *for_blenderobject)
KX_GameObject *BL_SceneConverter::FindGameObject(Object *for_blenderobject) const
{
return m_map_blender_to_gameobject[for_blenderobject];
return CM_MapGetItemNoInsert(m_map_blender_to_gameobject, for_blenderobject);
}

void BL_SceneConverter::RegisterGameMesh(KX_Mesh *gamemesh, Mesh *for_blendermesh)
Expand All @@ -105,9 +106,9 @@ void BL_SceneConverter::RegisterGameMesh(KX_Mesh *gamemesh, Mesh *for_blendermes
m_meshobjects.push_back(gamemesh);
}

KX_Mesh *BL_SceneConverter::FindGameMesh(Mesh *for_blendermesh)
KX_Mesh *BL_SceneConverter::FindGameMesh(Mesh *for_blendermesh) const
{
return m_map_mesh_to_gamemesh[for_blendermesh];
return CM_MapGetItemNoInsert(m_map_mesh_to_gamemesh, for_blendermesh);
}

void BL_SceneConverter::RegisterMaterial(KX_BlenderMaterial *blmat, Material *mat)
Expand All @@ -120,9 +121,9 @@ void BL_SceneConverter::RegisterMaterial(KX_BlenderMaterial *blmat, Material *ma
m_materials.push_back(blmat);
}

KX_BlenderMaterial *BL_SceneConverter::FindMaterial(Material *mat)
KX_BlenderMaterial *BL_SceneConverter::FindMaterial(Material *mat) const
{
return m_map_mesh_to_polyaterial[mat];
return CM_MapGetItemNoInsert(m_map_mesh_to_polyaterial, mat);
}

void BL_SceneConverter::RegisterActionData(BL_ActionData *data)
Expand All @@ -136,19 +137,19 @@ void BL_SceneConverter::RegisterGameActuator(SCA_IActuator *act, bActuator *for_
m_map_blender_to_gameactuator[for_actuator] = act;
}

SCA_IActuator *BL_SceneConverter::FindGameActuator(bActuator *for_actuator)
SCA_IActuator *BL_SceneConverter::FindGameActuator(bActuator *for_actuator) const
{
return m_map_blender_to_gameactuator[for_actuator];
return CM_MapGetItemNoInsert(m_map_blender_to_gameactuator, for_actuator);
}

void BL_SceneConverter::RegisterGameController(SCA_IController *cont, bController *for_controller)
{
m_map_blender_to_gamecontroller[for_controller] = cont;
}

SCA_IController *BL_SceneConverter::FindGameController(bController *for_controller)
SCA_IController *BL_SceneConverter::FindGameController(bController *for_controller) const
{
return m_map_blender_to_gamecontroller[for_controller];
return CM_MapGetItemNoInsert(m_map_blender_to_gamecontroller, for_controller);
}

BL_ConvertObjectInfo *BL_SceneConverter::GetObjectInfo(Object *blenderobj)
Expand All @@ -169,3 +170,8 @@ const std::vector<KX_GameObject *> &BL_SceneConverter::GetObjects() const
{
return m_objects;
}

const std::vector<KX_BlenderMaterial *> &BL_SceneConverter::GetMaterials() const
{
return m_materials;
}
11 changes: 6 additions & 5 deletions source/gameengine/Converter/BL_SceneConverter.h
Expand Up @@ -94,25 +94,26 @@ class BL_SceneConverter

void RegisterGameObject(KX_GameObject *gameobject, Object *for_blenderobject);
void UnregisterGameObject(KX_GameObject *gameobject);
KX_GameObject *FindGameObject(Object *for_blenderobject);
KX_GameObject *FindGameObject(Object *for_blenderobject) const;

void RegisterGameMesh(KX_Mesh *gamemesh, Mesh *for_blendermesh);
KX_Mesh *FindGameMesh(Mesh *for_blendermesh);
KX_Mesh *FindGameMesh(Mesh *for_blendermesh) const;

void RegisterMaterial(KX_BlenderMaterial *blmat, Material *mat);
KX_BlenderMaterial *FindMaterial(Material *mat);
KX_BlenderMaterial *FindMaterial(Material *mat) const;

void RegisterActionData(BL_ActionData *data);

void RegisterGameActuator(SCA_IActuator *act, bActuator *for_actuator);
SCA_IActuator *FindGameActuator(bActuator *for_actuator);
SCA_IActuator *FindGameActuator(bActuator *for_actuator) const;

void RegisterGameController(SCA_IController *cont, bController *for_controller);
SCA_IController *FindGameController(bController *for_controller);
SCA_IController *FindGameController(bController *for_controller) const;

BL_ConvertObjectInfo *GetObjectInfo(Object *blenderobj);

const std::vector<KX_GameObject *>& GetObjects() const;
const std::vector<KX_BlenderMaterial *>& GetMaterials() const;
};

#endif // __KX_BLENDERSCENECONVERTER_H__
2 changes: 0 additions & 2 deletions source/gameengine/Ketsji/KX_BlenderMaterial.cpp
Expand Up @@ -198,8 +198,6 @@ void KX_BlenderMaterial::ReloadMaterial()
m_blenderShader->ReloadMaterial();
}
else {
// Init textures.
InitTextures();
// Create shader.
m_blenderShader = new BL_BlenderShader(m_scene, m_material, this);

Expand Down
4 changes: 2 additions & 2 deletions source/gameengine/Ketsji/KX_BlenderMaterial.h
Expand Up @@ -53,6 +53,8 @@ class KX_BlenderMaterial : public EXP_Value, public BL_Resource, public RAS_IMat
virtual SCA_IScene *GetScene() const;
virtual void ReloadMaterial();

void InitTextures();

void ReplaceScene(KX_Scene *scene);

static void EndFrame(RAS_Rasterizer *rasty);
Expand Down Expand Up @@ -123,8 +125,6 @@ class KX_BlenderMaterial : public EXP_Value, public BL_Resource, public RAS_IMat
float specularalpha;
} m_savedData;

void InitTextures();

void ActivateGLMaterials(RAS_Rasterizer *rasty) const;

void SetBlenderShaderData(RAS_Rasterizer *ras);
Expand Down

0 comments on commit eebb46f

Please sign in to comment.