Jump to content

Outlined text


Recommended Posts

Hi there, what is the best way to make outlined text which won't have much impact on the performance. I want to create player tag system instead of standard one and ran into low FPS problem when many players were on the screen. I found this function but it has 4 additional dx calls which is not good:

function dxDrawFramedText ( message , left , top , width , height , color , scale , font , alignX , alignY , clip , wordBreak , postGUI )
    dxDrawText ( message , left + 1 , top + 1 , width + 1 , height + 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
    dxDrawText ( message , left + 1 , top - 1 , width + 1 , height - 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
    dxDrawText ( message , left - 1 , top + 1 , width - 1 , height + 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
    dxDrawText ( message , left - 1 , top - 1 , width - 1 , height - 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
    dxDrawText ( message , left , top , width , height , color , scale , font , alignX , alignY , clip , wordBreak , postGUI )
end

 

Link to comment

You can pre-render everything with a render target and then draw it with a single dxDrawImage

An example:

local text = dxCreateRenderTarget(width, height, true)

dxSetRenderTarget(text, true)
dxDrawText ( message , left + 1 , top + 1 , width + 1 , height + 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
dxDrawText ( message , left + 1 , top - 1 , width + 1 , height - 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
dxDrawText ( message , left - 1 , top + 1 , width - 1 , height + 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
dxDrawText ( message , left - 1 , top - 1 , width - 1 , height - 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
dxDrawText ( message , left , top, width, height, color , scale , font , alignX , alignY , clip , wordBreak , postGUI )
dxSetRenderTarget()

addEventHandler('onClientRender', root, function()
  dxDrawImage(left, top, width, height, text)
end)

It should be pretty easy to understand. If you need help putting it in an easy to use function let me know.

Edited by Tails
Link to comment
1 hour ago, Tails said:

You can pre-render everything with a render target and then draw it with a single dxDrawImage

An example:


local text = dxCreateRenderTarget(width, height, true)

dxSetRenderTarget(text, true)
dxDrawText ( message , left + 1 , top + 1 , width + 1 , height + 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
dxDrawText ( message , left + 1 , top - 1 , width + 1 , height - 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
dxDrawText ( message , left - 1 , top + 1 , width - 1 , height + 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
dxDrawText ( message , left - 1 , top - 1 , width - 1 , height - 1 , tocolor ( 0 , 0 , 0 , 255 ) , scale , font , alignX , alignY , clip , wordBreak , postGUI )
dxDrawText ( message , left , top, width, height, color , scale , font , alignX , alignY , clip , wordBreak , postGUI )
dxSetRenderTarget()

addEventHandler('onClientRender', root, function()
  dxDrawImage(left, top, width, height, text)
end)

It should be pretty easy to understand. If you need help putting it in an easy to use function let me know.

Thanks for reply 9_9 I understand how render targets work but unfortunately I'm not sure that they are OK for my purpose. You see it's quite hard to make DX text look like normal default DX-font via rendertarget. I don't know why this happens but my text becomes blurry... And what about many rendertargets on the screen instead of my framed text function above. Is it better for performance?

22 minutes ago, IIYAMA said:

Why not use an outline font?

Well, maybe it's a real solution. But the thing is that I need default-bold DX-font which comes with MTA. Is there any way to make it bold or outlined by MTA itself or I need to edit the font with some other program?

Link to comment
  • Moderators

fontforge can edit/export fonts like you want.

I do not recommend you to do that, unless you know this tool and can work with it. It is very complex and I am only using it to convert old print/printer fonts to convert them to use-able formats for other media.

 


What I do recommend you, is to search for a font-family which looks like the default-bold font.

This page says that the default-bold font from gui's is this font: Tahoma bold, 8px

As well as this page for dx fonts: "default-bold": Tahoma Bold

 


Finding a similar looking fonts:

https://www.myfonts.com/WhatTheFont/

 


Fonts (a lot of them are free with licence):

https://www.dafont.com/

 

Good luck

  • Thanks 1
Link to comment

You can use render targets perfectly fine. They aren't rendered to the screen they are rendered to a new texture at run time. The image is the only thing that's being drawn to the screen. So, you could have a 100 draw functions and render it to a single texture and only draw that texture to the screen with dxDrawImage.

The reason your text became blurry with render targets is because you were either stretching the image or the positions/dimensions were off.

Take this simple object oriented approach and you'll have an easy to use function. It works similar to the CEGUI functions except that you're responsible for drawing it, although you could make the function handle that as well.

function dxCreateFramedText(text, left, top, width, height, color, scale, font, alignX, alignY, clip, wordBreak, postGUI)
	local self = {}
	local rt = dxCreateRenderTarget(width, height, true)

	self.draw = function(x, y, w, h)
		dxDrawImage(left, top, width, height, rt)
	end

	self.update = function()
		dxSetRenderTarget(rt, true)
		dxDrawText(text, 1, 1, width + 1, height + 1, tocolor(0, 0, 0), scale, font, alignX, alignY, clip, wordBreak, postGUI)
		dxDrawText(text, 1, -1, width + 1, height - 1, tocolor(0, 0, 0), scale, font, alignX, alignY, clip, wordBreak, postGUI)
		dxDrawText(text, -1, 1, width - 1, height + 1, tocolor(0, 0, 0), scale, font, alignX, alignY, clip, wordBreak, postGUI)
		dxDrawText(text, 1, 1, width - 1, height - 1, tocolor(0, 0, 0), scale, font, alignX, alignY, clip, wordBreak, postGUI)
		dxDrawText(text, 0, 0, width, height, color, scale, font, alignX, alignY, clip, wordBreak, postGUI)
		dxSetRenderTarget()
	end

	self.setText = function(v)
		text = v
		self.update()
	end

	self.setColor = function(v)
		color = v
		self.update()
	end

	self.update()

	return self
end

local msg1 = dxCreateFramedText("Hello there",222,300,520,140,tocolor(0,255,0),3,'default','left','top',false,false,false)
local msg2 = dxCreateFramedText("How are you?",222,400,520,140,tocolor(0,255,0),3,'default','left','top',false,false,false)

addEventHandler('onClientRender', root, function()
   msg1.draw()
   msg2.draw()
end)

msg2.setColor(tocolor(0,255,255))

addCommandHandler('c', function() msg1.setColor(tocolor(255,99,0)) end)

It may look a little over the top but yeah, it works, and it's fast.

  • Like 1
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...