Ponto V!

Home Ogre 3D Ogre GUI
Jonathan Ohara de Araujo
Ogre GUIImprimir
Escrito por Jonathan Araujo

No artigo anterior, fizemos nosso primeiro aprimoramento no nosso protótipo de jogo que foi a inclusão da GUI e placar, nesse artigo vamos falar mais sobre a GUI que já vem com o Ogre chamado SdkTrays.

Trays e Widgets

Existem 10 widgets básicos no SdkTrays, widgets são os elementos de tela como Label (texto), barras de progresso e checkbox entre outros, todos eles são uma instância de um OverlayElement e todas widgets usam pixel como métrica.

Um “tray” é uma área onde se pode colocar widgets, por isso o nome da biblioteca. Para entender facilmente olhe a figura abaixo e repare nos retângulos cinza com os cantos arredondados.

figura_01

Ao todo existem 9 trays para posicionar seus widgets, são eles:

  • No topo à esquerda;
  • No topo ao centro;
  • No topo à direita;
  • No centro à esquerda;
  • No centro;
  • No centro à direita;
  • Em baixo à esquerda;
  • Em baixo ao centro;
  • Em baixo à direita;

Podem-se posicionar os objetos também manualmente, veremos um exemplo mais abaixo de como fazer isso.

Requisitos

São simples os requisitos para se usar o SdkTrays do Ogre, o primeiro é o uso de OIS, lembrando que o OIS já vem com o Ogre e o outro requesito é que se use o OIS no modo buffered que é o modo que utilizamos em todos os artigos anteriores, para não passar em branco, em poucas palavras o modo unbuferred você não tem os eventos disparados para os Listeners do OIS, cabendo a você testar manualmente se um botão foi apertado a cada frame. Veja um exemplo de uso do OIS no modo unbuffered:

