Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

hogosha

OpenGL GUI in OpenGL

This topic is 5562 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am trying to write make a graphical interface in my OpenGL, so whats the best way to do it. im going to use it for a game, doesnt necessarily have to use textures, but it may help. Using SDL as well in my code. Higher Forces

Share this post


Link to post
Share on other sites
Advertisement
This isn''t the best way, but its the way I do it...

1. Make a list of widgets your going to use, and the functions you''ll need to use them
2. Make a base GUI class, call it CGUI
3. GUI contains all the functions common to all you widgets(gain focus, lose focus, keypress, etc), and virtual functions to the ones that arn''t.
4. Create a class for all your widgets, inherite CGUI to each one, that way you already have obtained all your functinos.


5. Now, make a array of CGUI*, and initalize all your gui

array[0] = new CGUIBUTTON(location);
array[1] = new CGUITEXTBOX(location);

Then, whatever you have a need for a new press, do this

OnKeyPress()
{
for i = 0 to array_size
array->key_press();
}

etc, etc, so on and so forth.

Share this post


Link to post
Share on other sites
depending on how flexible you want to be you can use function or method pointers. so you write your onclick function for a certain button and just "link" it via the function pointer.

my current version:
http://festini.device-zero.de/downloads/ui.zip

only the source and it requires glut for now.. if you just want to have a look you can download the binary (i left out most textures in the src version)
http://festini.device-zero.de/downloads/srcc.zip

you still have to write your own class derived from dialogue and a a way to parse external files to build them at runtime wouldnt be a bad modification, but i wouldnt know how to add event functions without writing an interpreter for them.

Share this post


Link to post
Share on other sites
@ dede:

A better way to do this is to:
1) Register all windows to somekind of 'GUIBase' object
2) Link GUI elements (like buttons) to a window, so they get rendered relatively to the window coordinates
3) When registering a window, also register a function that is called each render loop, that does actions on the controls:



GUIBase guibase;
GUIWindow window(&guibase, callbackFunction, x, y);
GUIButton button1(&window, x, y, width, height);
GUIText textfield1(&window, &string, x, y, width, height);


callbackFunction()
{
// render button and return 'true' if button was clicked

if (button1.DoActions())
DoStuff();
// render and set &string if text was changed

textfield1.DoActions();
}


[edit] This, together with GUI elements like checkboxes, textfields, labels and other took about 3 days to code. The window manager took 1/3 of that time. I didn't mention it because it's kinda complex, but If you need more info:
The window manager sits between the window and the gui base. It makes sure that all windows are rendered in a good order and checks if the user clicks a window and if that window needs to be brought to the front of the screen. I first worked with a linked list, but working with priority ID's (1 per window) is a better thing to do imho.

[edited by - Vich on July 3, 2003 4:57:22 PM]

Share this post


Link to post
Share on other sites
if you need some impressions
here is the start of my Gui

i have created a basic CGui object which i am going to use as base object for all controls and so on

and a CGuiManager
the manager stores all the menus

and the controls are added to a child list of each individual menu

you can even add a button to a button LOL


here s some sample code( not much done though)


#include "standardheader.h"

CGui::CGui(int x, int y, int width, int height)
{
m_pChildren=NULL;
m_pNext=NULL;
m_pParent=NULL;
}

CGui::CGui(int x, int y, int width, int height, CGui *pParent)
{
CGui(x,y,width,height);
SetParent(pParent);
}

//Set
void CGui::SetParent(CGui *pParent)
{
if(!pParent)
return;

m_pParent=pParent;
pParent->AddChild(this);
}

void CGui::SetVisible(BOOL bVisible)
{
m_bVisible=bVisible;
}

void CGui::SetBorder(int size)
{
m_iBorderSize=size;
}

void CGui::SetFgColorfv(float *color)
{
if(!color)
return;
m_flFgColor[0]=color[0];
m_flFgColor[1]=color[1];
m_flFgColor[2]=color[2];
m_flFgColor[3]=color[3];
}

void CGui::SetFgColorf(float r,float g, float b, float a)
{
m_flFgColor[0]=r;
m_flFgColor[1]=g;
m_flFgColor[2]=b;
m_flFgColor[3]=a;
}

void CGui::SetFgColoriv(int *color)
{
if(!color)
return;
m_flFgColor[0]=color[0]/255;
m_flFgColor[1]=color[1]/255;
m_flFgColor[2]=color[2]/255;
m_flFgColor[3]=color[3]/255;
}

void CGui::SetFgColori(int r, int g, int b, int a)
{
m_flFgColor[0]=r/255;
m_flFgColor[1]=g/255;
m_flFgColor[2]=b/255;
m_flFgColor[3]=a/255;
}

void CGui::SetBgColorfv(float *color)
{
if(!color)
return;
m_flBgColor[0]=color[0];
m_flBgColor[1]=color[1];
m_flBgColor[2]=color[2];
m_flBgColor[3]=color[3];
}

