Skip to content

Commit

Permalink
Fix FOV calculation, projected texture orientation, crash when heighm…
Browse files Browse the repository at this point in the history
…aps are present

Signed-off-by: Ian Chen <[email protected]>
  • Loading branch information
iche033 committed Sep 16, 2023
1 parent 8c1fd27 commit fbb6bbc
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 11 deletions.
47 changes: 47 additions & 0 deletions examples/projector/Main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <gz/common/Console.hh>
#include <gz/rendering.hh>

#include <gz/common/geospatial/ImageHeightmap.hh>

#include "example_config.hh"
#include "GlutWindow.hh"

Expand Down Expand Up @@ -142,6 +144,51 @@ void buildScene(ScenePtr _scene)
camera->SetVisibilityMask(0x01);

root->AddChild(camera);

auto data = std::make_shared<common::ImageHeightmap>();
data->Load(common::joinPaths(RESOURCE_PATH, "heightmap_bowl.png"));

HeightmapDescriptor desc;
desc.SetName("example_bowl");
desc.SetData(data);
desc.SetSize({17, 17, 10});
desc.SetSampling(2u);
desc.SetUseTerrainPaging(false);

HeightmapTexture textureA;
textureA.SetSize(1.0);
textureA.SetDiffuse("../media/dirt_diffusespecular.png");
textureA.SetNormal("../media/flat_normal.png");
desc.AddTexture(textureA);

HeightmapBlend blendA;
blendA.SetMinHeight(2.0);
blendA.SetFadeDistance(5.0);
desc.AddBlend(blendA);

HeightmapTexture textureB;
textureB.SetSize(1.0);
textureB.SetDiffuse("../media/grass_diffusespecular.png");
textureB.SetNormal("../media/flat_normal.png");
desc.AddTexture(textureB);

HeightmapBlend blendB;
blendB.SetMinHeight(4.0);
blendB.SetFadeDistance(5.0);
desc.AddBlend(blendB);

HeightmapTexture textureC;
textureC.SetSize(1.0);
textureC.SetDiffuse("../media/fungus_diffusespecular.png");
textureC.SetNormal("../media/flat_normal.png");
desc.SetPosition({-20, 10, 0});
desc.AddTexture(textureC);

auto heightmapGeom = _scene->CreateHeightmap(desc);

auto vis = _scene->CreateVisual();
vis->AddGeometry(heightmapGeom);
root->AddChild(vis);
}

//////////////////////////////////////////////////
Expand Down
3 changes: 3 additions & 0 deletions ogre2/src/Ogre2Heightmap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ void Ogre2Heightmap::Init()

Ogre::Hlms *hlmsTerra =
ogreRoot->getHlmsManager()->getHlms(Ogre::HLMS_USER3);
hlmsTerra->setDebugOutputPath(true, false);
// hlmsTerra->_setProperty(Ogre::HlmsBaseProp::EnableDecals, 0);
// hlmsTerra->_setProperty(Ogre::HlmsBaseProp::DecalsDiffuse, 1);

