First download and install the AntTweakBar library.
The download page also explains how to compile, link and run your program with AntTweakBar.
AntTweakBar has a C interface, and can be directly integrated in any C++ or C program that uses OpenGL or DirectX 9 to 11.
We will now see how to integrate AntTweakBar into your source code.
Note that you can found some full examples and their commented sources in the examples
directory of the AntTweakBar library.
First, include the AntTweakBar header with your other includes.
#include <AntTweakBar.h>
After OpenGL or DirectX initializations and after the creation of your graphic window, initialize AntTweakBar by calling TwInit
.
If you are using OpenGL, the command is:
TwInit(TW_OPENGL, NULL); // or TwInit(TW_OPENGL_CORE, NULL); // for core profile
If you are using DirectX, the command is:
TwInit(TW_DIRECT3D9, myD3DDevice); // for Direct3D 9 // or TwInit(TW_DIRECT3D10, myD3DDevice); // for Direct3D 10 // or TwInit(TW_DIRECT3D11, myD3DDevice); // for Direct3D 11
where myD3DDevice
is the device pointer returned by the appropriate CreateDevice
function of Direct3D.
Then you tell the size of the graphic window to AntTweakBar by calling TwWindowSize
TwWindowSize(myWindowWidth, myWindowHeight);
Declare one or more pointers of type TwBar*
, and create one or more tweak bars by calling TwNewBar
TwBar *myBar; myBar = TwNewBar("NameOfMyTweakBar");
Then, you can add variables to your tweak bar(s) by calling TwAddVarRW
, TwAddVarRO
, TwAddVarCB
, or TwAddButton
TwAddVarRW(myBar, "NameOfMyVariable", TW_TYPE_xxxx, &myVar, "");
You will find examples of use of these functions in the program examples provided with the library.
Call TwDraw
at the end of your main loop to draw your tweak bar(s). It must be called just before the frame buffer is presented (swapped).
// main loop while( ... ) { // clear the frame buffer // update view and camera // update your scene // draw your scene TwDraw(); // draw the tweak bar(s) // present/swap the frame buffer } // end of main loop
At this point, a tweak bar has been created and is displayed into the graphic window of your application, but it does not react to user inputs and window size changes.
For that, you should send the keyboard, mouse and window size events to AntTweakBar by calling TwKeyPressed
, TwMouseButton
, TwMouseMotion
, TwMouseWheel
and TwWindowSize
.
Depending on your windowing system, you will probably have to translate the incoming events before sending them to AntTweakBar.
To help in debugging your key event translation routine, the translated key received by the AntTweakBar library is displayed at the bottom of the Help bar for a short while.
If you are using SDL, GLUT, GLFW or Windows (DirectX, DXUT), the following functions do the translation for you.
Use TwEventSDL
when processing incoming events
SDL_Event event; int handled; // ... // inside the main loop while( SDL_PollEvent(&event) ) // process events { // send event to AntTweakBar handled = TwEventSDL(&event SDL_MAJOR_VERSION, SDL_MINOR_VERSION); if( !handled ) // if event has not been handled by AntTweakBar, process it { // ... } }
See TwSimpleSDL for a full example based on SDL.
If you want to see how TwEventSDL
is implemented, have a look to the file src/TwEventSDL.c
.
Call TwEventKeyboardGLUT
, TwEventSpecialGLUT
, TwEventMouseButtonGLUT
and TwEventMouseMotionGLUT
inside the GLUT event callbacks that you have registered. These functions return a non-zero value if the event has been handled by AntTweakBar, or zero otherwise.
It is also required that you send the glutGetModifers
function pointer to AntTweakBar because the GLUT key event functions do not report key modifiers states.
TwEventKeyboardGLUT
, TwEventSpecialGLUT
, TwEventMouseButtonGLUT
and TwEventMouseMotionGLUT
can be directly used as GLUT event callbacks.
// after GLUT initialization // directly redirect GLUT events to AntTweakBar glutMouseFunc((GLUTmousebuttonfun)TwEventMouseButtonGLUT); glutMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT); glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT); // same as MouseMotion glutKeyboardFunc((GLUTkeyboardfun)TwEventKeyboardGLUT); glutSpecialFunc((GLUTspecialfun)TwEventSpecialGLUT); // send the ''glutGetModifers'' function pointer to AntTweakBar TwGLUTModifiersFunc(glutGetModifiers); // send window size events to AntTweakBar glutReshapeFunc(MyReshape); // and call TwWindowSize in the function MyReshape
See TwSimpleGLUT for a full example based on GLUT.
If you do not want to redirect events directly to AntTweakBar (because your app also need to handle them), define your own GLUT callbacks and call TwEventMouseButtonGLUT
, TwEventMouseMotionGLUT
,... at the beginning. For instance, for the mouse-motion event, your code should look like this:
void GLUTCALLBACK OnMouseMotion(int mouseX, int mouseY) // your callback function called by GLUT when mouse has moved { if( !TwEventMouseMotionGLUT(mouseX, mouseY) ) // send event to AntTweakBar { // event has not been handled by AntTweakBar // your code here to handle the event // ... } } // ... // somewhere in main() glutMotionFunc(OnMouseMotion);
If you want to see how the TwEvent*GLUT
functions are implemented, have a look to the file src/TwEventGLUT.c
.
Call TwEventKeyGLFW
, TwEventCharGLFW
, TwEventMouseButtonGLFW
, TwEventMousePosGLFW
and TwEventMouseWheelGLFW
inside the GLFW event callbacks that you have registered. These functions return a non-zero value if the event has been handled by AntTweakBar, or zero otherwise.
They can also be directly used as GLFW event callbacks.
// after GLFW initialization // directly redirect GLFW events to AntTweakBar glfwSetMouseButtonCallback((GLFWmousebuttonfun)TwEventMouseButtonGLFW); glfwSetMousePosCallback((GLFWmouseposfun)TwEventMousePosGLFW); glfwSetMouseWheelCallback((GLFWmousewheelfun)TwEventMouseWheelGLFW); glfwSetKeyCallback((GLFWkeyfun)TwEventKeyGLFW); glfwSetCharCallback((GLFWcharfun)TwEventCharGLFW); // send window size events to AntTweakBar glfwSetWindowSizeCallback(MyResize); // and call TwWindowSize in the function MyResize
See TwSimpleGLFW for a full example based on GLFW.
If you do not want to redirect events directly to AntTweakBar (because your app also need to handle them), define your own GLFW callbacks and call TwEventMouseButtonGLFW
, TwEventMousePosGLFW
,... at the beginning. For instance, for the mouse-motion event, your code should look like this:
void GLFWCALL OnMousePos(int mouseX, int mouseY) // your callback function called by GLFW when mouse has moved { if( !TwEventMousePosGLFW(mouseX, mouseY) ) // send event to AntTweakBar { // event has not been handled by AntTweakBar // your code here to handle the event // ... } } // ... // somewhere in main() glfwSetMousePosCallback(OnMousePos);
The TwAdvanced1 example follows this approach.
If you want to see how the TwEvent*GLFW
functions are implemented, have a look to the file src/TwEventGLFW.c
.
Use TwEventSFML
when processing incoming events
// inside the main loop sf::Event event; while (app.GetEvent(event)) { // send event to AntTweakBar int handled = TwEventSFML(&event, 1, 6); // assume SFML version 1.6 here if( !handled ) // if event has not been handled by AntTweakBar, process it { // ... } }
See TwSimpleSFML for a full example based on SFML.
If you want to see how TwEventSFML
is implemented, have a look to the file src/TwEventSFML.cpp
.
Use TwEventWin
when processing incoming events
// In the Windows MessageProc callback LRESULT CALLBACK MessageProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) { if( TwEventWin(wnd, msg, wParam, lParam) ) // send event message to AntTweakBar return 0; // event has been handled by AntTweakBar // else process the event message // ... }
In your main loop, make sure that you call the TranslateMessage
windows function prior to DispatchMessage
.
See TwSimpleDX9 for a full example based on DirectX9 and Windows.
See TwSimpleDX10 for a full example based on DirectX10 and Windows.
See TwSimpleDX11 for a full example based on DirectX11 and Windows.
If you want to see how TwEventWin
is implemented, have a look to the file src/TwEventWin.c
.
Note: if you need to release the graphics resources allocated by AntTweakBar, call TwWindowSize(0,0)
; This might be useful before resizing your app with DX10 for instance.
AntTweakBar can also be integrated in a DXUT-based application. DXUT is a framework included in the DirectX SDK. The integration scheme is as follow:
#include <DXUT.h> #include <AntTweakBar.h> //... LRESULT CALLBACK MessageProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam, bool*, void*) { if( TwEventWin(wnd, msg, wParam, lParam) // send event to AntTweakBar return 0; // event has been handled by AntTweakBar // process remaining events... } HRESULT CALLBACK OnCreateDevice(IDxxDevicex *d3dDevice,...) { TwInit(TW_DIRECT3Dxx, d3dDevice); // replace xx by 9 or 10 // create tweak bars and add variables here. // continue with the D3D code... } HRESULT CALLBACK OnDeviceReset(...) { TwWindowSize(backbuffer->Width, backbuffer->Height); // tell AntTweakBar the new backbuffer size // continue with the D3D code... } void CALLBACK OnDeviceLost(void*) { TwWindowSize(0, 0); // release resources allocated by AntTweakBar // release other D3D resources... } void CALLBACK OnFrameRender(...) { // first, clear the render target and draw your scene TwDraw(); // then draw the tweak bar(s) } void CALLBACK OnDestroyDevice(void*) { TwTerminate(); // uninitialize AntTweakBar // other D3D uninitializations... } //... int WINAPI wWinMain(...) { DXUTSetCallbackMsgProc(MessageProc); DXUTSetCallbackD3DxxDeviceCreated(OnCreateDevice); // replace xx by 9 or 10 DXUTSetCallbackD3D9DeviceReset(OnDeviceReset) or DXUTSetCallbackD3D10SwapChainResized(OnDeviceReset); DXUTSetCallbackD3D9DeviceLost(OnDeviceLost) or DXUTSetCallbackD3D10SwapChainReleasing(OnDeviceLost); DXUTSetCallbackD3DxxFrameRender(OnFrameRender); DXUTSetCallbackD3DxxDeviceDestroyed(OnDestroyDevice); // continue with the DXUT code: DXUTInit, DXUTCreateWindow, DXUTCreateDevice and so on. }
Use TwEventX11
when processing native X11 events.
If you want to see how TwEventX11
is implemented, have a look to the file src/TwEventX11.c
.
Just before closing your graphic window and uninitializing the graphic API, call TwTerminate
to uninitialize AntTweakBar
// at the end of your program TwTerminate(); // close your graphic window // exit your application
We now got one or more fully functional tweak bars.
The examples cited above will also give you a general survey of possibilities offered by the TwAddVar*
functions. Refer to their documentation pages for more details. Be sure to read the Variable parameters and the Bar parameters syntax pages, they describe many useful parameters that changes the behavior of your variables and tweak bars.
For advanced use of AntTweakBar, have a look to the TwAdvanced1 or TwDualGLUT examples.
It’s up to you now. Enjoy!