1

我用这个函数来获取材料

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;

其次,我添加了一个鼠标移动过程

首先是 const 向量颜色

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

创建对象

 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;

然后程序

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;

这是 ismouseoverImage 函数...

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;

现在,当鼠标悬停在图像上时,材料会改变发射颜色,但我没有得到结果......(我什么也没看到)。

我做错了什么...?

谢谢...

4

4 回答 4

1

我整理了一个示例,展示了我试图解释的内容。它包含的唯一过程是在鼠标悬停时将不同的材质分配给 HUDSprite,并在鼠标移出时取消选择它。

    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;

这就是你所需要的,我附上了包含所有文件的样本。请从这里下载项目文件:TestHUDSprite

于 2013-10-26T22:25:57.340 回答
0

您可能需要调用 GlSceneViewer.Invalidate 来更新显示。另外,尽量不要使用纹理调制模式并检查它是否有效,因为在使用调制时,某些颜色组合可以产生相同的结果,具体取决于您使用的背景和发射颜色。希望这可以帮助。

于 2013-10-24T21:52:44.893 回答
0

从我看到的情况来看,您正在第一个代码片段中将材料添加到材料库中。但是,您的鼠标悬停图像功能使用 HUD 的内部材料,而不是您在库中定义的材料。如果每个 HUDSprite 都有自己不同的纹理并且您将所有纹理都存储在 MatLib 中,那么您应该从 MaterialLibrary 修改材质的属性,而不是内部材质的属性(每个 GLSceneObject 都带有一个“内部”材质,但您可以分配它通过设置 MaterialLibrary 和 LibMatName 属性来获取库材料。

//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)

然后以任何你想要的方式改变材料。

于 2013-10-25T09:42:13.590 回答
0

好的,这是我推荐的解决方案,但这取决于每个精灵的材料有多么不同:创建精灵时,不要为每个精灵分配 matlib 材料,只需从 matlib 材料中复制所需的属性进入每个精灵的内部材质(如您在上面所做的那样)。因此,每个精灵不应该附加任何 matlib,而仅依赖于其内部材料(您只需使用 matlib 材料作为预设),然后当您更改精灵时,您只需修改其内部发射颜色。这种方法的缺点是,如果你有大量的精灵,而不是为所有精灵共享一个纹理,你会为每个精灵复制那个特定的纹理,这不是内存效率的。

我还建议的另一个解决方案如下:为 qyour matlib 中的每种材料定义两个版本。一个未选择的和一个已选择的(您实际上将有两种单独的材料),当您需要突出显示一个精灵时,只需将其分配给 matlib 中的“选定材料”,并将“未选择的材料”分配给其他精灵。

在这两种情况下,您可能都需要调用 Hudsprite.structurechanged,尽管我很确定这不是必需的。考虑一下,我认为第二种解决方案是我要实施的解决方案,因为它的内存效率很高,并且您可以对选定/未选定状态有两种完全不同的外观。

我希望我想在这里提出的建议足够清楚。

于 2013-10-25T23:39:26.710 回答