2013-10-24 30 views
1

我使用此函数来获得材料我可以将Emition Color更改为GLScene中的GLHudSprite对象吗?

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; 

第二i添加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; 

现在,当鼠标移动到图像的材料改变emition颜色,但我不明白的结果...(我不看到任何东西)。

我做错了什么...?

谢谢...

回答

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

+0

也许我不把我的问题正确。 ..或者你不明白我在问什么......我不想把材料放到我想改变当前素材的表现颜色......所以在你的例子中我想改变'selected'材质。 emition.color to'unselected'meterial.emition.color不使用第二个材质...当鼠标结束时更改它...查看下面的例子“..” – azrael11

+0

@ azrael11,请更具体地说明你在尝试什么实现。正如我已经告诉过你的,一旦你将matlib&Libmatname分配给HUDSprite,你可以把它看作是一种材料指针,从这个lib中指向特定的材质。它不会复制MatLib材质的信息,它实际上是“指向”它并使用它来代替它自己的内部材质。因此,如果您更改该材质的发光颜色,则使用该特定材质的所有对象也会改变颜色。 –

+0

您的代码至少从上面共享的内容中可能无法工作,因为在将matlib和matlibname分配给对象之后,无论您在其内部应用的更改都被忽略。所以请更具体地说明你正在努力获得什么。我试图帮助这里,但我似乎并没有把握你的实际问题。我提出的解决方案(在matlib中使用两种材料并在它们之间切换)是最优雅,高效的内存,并且提供了最大的设计自由度。请告诉我你到底想要达到什么目标。 –

0

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

+0

比你的anwser ... 1)我打电话GLSceneViewer.Invalidate ... 2)我尝试没有纹理调制只是材料模式:= tmadd或其他任何不工作...和3)颜色组合是在我的问题,更新谢谢你... – azrael11

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) 

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

+0

正如你所看到的我添加对象fsexit的创建...我已经这样做...对不起,我没有发布它从一开始我就想念它......但是谢谢你的接吻师......或者我从你的接吻师那丢失了一些东西......谢谢 – azrael11

+0

我想说的是,你的fsExit sprite有两种截然不同的材料:它的默认“内部”材料和你通过材料库分配的材料。当您从材质库中分配fsExit材质时,它会覆盖fsExit自己的“内部”材质。所以当你改变它的“内部”材料时,什么都不会发生。您应该更改材料库中“bexit”材质的属性,或者不要将材质库分配给HUDSprite,然后编辑内部材质以进行更改。 –

+0

现在我理解了你的观点......那么,如何从材料库中更改“bexit”材质的属性,而不是更改全局材质库属性......?再次感谢你,你非常帮我... – azrael11

0

好了,这是解决方案,我建议,但它取决于你的材料有何不同适用于每个精灵: 当您创建精灵时,不要为每个精灵分配matlib材质,只需从matlib mater中复制需要的属性分成每个精灵的内部材料(如上所述)。因此,每个精灵都不应该附加任何matlib,而仅仅依靠其内部材质(您只需使用matlib材质作为预设),然后在改变精灵时,只需修改其内部发射颜色即可。这种方法的缺点是,如果你有大量的精灵,而不是共享一个纹理,你复制每个精灵的特定纹理,这是不符合内存效率。

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

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

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

+0

第二种解决方案我认为对于我的代码更简单...但我怎样才能为一个精灵添加资料,以及如何选择愿望材料...非常感谢您... – azrael11

+0

只需更改您的LibMaterialName属性sprite,以便它指向Selected或Unselected材质。您不需要为精灵创建两个材质,只有材质库中有两个材质。每个精灵或任何您需要的对象都必须链接到此材质库,并将LibMaterialName属性设置为matlib中的选定材质或未选材质。您还应该检查Glscene附带的示例,您可能会在其中找到其他有用的示例。 –

+0

Bcs我卡住了...你能告诉我如何选择一个mateliar,我可以改变...在代码请...非常感谢你... – azrael11

相关问题