GZ_ASSERT(dynamic_cast<Ogre::HlmsTerra*>(hlmsTerra),
"HlmsTerra incorrectly setup, memory corrupted, or "
Expand Down
9 changes: 6 additions & 3 deletions ogre2/src/Ogre2Projector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,16 @@ Ogre2Projector::Ogre2Projector()
/////////////////////////////////////////////////
Ogre2Projector::~Ogre2Projector()
{
this->SetEnabled(false);

if (!this->scene->IsInitialized())
return;

this->SetEnabled(false);

for (const auto &ogreCamIt : this->dataPtr->camerasWithListener)
{
Ogre::IdString camName = ogreCamIt.second;
auto ogreCam = this->scene->OgreSceneManager()->findCameraNoThrow(camName);
if (ogreCam)
ogreCam->removeListener(this->dataPtr->listener.get());
}
this->dataPtr->camerasWithListener.clear();
Expand Down Expand Up @@ -230,6 +231,7 @@ void Ogre2Projector::CreateProjector()
{
this->dataPtr->decalNode = this->ogreNode->createChildSceneNode();
this->dataPtr->decalNode->roll(Ogre::Degree(90));
this->dataPtr->decalNode->yaw(Ogre::Degree(180));

this->dataPtr->decal = this->scene->OgreSceneManager()->createDecal();
this->dataPtr->decalNode->attachObject(this->dataPtr->decal);
Expand Down Expand Up @@ -275,7 +277,8 @@ void Ogre2Projector::CreateProjector()

// approximate frustum size
common::Image image(this->textureName);
const double aspectRatio = image.Width() / image.Height();
const double aspectRatio = static_cast<double>(image.Width()) /
static_cast<double>(image.Height());
const double vfov = 2.0 * atan(tan(this->hfov.Radian() / 2.0)
/ aspectRatio);

Expand Down
23 changes: 22 additions & 1 deletion ogre2/src/media/Hlms/Terra/GLSL/PixelShader_ps.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,28 @@ vulkan( layout( ogre_s@value(terrainNormals) ) uniform sampler samplerStateTerra
@insertpiece( DeclParallaxLocalCorrect )
@end

@insertpiece( DeclDecalsSamplers )
// The DeclDecalsSamplers insertpiece does not seem to do anything.
// The contents from DeclDecalsSamplers are manually pasted below
// This prevents a crash when there are decals in the scene
// @insertpiece( DeclDecalsSamplers )
@property( hlms_forwardplus )
@property( hlms_enable_decals )
@piece( DeclDecalsSamplers )
@property( syntax == glslvk )
layout( ogre_s@value(decalsSampler) ) uniform sampler decalsSampler;
@end
@property( hlms_decals_diffuse ) vulkan_layout( ogre_t@value(decalsDiffuseTex) ) uniform texture2DArray decalsDiffuseTex;@end
@property( hlms_decals_normals )vulkan_layout( ogre_t@value(decalsNormalsTex) ) uniform texture2DArray decalsNormalsTex;@end
@property( hlms_decals_diffuse == hlms_decals_emissive )
#define decalsEmissiveTex decalsDiffuseTex
@end
@property( hlms_decals_emissive && hlms_decals_diffuse != hlms_decals_emissive )
vulkan_layout( ogre_t@value(decalsEmissiveTex) ) uniform texture2DArray decalsEmissiveTex;
@end
@end
@end
@end


@insertpiece( DeclShadowMapMacros )
@insertpiece( DeclShadowSamplers )
Expand Down
3 changes: 3 additions & 0 deletions ogre2/src/media/Hlms/Terra/gz/500.gz_Structs_piece_all.any
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@

@piece( custom_VStoPS_terra )
INTERPOLANT( float localHeight, @counter(texcoord) );

// added to prevent crash when decals are in the scene
INTERPOLANT( float3 normal, @counter(texcoord) );
@end
107 changes: 100 additions & 7 deletions test/integration/projector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
#include "CommonRenderingTest.hh"

#include <gz/common/Image.hh>
#include <gz/common/geospatial/ImageHeightmap.hh>

#include "gz/rendering/Camera.hh"
#include "gz/rendering/Heightmap.hh"
#include "gz/rendering/Material.hh"
#include "gz/rendering/Projector.hh"
#include "gz/rendering/Scene.hh"
Expand All @@ -47,11 +49,6 @@ TEST_F(ProjectorTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(Visibility))
ScenePtr scene = engine->CreateScene("scene");
ASSERT_NE(nullptr, scene);

// Projector and can only be accessed by the scene extension API
// in gz-rendering7
if (!scene->Extension())
return;

scene->SetBackgroundColor(0, 0, 0);
scene->SetAmbientLight(1, 1, 1);

Expand Down Expand Up @@ -152,11 +149,9 @@ TEST_F(ProjectorTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(Visibility))

common::Image imgA;
imgA.SetFromData(dataA, width, height, common::Image::RGB_INT8);
imgA.SavePNG("imageA.png");

common::Image imgB;
imgB.SetFromData(dataB, width, height, common::Image::RGB_INT8);
imgB.SavePNG("imageB.png");

for (unsigned int i = 0; i < height; ++i)
{
Expand Down Expand Up @@ -184,3 +179,101 @@ TEST_F(ProjectorTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(Visibility))
// Clean up
engine->DestroyScene(scene);
}

/////////////////////////////////////////////////
TEST_F(ProjectorTest, GZ_UTILS_TEST_DISABLED_ON_WIN32(Heightmap))
{
// This test checks that projectors and heightmaps can co-exist
ScenePtr scene = engine->CreateScene("scene");
ASSERT_NE(nullptr, scene);

scene->SetBackgroundColor(0, 0, 0);
scene->SetAmbientLight(1, 1, 1);

VisualPtr root = scene->RootVisual();
ASSERT_NE(nullptr, root);

DirectionalLightPtr light0 = scene->CreateDirectionalLight();
light0->SetDirection(0.0, 0.0, -1);
light0->SetDiffuseColor(1.0, 1.0, 1.0);
light0->SetSpecularColor(1.0, 1.0, 1.0);
root->AddChild(light0);

CameraPtr cameraA = scene->CreateCamera();
ASSERT_NE(nullptr, cameraA);
cameraA->SetWorldPosition(0, 0, -2);
cameraA->SetWorldRotation(0, GZ_PI / 2.0, 0);
cameraA->SetVisibilityMask(0x01);
cameraA->SetImageWidth(256);
cameraA->SetImageHeight(256);
root->AddChild(cameraA);

// create projectors with different visibility flags
std::string textureRed = common::joinPaths(
TEST_MEDIA_PATH, "materials", "textures",
"red_texture.png");
ProjectorPtr projectorA = scene->CreateProjector();
ASSERT_NE(nullptr, projectorA);
projectorA->SetNearClipPlane(1.0);
projectorA->SetFarClipPlane(6.0);
projectorA->SetTexture(textureRed);
projectorA->SetVisibilityFlags(0x01);
projectorA->SetWorldRotation(0, GZ_PI / 2.0, 0);
root->AddChild(projectorA);

// create ImageHeightmap
auto data = std::make_shared<common::ImageHeightmap>();
data->Load(common::joinPaths(TEST_MEDIA_PATH, "heightmap_bowl.png"));

HeightmapDescriptor desc;
desc.SetName("example_bowl");
desc.SetData(data);
desc.SetSize({ 17, 17, 7.0 });
desc.SetSampling(2u);
desc.SetUseTerrainPaging(false);

const auto textureImage =
common::joinPaths(TEST_MEDIA_PATH, "materials", "textures", "texture.png");
const auto normalImage = common::joinPaths(TEST_MEDIA_PATH, "materials",
"textures", "flat_normal.png");

HeightmapTexture textureA;
textureA.SetSize(1.0);
textureA.SetDiffuse(textureImage);
textureA.SetNormal(normalImage);
desc.AddTexture(textureA);

HeightmapBlend blendA;
blendA.SetMinHeight(2.0);
blendA.SetFadeDistance(5.0);
desc.AddBlend(blendA);

HeightmapTexture textureB;
textureB.SetSize(1.0);
textureB.SetDiffuse(textureImage);
textureB.SetNormal(normalImage);
desc.AddTexture(textureB);

HeightmapBlend blendB;
blendB.SetMinHeight(4.0);
blendB.SetFadeDistance(5.0);
desc.AddBlend(blendB);

HeightmapTexture textureC;
textureC.SetSize(1.0);
textureC.SetDiffuse(textureImage);
textureC.SetNormal(normalImage);
desc.AddTexture(textureC);
auto heightmapGeom = scene->CreateHeightmap(desc);
auto vis = scene->CreateVisual();
vis->AddGeometry(heightmapGeom);
root->AddChild(vis);

// render once to update scene graph and make sure
// there are no crashes
Image imageA = cameraA->CreateImage();
EXPECT_NO_THROW(cameraA->Capture(imageA));

// Clean up
engine->DestroyScene(scene);
}

0 comments on commit fbb6bbc

Please sign in to comment.