Skip to content
Li, Xizhi edited this page Jul 16, 2020 · 10 revisions

Drawing With 2D API

There are two low-level ways to draw 2d graphical objects.

  • One is via creating ParaUIObject controls (like buttons, containers, editbox). These controls are managed in C++ and created in NPL scripts.
  • The other is creating owner draw ParaUIObject, and do all the drawings with Painting API in NPL scripts, such as draw rect, lines, text, etc.

Moreover, there is a number of high-level graphical libraries written in NPL which allows you to create 2D user interface more easily.

  • IDE controls is NPL wrapper of the low-level C++ API. It provides more versatile controls than the raw ParaUIObjects.
    • One old implementation is based on ParaUIObject controls.
    • One new implementation is based on Painting API, in System.Window.UIElement namespace.
  • MCML/NPL is a HTML/JS like mark up language to create user interface.
    • One old implementation is based on ParaUIObject controls.
    • One new implementation is based on Painting API, in System.Window.mcml namespace.

This article is only about low-level drawing API in C++ side, which are exposed to NPL. However, one should always use MCML or Windows.UIElement instead of following raw API.

button

Creating a button with a texture background and text. The root element is a container see next section. Please place a png texture Texture/alphadot.png at the working directory.

NPL.load("(gl)script/ide/System/System.lua");

local clickCount = 1;
local function CreateUI()
   local _this = ParaUI.CreateUIObject("button", "MyBtn", "_lt", 10, 10, 64, 22);
   _this.text= "text";
   _this.background = "Texture/alphadot.png";
   _this:SetScript("onclick", function(obj) 
      obj.text = "clicked "..clickCount;
      clickCount = clickCount + 1;
   end)
   _this:AttachToRoot();
end
CreateUI();

container

Create a container and a child button inside it.

	local _parent, _this;
	_this = ParaUI.CreateUIObject("container", "MyContainer", "_lt", 10, 110, 200, 64);
	_this:AttachToRoot();
	_this.background = "Texture/alphadot.png";
	_parent = _this;

	-- create a child
	_this = ParaUI.CreateUIObject("button", "b", "_rt", -10-32, 10, 32, 22);
	_this.text= "X"
	_this.background = "";
	_parent:AddChild(_this);

text and editbox

System Fonts

In ParaEngine/NPL, we support loading fonts from *.ttf files. One can install custom font files at fonts/*.ttf, and use them with filename, such as Verdana;bold. Please note, all controls in ParaEngine uses "System" font by default. "System" font maps to the system font used by the current computer by default. However, one can change it to a different custom font installed in fonts/*.ttf. Suppose you have a font file at fonts/ParaEngineThaiFont.ttf, you can map default System font to it by calling.

Config.AppendTextValue("GUI_font_mapping","System");	
Config.AppendTextValue("GUI_font_mapping","ParaEngineThaiFont");

It is a pair of function calls, the first is name, the second is value. We recommend doing it in script/config.lua, it is loaded before any UI control is created. Please see that file for details.

Please note, for each font with different size, weight, and name, we will create a different internal temporary image file for rendering. So it is recommended to use just a few fonts in your application.

Also please note that we need font name to match ttf font's filename. You can download a small tool called fontrenamer.exe (google it) to rename a font to match its filename.

GUI Images

ParaUIObject.background property supports a feature called image tiling. It can use a specified section of an image and divide the subsection into 9 images and automatically stretch the 5 middle images as the target resizes (4 images at the corner are unstretched). This is very useful to create good looking buttons with various sizes.

image

The syntax is like this: Filename.png;left top width height:px py pr pb

  • such as: obj.background="someimage_32bits.png;0 0 64 21: 10 10 10 10"
  • ;left top width height is optional, which specifies a sub region. if ignored it means the entire image.
  • :px py pr pb means distance to left, top, right and bottom of the above sub region.
  • _32bits.png means that we should use 32bits color, otherwise we will compress the color to save video memory
  • Image size must of order of 2, like 2,4,8,16,64, 128, 256, etc. Because directX/openGL only supports order of 2 images. If your image file is not order of 2, they will be stretched and become blurred when rendered.

Here is an example of UI image used in real 3D application (Paracraft):

gamecommonicon_32bits

We usually buddle all images into one or more image files and specify offset and 9 tiles when using them. Because there is extra cost when switching textures in modern graphics cards, we tend to use only a few image files (textures).

Clone this wiki locally