我使用此功能获取材料
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;
第二个我添加了一个onmouse移动程序
首先是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;
现在,当鼠标悬停在图像上时,材质会改变颜色,但我不会得到结果......(我什么也看不见)。
我做错了什么......?
谢谢...
答案 0 :(得分: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
答案 1 :(得分:0)
您可能需要调用GlSceneViewer.Invalidate来更新显示。此外,尝试不使用纹理调制模式并检查它是否有效,因为使用调制时,某些颜色组合可以产生相同的结果,具体取决于您使用的背景和发光颜色。 希望这会有所帮助。
答案 2 :(得分: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)
然后以任何你想要的方式改变材料。
答案 3 :(得分:0)
好的,所以这是我推荐的解决方案,但这取决于每种精灵的材质有多么不同: 在创建精灵时,不要为每个精灵分配matlib材质,只需将matlib材质所需的属性复制到每个精灵的内部材质中(如上所述)。所以每个精灵都不应该附加任何matlib,而只依赖于它的内部材质(你只需使用matlib材料作为预设),然后当你改变精灵时,你只需修改它们的内部发射颜色即可。这种方法的缺点是,如果你有大量的精灵,而不是共享一个纹理,你可以为每个精灵复制特定的纹理,这不是内存效率。
我还建议的另一个解决方案如下:为qyour matlib中的每个材质定义两个版本。一个未选择的和一个选定的(你实际上将有两个单独的材料),当你需要突出显示一个精灵时,只需为它选择&#34;选择的材料&#34;从matlib中分配&#34;未选择的材料&#34;对其他精灵。
在这两种情况下,您可能需要调用Hudsprite.structurechanged,尽管我非常确定它不是必需的。快来想想,如果它,我认为第二个解决方案是我要实现的解决方案,因为它的内存效率很高,你可以对选择/未选择的状态有两个完全不同的外观。
我希望我能够在这里明确提出建议。