void CGui::SetBgColorf(float r,float g, float b, float a)
{
m_flBgColor[0]=r;
m_flBgColor[1]=g;
m_flBgColor[2]=b;
m_flBgColor[3]=a;
}

void CGui::SetBgColoriv(int *color)
{
if(!color)
return;
m_flBgColor[0]=color[0]/255;
m_flBgColor[1]=color[1]/255;
m_flBgColor[2]=color[2]/255;
m_flBgColor[3]=color[3]/255;
}

void CGui::SetBgColori(int r, int g, int b, int a)
{
m_flBgColor[0]=r/255;
m_flBgColor[1]=g/255;
m_flBgColor[2]=b/255;
m_flBgColor[3]=a/255;
}

void CGui::SetPos(int x, int y)
{
m_iX=x;
m_iY=y;
}

void CGui::SetSize(int width, int height)
{
m_iWidth=width;
m_iHeight=height;
}

//Add
void CGui::AddChild(CGui *pChild)
{
if(!pChild)
return;
CGui *p=NULL;;
if(m_pChildren==NULL)
{
m_pChildren=pChild;
}
else
{
p=m_pChildren;
while(p)
{
if(p->m_pNext==NULL)
{
p->m_pNext=pChild;
return;
}
p=p->m_pNext;
}
}
}

//Get/Is
BOOL CGui::IsVisible()
{
return m_bVisible;
}

//on

void CGui::onPaint()
{
}

void CGui::onPaintBackground()
{
}






















Share this post


Link to post
Share on other sites
hm.. if youre using a simple linked list (why not stl list or a minimal own list storing at least a first and last pointer?)... does the order matter? because if not it would seem a lot easier to do:

pChild->m_pNext=m_pChildren;
m_pChildren=pChild;

instead of:

if(m_pChildren==NULL) m_pChildren=pChild;
else {
p=m_pChildren;
while(p){
if(p->m_pNext==NULL) {
p->m_pNext=pChild;
return;
}
p=p->m_pNext;
}
}

or in other words: add them to the front, not the back.

Share this post


Link to post
Share on other sites
performance is not an issue in my implementation since these functions are only called at start up time
when i initialize all the menues

that s only because i usually only work with lists where order matters

of course you could change itbut you probably get crazy when you have positioned an object incorrect

i am planning to implement a function that automatically aligns the controls so they don t intersect and that s easiest to do when you have got a sorted list

Share this post


Link to post
Share on other sites
Hi!

Since you''re using OGL, why wouldn''t use use one of the existing libraries? I''d suggest ParaGUI as the best one(search on google), I''d use it myself if it didn''t use OGL and SDL The other option would be glgui(I think it''s glgui.sourceforge.net), so give it a try.



--------
Leave all your expectations behind, or
they''ll pull you down on your way to the top.

-Ivan

Share this post


Link to post
Share on other sites
I define GUIs using XML and then push and pop them to and from the screen when required. For example I define an About GUI:


<gui name="About">

<component name="AboutCanvas" type="hbGuiCanvas">

<size>1.0, 1.0</size>
<position>0.0, 0.0</position>
<hpos>left</hpos>
<vpos>top</vpos>
<hsize>relative</hsize>
<vsize>relative</vsize>

<component name="AboutFrame" type="hbGuiBitmapFrame">
<position>0.2, 0.2</position>
<hpos>centre</hpos>
<vpos>centre</vpos>
<size>0.7, 360</size>
<hsize>relative</hsize>
<vsize>absolute</vsize>
<colour>128, 128, 128, 255</colour>
<bitmap>./data/gui/frame.png</bitmap>
<border>20, 20, 20, 20</border>

<component name="AboutButton" type="hbGuiBitmapButton">
<normal>./data/gui/TestExitNormal.tga</normal>
<focus>./data/gui/TestExitFocused.tga</focus>
<active>./data/gui/TestExitActive.tga</active>
<position>0.5, 0.05</position>
<hpos>centre</hpos>
<vpos>bottom</vpos>
<hsize>absolute</hsize>
<vsize>absolute</vsize>
<size>50.0, 33.0</size>
<audioOver>ButtonOver</audioOver>
<audioClick>Buttwhenclickedon</audioClick>
<command>ExitAbout</command>
</component>

<component name="TextArea1" type="hbGuiTextArea">
<font>DebugText</font>
<position>0.0, 0.0</position>
<hpos>centre</hpos>
<vpos>top</vpos>
<hsize>relative</hsize>
<vsize>relative</vsize>
<size>1.0, 0.8</size>
<text>./data/gui/about.txt</text>
<colour>225, 225, 225, 255</colour>
</component>

</component>

</component>

</gui>


I then push it to the screen with a Lua script call like this:


Gui:Push("About")


Gui components are coded in C++ and call Lua script functions when events occur, such as a button being pressed.

Edit: Fixed the source tags (I was using code instead of source - must remember that!).

[edited by - stodge on July 4, 2003 12:25:26 PM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!