Question

I'm wanting to put a visual highlight (selection box really) onto one of many TGLPlane's which have many different textures assigned to them. How would I apply a second decal texture to that plane using GLScene?

Some background. The various different textures applied to the planes are all stored in a MaterialLibrary and assigned to the respective planes Material.MaterialLibrary and Material.LibMaterialName. This is the proper efficient reuse of textures as they are loaded only once regardless of how many times they are used.

What you can't seemingly do is use any of the properties on the TGLPlane because they are ignored once you apply a MaterialLibrary texture to it.

The methods I can find for doing so seem to require me to alter the LibMaterial which of course then applies to all other planes which share that particular texture, so that's a no-go.

Another method I spotted at Google Code (Checkers) solves the issue by creating a second plane which has it's own 'highlight' partially transparent texture applied, which is then placed slightly above the original object (a cube as it happens to be). This seems like a hack to get around it and I'm hoping to avoid that if possible.

If its not a built in capability for GLScene then is there a method to intercept the rendering when it gets to that particular plane and then use some OpenGL primitives to apply the decal texture after the MaterialLibrary texture is applied?

Was it helpful?

Solution

Here is one method, without applying a second texture but nevertheless making a visible marker.

When loading the textures, create a second TGLLibMaterial without a texture but with whatever 'highlight' modifications you want to make on your 'selected' texture, and call it the same except with '-selected' appended to the name.

fMatLib.AddTextureMaterial('empty','empty.bmp', False);

with TGLLibMaterial.Create(fMatLib.Materials) do begin
  Material.MaterialLibrary := fMatLib;
  Texture2Name := 'empty';
  Name := 'empty-selected';
  Material.FrontProperties.Emission.Color := clrRed;
  Material.Texture.ImageBrightness := 1.5;
end;

This doesn't consume texture memory because you're not reloading the texture.

Then in your code identify the object you wish to highlight, and do something like this.

fPickedMaterial := fPickedObject.Material.LibMaterialName;
fPickedObject.Material.LibMaterialName :=
  fPickedObject.Material.LibMaterialName + '-selected';

fPickedMaterial saves the original material name so that I can restore it later.

Not perfectly what I want, but it works. Call it a work-around for now.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top