1

i use this function to get the material

function AddMaterial(aMatLib: TGlMaterialLibrary; aFileName, aMaterialName: string):TGlLibMaterial;
begin
  result := aMatLib.Materials.Add;
  with result do
  begin
    with Material do
     begin
       MaterialOptions := [moIgnoreFog, moNoLighting];
       Texture.Disabled := false;
       BlendingMode := bmTransparency;
       Texture.TextureMode := tmModulate;
       with FrontProperties do
        begin
          Ambient.SetColor(1, 1, 1, 1);
          Diffuse.SetColor(1, 1, 1, 1);
          Emission.SetColor(1, 1, 1, 1);
          Specular.SetColor(1, 1, 1, 1);
        end;
      Texture.ImageClassName := 'TGLCompositeImage';
      if ExtractFileExt(aFileName) = '' then
        TGLCompositeImage(Texture.Image).LoadFromFile(aFileName + '.png')
      else
        TGLCompositeImage(Texture.Image).LoadFromFile(aFileName);
      //TGLCompositeImage(Texture.Image).LoadFromFile(aFileName);
   end;
    Name := aMaterialName;
  end;
end;

second i add an onmouse move procedure

first the const vector colors

const
  OnMoveInObjects_Color: TColorVector = (0.243, 0.243, 0.243, 1.000);
  OnOutObjects_Color: TColorVector = (0.000, 0.000, 0.000, 1.000);

create the object

 fsExit:= TGLHUDSprite.CreateAsChild(MainForm.Dummy_mainmenu);
 fsExit.Material.MaterialLibrary:= MatLib;
 fsExit.Material.LibMaterialName:= 'bexit';
 fsExit.SetSquareSize(50);
 fsExit.Position.X:= CenterX;
 fsExit.Position.Y:= 30;
 fsExit.Visible:= true;

and then the procedure

procedure Check_Mouse_UpPlayer(x,y:Integer);
 var
  sTVol: FLOAT;
begin
 if MainForm.IsMouseOverImage(fsExit,x,y) then
   begin
     fsExit.Material.FrontProperties.Emission.Color:= OnMoveInObjects_Color;
     if IsKeyDown(VK_LBUTTON) then
       begin
        fade_blur:= true;
        ShowExit;
      end;
    end
  else
   fsExit.Material.FrontProperties.Emission.Color:= OnOutObjects_Color;
end;

and here is the ismouseoverImage function...

function TMainForm.IsMouseOverImage(const AButton: TGLHudSprite; const X, Y: Integer):Boolean;
begin
  Result := (X >= AButton.Position.X - AButton.Width / 2) and (X <= AButton.Position.X + AButton.Width / 2) and
        (Y >= AButton.Position.Y - AButton.Height / 2) and (Y <= AButton.Position.Y + AButton.Height / 2);
end;

Now when the mouse is over the image the material change the emition color but i dont get results... (i don't see anything).

What i am doing wrong...?

Thank you...

azrael11
  • 417
  • 6
  • 18

4 Answers4

1

I put together a sample showcasing what I tried to explain. The only procedure it contains assigns a different material to a HUDSprite on mouse over and deselects it on mouse out.

    procedure TForm1.GLSceneViewer1MouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
   if (X >= GLHUDSprite1.Position.X - GLHUDSprite1.Width * 0.5) and (X <= GLHUDSprite1.Position.X + GLHUDSprite1.Width * 0.5) and (Y >= GLHUDSprite1.Position.Y - GLHUDSprite1.Height * 0.5) and (Y <= GLHUDSprite1.Position.Y + GLHUDSprite1.Height * 0.5) then
   begin
      GLHUDSprite1.Material.LibMaterialName := 'Selected';
   end
   else
      GLHUDSprite1.Material.LibMaterialName := 'Unselected';
  GLSceneViewer1.Invalidate;
end;

This is all you need, I'm attaching the sample including all the files. Please download the project files from here: TestHUDSprite

  • Maybe i don't put my question right... or you don't understand what i ask... I don't want to put to materials i want to change the emition color of current material... so in your example i want to change the 'selected' material.emition.color to 'unselected' meterial.emition.color without use a second material... change it when mouse is over... see example down ".." – azrael11 Oct 27 '13 at 07:23
  • @azrael11, please be more specific as to what are you trying to achieve. As i've told you, once you assigned a matlib & Libmatname to a HUDSprite you can think of it as a kind of Material Pointer to that specific material from the lib. It is not copying information for the MatLib material, it actually "points" to it and uses it instead of its own internal material. So if you change that material's emission color, all objects using that particular material will change color too. – BARSAN-PIPU Claudiu Oct 28 '13 at 02:40
  • Your code, at least from what you've shared above, can't possibly work since after you assign a matlib & matlibname to an object, whatever changes you apply on its internal one are simply ignored. So please be more specific as what you are trying to obtain. I'm trying to help here but I simply don't seem to grasp your actual problem. The solution I've proposed (using two materials in the matlib and switching between them onmouseover) is the most elegant, memory efficient and also offers the most freedom design-wise. Please tell me exactly what are you trying to achieve. – BARSAN-PIPU Claudiu Oct 28 '13 at 02:44
  • The main goal is to change the color of one texture material on the fly but as i can see from your anwsers you say that can not be do... – azrael11 Oct 28 '13 at 06:57
  • You don't solve my problem but you point me to right view of my problem... Thank you very much I hope to help you or help me in another question... Thank you again – azrael11 Nov 02 '13 at 16:44
0

You might need to call a GlSceneViewer.Invalidate to update the display. Also, try not using texture modulation mode and check if it works then, since when using modulation, some color combinations can produce the same result, depending on the background and emission colors you use. Hope this helps.

  • Than you for your anwser... 1) I call GLSceneViewer.Invalidate ... 2) i try it without texture modulation just material mode:= tmadd or anything else not working ... and 3) the color combination is in my question that update thank you... – azrael11 Oct 25 '13 at 05:30
