Jump to content

GUI system design tips...


EvilNoodle
 Share

Recommended Posts

Hello all,

 

A while ago when I was working with the DarkGDK from "The Game Creators" I started building a fairly flexible event based GUI system which I am planning to port to Leadwerks.

 

The GDK version used sprites to render simple controls on top of the 3D content which gave them the ability to be made transparent and rotated etc. I have started porting to Leadwerks using the 2D draw commands as a starting point but I can see some problems with continuing this approach... For example The 2D commands work and work well but at the moment I am not seeing any obvious way to make content drawn with them transparent.

 

Do any of you guys know how I can draw 2D content (or 3D that looks like 2D) to the screen for a GUI where I can set transparency on the components? Ideally I would like to be able to treat GUI components like any other entity - materials etc.

 

What I want to do as a starting point is render an image loaded from file to the screen on top of all other content using the following arguments...

 

xPos = 0.25 (25% of the displayable screen from the left)

yPos = 0.25 (25% of the displayable screen from the top)

width = 0.5 (50% of the displayable screen)

height = 0.5 (50% of the displayable screen)

alpha = 0.5 (50% transparent)

 

Resulting in an image drawn with 50% transparency exactly half the size of the display and perfectly centred.

 

Thanks

 

EvilNoodle

Link to comment
Share on other sites

xPos = ScreenWidth() / 4;

 

So to transfer your value (0.25) to what could be used, use:

 

int XPercentToPixel(float percent)
{
   return percent * ScreenWidth();
}

int YPercentToPixe(float percent)
{
   return percent * ScreenHeight();
}

 

If you have an alpha channel in a DDS file you render to the screen, transparency will be enabled. You cannot have alpha programmed, as far as I know.

 

I suggest using the OOP drawing approach in my C# wrapper, if that's not too much of a hassle for you. Porting is easy too. More information here.

Link to comment
Share on other sites

Thanks for the response. The sorting out of screen coords for the 2D drawing is already done in my ported implementation and works as I want it. Its mainly the transparency that I am having issues with.

 

I made a .png in the Gimp and applied an alpha layer to it so I now have a 50% see through png file. I then saved this as .dds using the Gimp plugin but the dds doesnt seem to have preserved the alpha hence it is not showing up as transparrent in engine.

 

This may be a limitation of the Gimp DDS export plugin or the way I am using it so I will look at it again tonight with a different conversion workflow.

 

If I can get this working there is very little I need to do to complete my lightweight GUI framework.

 

Thanks again.

 

EvilNoodle

Link to comment
Share on other sites

Hello again...

 

I have now managed to get a dds to export properly with a transparent background (at least the parts that should be transparent appear in bright cyan when the dds is viewed) but I am a little unclear as to where in the render process I should be doing the drawing to get the transparency to work.

 

I am using Framewerk and my test code is pretty much taken from the example as below

 

#include "engine.h"
#include "framewerk.h"

#define WIN_RES_X 1024
#define WIN_RES_Y 768

int main(int argc, char** argv)
{
if(!Initialize())return 1;

TMesh		mesh, ground;
TLight		light;
TMaterial	material;

RegisterAbstractPath(".");

Graphics(WIN_RES_X,WIN_RES_Y);

leadwerks::Framewerk fw;

if( !fw.Create() )
{
	MessageBoxA(0,"Failed to initialize engine.",NULL,0);
	return 1;
}

fw.GetRenderer().SetSkybox( LoadMaterial("abstract::FullskiesBlueClear0016_2_L.mat") );
fw.GetRenderer().SetSSAO( true );
PositionEntity( fw.GetMain().GetCamera(), Vec3(0,0,-3) );

material = LoadMaterial("abstract::cobblestones.mat");

mesh = CreateCube();
ScaleEntity(mesh, Vec3(0.5, 0.5, 0.5));
PaintEntity( mesh, material );

ground = CreateCube();
ScaleEntity   ( ground, Vec3( 10,  1, 10 ) );
PositionEntity( ground, Vec3(  0, -1,  0 ) );
PaintEntity   ( ground, material );

light = CreateDirectionalLight();

RotateEntity( light, Vec3(45) );

TTexture testImage = LoadTexture("abstract::test.dds");

do
{
	TurnEntity( mesh, Vec3(AppSpeed()*0.5f) );

	if( KeyHit(KEY_ESCAPE) ) break;
	if( AppTerminate()     ) break;

	fw.Update();
	fw.Render();

	Flip(0);
}
while( true );

return Terminate();
}

 

The question is where should I be placing the "DrawImage(testImage, 200, 200, 320, 200);" to get the desired effect? The sensible place from my perspective would be between the "fw.Render();" and "Flip(0)" lines but while that draws the image it is far from transparent. The parts that should be transparent just render in white.

 

Any ideas?

 

Lazlo I will send you a pm about your drawing approach I would like to know more.

Link to comment
Share on other sites

Thanks!!! That works like a charm!!!

 

Now I have my black blob :blink:

 

Do you know if it is possible to set the alpha in a DDS so that the blob is itself partially transparent?

 

I tried to do it in the Gimp but I get told it doesnt support it.

 

EvilNoodle

 

...
fw.Render();

SetBlend(BLEND_ALPHA);
DrawImage(testImage, 200, 200, 320, 200);
SetBlend(BLEND_NONE);

Flip(0);
...

Link to comment
Share on other sites

I think the time is past where making the GUI fit in the same space is a good idea. People have different monitor ratios and multiple monitors. Valve's windowed GUI is the best approach, I think.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

I agree with you that there are far better sollutions in the GUI space but for the time being all I need is a very simple implementation.

 

For my needs I have pretty much everything I require for now because all I want is some simple event driven buttons and text elements.

 

In the future I would like additional viewports although I will cross that bridge when I come to it.

 

EvilNoodle

Link to comment
Share on other sites

My point was that if you try to make your GUI appear the same on every resolution it will be more complicated and buggy than if you used a fixed sized for your controls.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Just some notes:

 

SetBlend(BLEND_ALPHA) enables the alpha blending for your pre-existing alpha channels.

 

If you want to affect the ENTIRE alpha (opacity/transparency) of your whole control (even non-blended parts in the texture), you can make a call to SetColor: SetColor(Vec4(1,1,1,0.5)) will draw your image at 50% transparency. You can also modify the color via that, obviously.

 

Hope that is what you were looking for,

Tyler

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

It would require the use of OpenGL calls, specifically glReadPixels.

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

  • 9 months later...

Best way for simple GUI in my opinion ,for example :

 

Let's say we have to create abstract screen with a fixed size. Let's say it's 100 x 75 for a 4:3 ratio.

 

We will then simply convert the position and scale of the element for real current screen size. The only problem remains the ratio of the screen. And it's not a big problem because we can create two versions for 4:3 and 16:9 or 16:10 aspect ratio. :)

 

I will try to make something useful :P

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...