if (mKeyboard->isKeyDown(OIS::KC_K)) {

Observe que no código acima é verificado manualmente se a tecla ‘K’ esta pressionada ou não.

Projeto

O projeto que está disponível para download no fim da página, mostra como se usar maioria dos widgets do SdkTrays, assim como suas principais funções.

Veja o resultado do nosso projeto:

figura_02

Para começar vamos ver a declaração dos objetos que iremos utilizar nesse projeto. Repare que o namespace que utilizamos para declarar não é o Ogre como mostrado anteriormente, utilizamos para todos os objetos do sdkTrays o namespace OgreBites. Os objetos são declarados como membros da classe Tutorial9, que é a principal classe do exemplo.

OgreBites::Button *button;

OgreBites::TextBox *textBox;

OgreBites::SelectMenu *selectMenu;

OgreBites::Label *label;

OgreBites::Separator *separator;

OgreBites::Slider *slider;

OgreBites::ParamsPanel *paramsPanel;

OgreBites::CheckBox *checkbox;

OgreBites::ProgressBar *progressBar;

Sendo que cada um deles é descrito abaixo:

  • Button: Um botão comum, na figura acima ele aparece na parte inferior direita;
  • TextBox: Uma caixa com texto, na figura acima ele aparece na parte superior esquerda;
  • SelectMenu: Um combo de opções, na figura acima ele aparece na parte superior no centro;
  • Label: Mensagem simples, na figura acima ele aparece no centro;
  • Slider: Um slider com range de valores, na figura acima ele aprece no centro a direita;
  • ParamsPanel: Um painel para colocar parâmetros no formato par/valor, na figura acima aparece no centro a esquerda;
  • Checkbox: Um checkbox simples, na figura acima aparece na parte inferior esquerda;
  • PorgressBar: Uma barra de progresso, na figura acima aparece na parte inferior no centro.

Agora vamos ver como utilizar cada widget em especifíco.

SdkTrayManager

Para criar a GUI primeiramente é preciso criar um gerenciador para a mesma, que é feito na linha abaixo:

mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", mWindow, mMouse, this);

Os parâmetros são:

  • Nome da interface
  • Janela onde ela será desenhada
  • Classe Mouse da OIS
  • this: esse é o ponteiro para a classe principal do tutorial, que herda de OgreBites::SdkTrayListener, uma interface que define um listener para receber eventos da SdkTrays.

Observe que um item importante aqui é classe que implementa a interface SdkTrayListener, essa classe é quem irá rebecer os eventos da GUI e tratar eles, como um clique de um botão.

Button

button = mTrayMgr->createButton( OgreBites::TL_BOTTOMRIGHT, "button", "", 200 );

Os parâmetros para criar o button são:

  • TrayLocation: Localização do Widget, repare que utilizamos a posição inferior direita;
  • Name: Nome do Widget, lembrando que NÃO podem existir widgets com mesmo nome;
  • Caption: O texto que irá aparecer no button;
  • Width: largura.

Caso queira implementar controle de clique no botão basta implementar o seguinte método:

void buttonHit(OgreBites::Button* bt)

Onde o argumento é o botão que disparou o evento. É importante observar que este método é uma sobrecarga do método existente na classe OgreBites::SdkTrayListener.

TextBox

textbox = mTrayMgr->createTextBox( OgreBites::TL_NONE, "textBox", "", 200, 100 );

Os parâmetros para criar o textbox são:

  • TrayLocation: Localização do Widget, repare que utilizamos nenhuma e depois colocaremos a posição manualmente;
  • Name: Nome do Widget, lembrando que NÃO podem existir widgets com mesmo nome;
  • Caption: O texto que irá aparecer no textBox;
  • Width: largura;
  • Height: altura.

No trecho a seguir vamos colocar um caption e posição para esse textBox.

textBox->setCaption( "Texto" );

textBox->getOverlayElement()->setTop(0);

textBox->getOverlayElement()->setLeft(0);

Repare que para “setar” os valores de posição precisamos primeiro pegar o OverLayElement do Widget.

SelectMenu

textbox = mTrayMgr->createThickSelectMenu( OgreBites::TL_TOP, "selectMenu", "", 200, 200 );

Os parâmetros para criar o textbox são:

  • TrayLocation: Localização do Widget;
  • Name: Nome do Widget;
  • Caption: O texto que irá aparecer no SelectMenu;
  • Width: largura;
  • Height: altura.

No trecho a seguir vamos colocar um caption e adicionar alguns itens no SelectMenu.

selectMenu->setCaption( "Selecione:" );

selectMenu->addItem( "Otion 1" );

selectMenu->addItem( "Otion 2" );

selectMenu->addItem( "Otion 3" );

Caso queira implementar um evento para controlar se houve alteração de um item no SelectMenu implementar o seguinte método:

void itemSelected(OgreBites::SelectMenu* menu)

Label

textbox = mTrayMgr->createLabel( OgreBites::TL_CENTER, "label", "", 500 );

Os parâmetros para criar o label são:

  • TrayLocation: Localização do Widget;
  • Name: Nome do Widget;
  • Caption: O texto que irá aparecer no Label;
  • Width: largura.

Separator

textbox = mTrayMgr->createLabel( OgreBites::TL_TOPRIGHT, "separator", 200 );

Os parâmetros para criar o separator são:

  • TrayLocation: Localização do Widget;
  • Name: Nome do Widget;
  • Width: largura;

O separator é um simples separador horizontal, um traço.

Slider

textbox = mTrayMgr->createThickSlider( OgreBites::TL_RIGHT, "slider", "", 200, 80, 1, 32, 32 );

Os parâmetros para criar o Slider são:

  • TrayLocation: Localização do Widget;
  • Name: Nome do Widget;
  • Caption: O texto que irá aparecer no Slider;
  • Width: largura;
  • ValueBoxWidth: Largura da caixa com o texto do valor do Slider;
  • minValue: O valor Mínimo do slider;
  • maxValues: o Valor máximo do slider;
  • Snaps: Quantidade de passos que terá o Slide. Por exemplo se o slider com range de 0 a 1 e com 6 snaps, os valores serão 0 0.2 0.4 0.6 0.8 1.

Caso queira implementar um evento para controlar se houve movimentação no slider basta implementar o seguinte método:

void sliderMoved(OgreBites::Slider* sl) {

ParamsPanel

paramsPanel = mTrayMgr->createParamsPanel(OgreBites::TL_LEFT, "paramsPanel", 200, paramsPanelItems );

Os parâmetros para criar o Slider são:

  • TrayLocation: Localização do Widget;
  • Name: Nome do Widget;
  • Width: largura;
  • ParamsPanelItems: Um Ogre::StringVector com todos parâmetros(valores do lado esquerdo) do Painel;

No trecho a seguir vamos colocar os valores para os parâmetros, repare que o primeiro argumento é um inteiro contendo o índice do valor e o segundo uma String com o valor:

paramsPanel->setParamValue( 0, "0" );

paramsPanel->setParamValue( 1, "1" );

paramsPanel->setParamValue( 2, "2" );

Checkbox

checkbox = mTrayMgr->createCheckBox(OgreBites::TL_BOTTOMLEFT, "checkbox", "", 200 );

Os parâmetros para criar o CheckBox são:

  • TrayLocation: Localização do Widget;
  • Name: Nome do Widget;
  • Caption: O texto que irá aparecer no Slider;
  • Width: largura;

Agora vamos mudar o caption do checkbox e deixar e setar o checkbox como marcado:

checkbox->setCaption( "CheckBox" );

checkbox->setChecked( true );

Caso queira implementar um evento para controlar se houve alteração entre checado e não checado basta implementar o seguinte método:

void checkBoxToggled( OgreBites::CheckBox* box );

ProgressBar

progressBar = mTrayMgr->createProgressBar( OgreBites::TL_BOTTOM, "progressBar", "", 200, 100);

Os parâmetros para criar a barra de progresso são:

  • TrayLocation: Localização do Widget;
  • Name: Nome do Widget;
  • Caption: O texto que irá aparecer no ProgressBar;
  • Width: largura;
  • CommentBoxWidth: largura da caixa com o valor da barra de progresso.

Agora vamos mudar o caption e setar o progresso da barra com 50%(lembrado que 0 é igual a 0% e 1 igual a 100%).

progressBar->setCaption( "Progess" );

progressBar->setProgress( 0.5f );

Repare que em alguns trechos é renderizado um frame manualmente usando a seguinte função do root:

mRoot->renderOneFrame();

Isso acontece por um pequeno problema interno do SDKtrays onde não é possível fazer certas mudanças na GUI sem ter renderizado ao menos um frame.

Conclusão

Nesse artigo vimos as principais funções da GUI básica do Ogre a SdkTrays. No próximo artigo voltaremos ao nosso protótipo de PAC-man introduzindo animação de esqueletos em nossos personagens, entre outras melhorias. Recomendo desde agora ler o artigo sobre Técnicas de animação para jogos 3D aqui mesmo no ponto V.


Comentários (6)
  • Anônimo
    avatar

    muito bom

  • Victor
    avatar

    Eu gostaria de mais tutoriais sobre Ogre3D, como de animações esqueletais,etc...

  • Bruno Crivelari Sanches
    avatar

    O próximo artigo já trata disso! :)

  • João Cássio  - Versão OGRE
    avatar

    Eu não estou conseguindo compilar, estou usando o OGRE vs 1.9, primeiro deu esses erros:

    Na linha:

    Código:
    mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", mWindow, mMouse, this);

    Erro:

    Código:
    Error 1 error C2664: 'OgreBites::SdkTrayManager::SdkTrayManager(const Ogre::String &,Ogre::RenderWindow *,OgreBites::InputContext,OgreBites::SdkTrayListener *)' : cannot convert parameter 3 from 'OIS::Mouse *' to 'OgreBites::InputContext'

    2 IntelliSense: no instance of constructor "OgreBites::SdkTrayManager::SdkTrayManager" matches the argument list
    argument types are: (const char [14], Ogre::RenderWindow *, OIS::Mouse *, Tutorial9 *)

    Consegui resolver fazendo isso:

    Código:
    OgreBites::InputContext inputContext;
    inputContext.mMouse = mMouse;
    inputContext.mKeyboard = mKeyboard;

    mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", mWindow, inputContext, this);

    Mas agora da esses erros:

    Código:
    1>Tutorial9.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall Ogre::BorderPanelOverlayElement::setBorderMaterialName(class std::basic_string const &)" (__imp_?setBorderMaterialName@BorderPanelOverlayElement@Ogre&# 64;@QAEXABV?$basic_string@DU?$char_traits@D@std@&# 64;V?$allocator@D@2@@std@@@Z) referenced in function "public: virtual void __thiscall OgreBites::CheckBox::_cursorMoved(class Ogre::Vector2 const &)" (?_cursorMoved@CheckBox@OgreBites@@UAEXABVVector2@ Ogre@@@Z)
    1>Tutorial9.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: float __thiscall Ogre::TextAreaOverlayElement::getCharHeight(void)const " (__imp_?getCharHeight@TextAreaOverlayElement@Ogre@@QBE MXZ) referenced in function "public: __thiscall OgreBites::Button::Button(class std::basic_string const &,class Ogre::UTFString const &,float)" (??0Button@OgreBites@@QAE@ABV?$basic_string@DU?$ch ar_traits@D@std@@V?$allocator@D@2@@std @@ABVUTFString@Ogre@@M@Z)
    1>Tutorial9.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: float __thiscall Ogre::TextAreaOverlayElement::getSpaceWidth(void)const " (__imp_?getSpaceWidth@TextAreaOverlayElement@Ogre@@QBE MXZ) referenced in function "public: static void __cdecl OgreBites::Widget::fitCaptionToArea(class Ogre::UTFString const &,class Ogre::TextAreaOverlayElement *,float)" (?fitCaptionToArea@Widget@OgreBites@@SAXABVUTFString&# 64;Ogre@@PAVTextAreaOverlayElement@4@M@Z)
    1>Tutorial9.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class std::basic_string const & __thiscall Ogre::TextAreaOverlayElement::getFontName(void)const " (__imp_?getFontName@TextAreaOverlayElement@Ogre@@QBEAB V?$basic_string@DU?$char_traits@D@std@@V?$allocato r@D@2@@std@@XZ) referenced in function "public: static void __cdecl OgreBites::Widget::fitCaptionToArea(class Ogre::UTFString const &,class Ogre::TextAreaOverlayElement *,float)" (?fitCaptionToArea@Widget@OgreBites@@SAXABVUTFString&# 64;Ogre@@PAVTextAreaOverlayElement@4@M@Z)
    1>Tutorial9.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall Ogre::TextAreaOverlayElement::setAlignment(enum Ogre::TextAreaOverlayElement::Alignment)" (__imp_?setAlignment@TextAreaOverlayElement@Ogre@@QAEX W4Alignment@12@@Z) referenced in function "public: __thiscall OgreBites::SelectMenu::SelectMenu(class std::basic_string const &,class Ogre::UTFString const &,float,float,unsigned int)" (??0SelectMenu@OgreBites@@QAE@ABV?$basic_string@DU ?$char_traits@D@std@@V?$allocator@D@2@@ ;std@@ABVUTFString@Ogre@@MMI@Z)
    1>bin\Debug\\pontov_tutorial_09.exe : fatal error LNK1120: 36 unresolved externals

    Creio que seja por causa da versão do OGRE, vocês sabem como faço pra resolver esses erros, eu sei que tem alguma biblioteca que deve ser incluída em algum lugar, mas a estrutura desse OGRE é muito grande.

    Estou usando OGRE 1.9 e VSC++ Express 2012.

  • João Cássio  - Consegui
    avatar

    Consegui resolver:

    Properties/Link/Imput/Additional Dependencies/
    Adicionar essa pra debug:
    OgreOverlay_d.lib

    Release:
    OgreOverlay.lib

    Mas ainda não executou está dando esse erro http://i.imgur.com/9cAzFY7.png

    Estou em busca de resolução.

Escrever um comentário
Your Contact Details:
Gravatar enabled
Comentário:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch::(:shock:
:X:side::):P:unsure::woohoo::huh::whistle:;):S:!::?::idea::arrow:
Security
Por favor coloque o código anti-spam que você lê na imagem.
LAST_UPDATED2  

Busca

Linguagens

Twitter