0

from what I see you are adding a material to the material library in your first code snippet. However, your mouse over image function uses the internal material of your HUD, and not the one you defined in the library. If each HUDSprite has its own different texture and you store all in the MatLib, then you should modify the properties of the material from the MaterialLibrary and not those of the internal material (each GLSceneObject comes with an "Internal" material but you can assign it a library material by setting MaterialLibrary and LibMatName properties.

//This assumes that for each HUDsprite in your scene you have assigned a MateriaLibrary and LibMaterialName     
//you can get the library material assigned to a sprite like this:
    GLMaterialLibrary1.Materials.GetLibMaterialByName(CurrentHUDSprite.Material.LibMaterialName)

and then just alter the material any way you want.

  • As you can see i add the creation of the object fsexit... i already do that... sorry i did't post it from the start i miss it... but thank you for your anwser... ... or i missing something from your anwser... thanks – azrael11 Oct 25 '13 at 12:18
  • What I'm trying to say that there are two distinct materials for your fsExit sprite: its default "internal" material and the one you assign via material lib. When you assign fsExit a material from the Material Library it overrides fsExit's own "internal" material. So when you change its "internal" material nothing happens. You should be changing the properties of the 'bexit' material from the material library or don't assign a library material to your HUDSprite, and then edit the internal one for changes. – BARSAN-PIPU Claudiu Oct 25 '13 at 16:54
  • Now i understand your point ... So how can i change the properties of the "bexit" material from the material library and not change the material library properties global...? Thank you again you help me very much... – azrael11 Oct 25 '13 at 21:23
  • I assing this with this code line fsExit.Material.GetLibMaterial.Assign(MatLib.Materials.GetLibMaterialByName(fsExit.matlib.libmaterialname)); but it shows me nothing... so... any help please... – azrael11 Oct 25 '13 at 22:00
  • Hi @azrael11, I put together a sample showcasing what I tried to explain. The only procedure it contains assigns a different material to a HUDSprite on mouse over and deselects it on mouse out. – BARSAN-PIPU Claudiu Oct 26 '13 at 22:14
0

ok, so this is the solution i recommend, but it depends on how different your materials are for each sprite: when you create the sprites, don't assign a matlib material to each one, just copy the properties you need from the matlib material into each sprite's internal material (as you did above). So each sprite should not have any matlib attached, but rely solely on its internal material (you just use the matlib materials as presets) and then when you alter sprites you simply modify thier inner emission color for example. the downside to this approach is that if you have a large number of sprites, instead of sharing one texture for all, you copy that particular texture for each sprite, which is not memory efficient.

Another solution I also suggest is the following: define two versions for each material in qyour matlib. A unselected one and a selected one (you will actually have two separate materials) and when you need to highlight one sprite just assign it the "selected material" from the matlib and assign the "unselected material" to the other sprites.

In both cases you might need to call Hudsprite.structurechanged although i'm pretty sure it's not required. Come to think if it, I think the second solution is the one I would implement cause it's memory efficient and you can have two completely different looks for selected/unselected states.

I hope it's clear enough what I'm trying to suggest here.

  • the second solution i think is easier for my code... but how can i add to materials for one sprite and how can i select the desire material... Thank you very much... – azrael11 Oct 26 '13 at 06:24
  • Simply change the LibMaterialName property of your sprite so that it points either to the Selected or to the Unselected material. You don't need to have two materials for a sprite, you will only have the two materials in the material library. Each sprite or whatever object you need will simply have to be linked to this MaterialLibrary and have LibMaterialName property set to either the selected or unselected materials from the matlib. You should also check the Samples that come with Glscene, you might find other useful examples there. – Claudiu Barsan Oct 26 '13 at 11:54
  • Bcs i am stuck ... can you tell me how to select a mateliar that i can change the emition... in code please... thank you so much... – azrael11 Oct 26 '13 at 13:46