Могу ли я изменить цвет Emition на объект GLHudSprite в GLScene?
Я использую эту функцию, чтобы получить материал
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
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 ответа
Я собрал образец, демонстрирующий то, что я пытался объяснить. Единственная процедура, которая в нем содержится, назначает другой материал 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
Возможно, вам придется вызвать GlSceneViewer.Invalidate для обновления отображения. Кроме того, попробуйте не использовать режим текстурной модуляции и проверьте, работает ли он тогда, поскольку при использовании модуляции некоторые цветовые комбинации могут давать один и тот же результат, в зависимости от используемого фона и цветов излучения. Надеюсь это поможет.
Из того, что я вижу, вы добавляете материал в библиотеку материалов в своем первом фрагменте кода. Однако функция наведения мыши на изображение использует внутренний материал вашего 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)
а затем просто измените материал, как вы хотите.
Хорошо, так что это решение, которое я рекомендую, но оно зависит от того, насколько разные ваши материалы для каждого спрайта: когда вы создаете спрайты, не назначайте материал matlib каждому, просто скопируйте нужные свойства из материала matlib во внутренний материал каждого спрайта (как вы сделали выше). Таким образом, к каждому спрайту не нужно прикреплять какую-либо матрицу, а полагаться исключительно на его внутренний материал (вы просто используете материалы матрицы в качестве предварительных настроек), а затем, когда вы изменяете спрайты, вы просто изменяете, например, их внутренний цвет излучения. Недостатком этого подхода является то, что если у вас есть большое количество спрайтов, вместо совместного использования одной текстуры для всех, вы копируете эту конкретную текстуру для каждого спрайта, что неэффективно для памяти.
Другое решение, которое я также предлагаю, заключается в следующем: определите две версии для каждого материала в qyour matlib. Невыбранный и выбранный (у вас фактически будет два отдельных материала), и когда вам нужно выделить один спрайт, просто назначьте ему "выбранный материал" из matlib и назначьте "невыбранный материал" другим спрайтам.
В обоих случаях вам может понадобиться позвонить в Hudsprite.structurechanged, хотя я уверен, что в этом нет необходимости. Если подумать, если это так, я думаю, что второе решение - это то, которое я бы реализовал, потому что оно эффективно использует память, и вы можете иметь два совершенно разных вида для выбранных / невыбранных состояний.
Я надеюсь, что достаточно ясно, что я пытаюсь предложить здесь.