Additional GUI updates to GL example code

- switch Compute selection to pull-down menu
- add TBB controller to ptexViewer
- small cleanup in Hud

note: shading should also switch to a pull-down
This commit is contained in:
Manuel Kraemer 2014-04-27 23:05:18 -07:00
parent aa584ed2ce
commit 00f2419388
10 changed files with 124 additions and 94 deletions

View File

@ -128,7 +128,7 @@ Hud::KeyDown(int key)
if (it->selected>=(int)it->labels.size()) {
it->selected=0;
}
it->callback(it->selected);
it->callback(it->values[it->selected]);
_requiresRebuildStatic = true;
return true;
}
@ -191,7 +191,7 @@ Hud::MouseClick(int x, int y)
int sel = it->selected;
it->SetSelected((y - it->y) / FONT_CHAR_HEIGHT);
if (it->selected!=sel) {
it->callback(it->selected);
it->callback(it->values[it->selected]);
}
}
}
@ -336,12 +336,13 @@ Hud::AddPullDown(const char *label, int x, int y, int width,
}
void
Hud::AddPullDownButton(int handle, const char *label)
Hud::AddPullDownButton(int handle, const char *label, int value)
{
if (handle < (int)_pulldowns.size()) {
PullDown & pulldown = _pulldowns[handle];
pulldown.labels.push_back(label);
pulldown.values.push_back(value);
}
}
@ -349,7 +350,7 @@ Hud::AddPullDownButton(int handle, const char *label)
int
Hud::drawChar(std::vector<float> &vboSource,
int x, int y, float r, float g, float b, char ch) const
int x, int y, float r, float g, float b, char ch)
{
const float w = 1.0f/FONT_TEXTURE_COLUMNS;
const float h = 1.0f/FONT_TEXTURE_ROWS;
@ -410,7 +411,7 @@ Hud::drawChar(std::vector<float> &vboSource,
int
Hud::drawString(std::vector<float> &vboSource,
int x, int y, float r, float g, float b, const char *c) const
int x, int y, float r, float g, float b, const char *c)
{
while (*c) {
char ch = (*c) & 0x7f;

View File

@ -73,7 +73,7 @@ public:
int AddPullDown(const char *label, int x, int y, int width,
PullDownCallback callback=0, int shortcut=0);
void AddPullDownButton(int handle, const char *label);
void AddPullDownButton(int handle, const char *label, int value);
bool KeyDown(int key);
@ -133,6 +133,7 @@ protected:
bool open;
int selected;
std::vector<char const *> labels;
std::vector<int> values;
int shortcut;
PullDownCallback callback;
@ -143,11 +144,11 @@ protected:
}
};
int drawString(std::vector<float> &vboSource, int x, int y,
float r, float g, float b, const char *c) const;
static int drawString(std::vector<float> &vboSource, int x, int y,
float r, float g, float b, const char *c);
int drawChar(std::vector<float> &vboSource, int x, int y,
float r, float g, float b, char ch) const;
static int drawChar(std::vector<float> &vboSource, int x, int y,
float r, float g, float b, char ch);
bool hitTest(Item const &item, int x, int y) const {
int ix = item.x > 0 ? item.x : _windowWidth + item.x;

View File

@ -1153,7 +1153,7 @@ initHUD()
int pulldown_handle = g_hud.AddPullDown("Shape :", -300, 10, 300, callbackModel, 'n');
for (int i = 0; i < (int)g_defaultShapes.size(); ++i) {
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str());
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str(),i);
}
}

View File

@ -833,45 +833,46 @@ initHUD()
#endif
g_hud.Init(windowWidth, windowHeight);
g_hud.AddRadioButton(0, "CPU (K)", g_kernel == kCPU, 10, 10, callbackKernel, kCPU, 'k');
g_hud.AddRadioButton(1, "Wire (W)", g_displayStyle == kWire,
10, 10, callbackDisplayStyle, kWire, 'w');
g_hud.AddRadioButton(1, "Shaded", g_displayStyle == kShaded,
10, 30, callbackDisplayStyle, kShaded, 'w');
g_hud.AddRadioButton(1, "Wire+Shaded", g_displayStyle == kWireShaded,
10, 50, callbackDisplayStyle, kWireShaded, 'w');
g_hud.AddRadioButton(1, "Varying color", g_displayStyle == kVaryingColor,
10, 70, callbackDisplayStyle, kVaryingColor, 'w');
g_hud.AddRadioButton(1, "Face varying color", g_displayStyle == kFaceVaryingColor,
10, 90, callbackDisplayStyle, kFaceVaryingColor, 'w');
g_hud.AddCheckBox("Batching (B)", g_batching != 0, 200, 10, callbackCheckBox, HUD_CB_BATCHING, 'b');
g_hud.AddCheckBox("Patch Color (P)", true, 200, 50, callbackCheckBox, HUD_CB_DISPLAY_PATCH_COLOR, 'p');
g_hud.AddCheckBox("Screen space LOD (V)", g_screenSpaceTess != 0, 200, 70, callbackCheckBox, HUD_CB_VIEW_LOD, 'v');
g_hud.AddCheckBox("Freeze (spc)", false, 200, 90, callbackCheckBox, HUD_CB_FREEZE, ' ');
int compute_pulldown = g_hud.AddPullDown("Compute (k) :", 450, 10, 300, callbackKernel, 'k');
g_hud.AddPullDownButton(compute_pulldown, "CPU", kCPU);
#ifdef OPENSUBDIV_HAS_OPENMP
g_hud.AddRadioButton(0, "OPENMP", g_kernel == kOPENMP, 10, 30, callbackKernel, kOPENMP, 'k');
g_hud.AddPullDownButton(compute_pulldown, "OpenMP", kOPENMP);
#endif
#ifdef OPENSUBDIV_HAS_GCD
g_hud.AddRadioButton(0, "GCD", g_kernel == kGCD, 10, 30, callbackKernel, kGCD, 'k');
g_hud.AddPullDownButton(compute_pulldown, "GCD", kGCD);
#endif
#ifdef OPENSUBDIV_HAS_CUDA
g_hud.AddRadioButton(0, "CUDA", g_kernel == kCUDA, 10, 50, callbackKernel, kCUDA, 'k');
g_hud.AddPullDownButton(compute_pulldown, "CUDA", kCUDA);
#endif
#ifdef OPENSUBDIV_HAS_OPENCL
g_hud.AddRadioButton(0, "OPENCL", g_kernel == kCL, 10, 70, callbackKernel, kCL, 'k');
g_hud.AddPullDownButton(compute_pulldown, "OpenCL", kCL);
#endif
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
g_hud.AddRadioButton(0, "GLSL TransformFeedback", g_kernel == kGLSL, 10, 90, callbackKernel, kGLSL, 'k');
g_hud.AddPullDownButton(compute_pulldown, "GLSL TransformFeedback", kGLSL);
#endif
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
// Must also check at run time for OpenGL 4.3
// if (GLEW_VERSION_4_3) {
g_hud.AddRadioButton(0, "GLSL Compute", g_kernel == kGLSLCompute, 10, 110, callbackKernel, kGLSLCompute, 'k');
// }
if (GLEW_VERSION_4_3) {
g_hud.AddPullDownButton(compute_pulldown, "GLSL Compute", kGLSLCompute);
}
#endif
g_hud.AddRadioButton(1, "Wire (W)", g_displayStyle == kWire,
200, 10, callbackDisplayStyle, kWire, 'w');
g_hud.AddRadioButton(1, "Shaded", g_displayStyle == kShaded,
200, 30, callbackDisplayStyle, kShaded, 'w');
g_hud.AddRadioButton(1, "Wire+Shaded", g_displayStyle == kWireShaded,
200, 50, callbackDisplayStyle, kWireShaded, 'w');
g_hud.AddRadioButton(1, "Varying color", g_displayStyle == kVaryingColor,
200, 70, callbackDisplayStyle, kVaryingColor, 'w');
g_hud.AddRadioButton(1, "Face varying color", g_displayStyle == kFaceVaryingColor,
200, 90, callbackDisplayStyle, kFaceVaryingColor, 'w');
g_hud.AddCheckBox("Batching (B)", g_batching != 0, 350, 10, callbackCheckBox, HUD_CB_BATCHING, 'b');
g_hud.AddCheckBox("Patch Color (P)", true, 350, 50, callbackCheckBox, HUD_CB_DISPLAY_PATCH_COLOR, 'p');
g_hud.AddCheckBox("Screen space LOD (V)", g_screenSpaceTess != 0, 350, 70, callbackCheckBox, HUD_CB_VIEW_LOD, 'v');
g_hud.AddCheckBox("Freeze (spc)", false, 350, 90, callbackCheckBox, HUD_CB_FREEZE, ' ');
if (OpenSubdiv::OsdGLDrawContext::SupportsAdaptiveTessellation())
g_hud.AddCheckBox("Adaptive (`)", g_adaptive!=0, 10, 150, callbackCheckBox, HUD_CB_ADAPTIVE, '`');
@ -883,7 +884,7 @@ initHUD()
int pulldown_handle = g_hud.AddPullDown("Shape :", -300, 10, 300, callbackModel, 'n');
for (int i = 0; i < (int)g_defaultShapes.size(); ++i) {
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str());
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str(),i);
}
}

View File

@ -1066,12 +1066,13 @@ initHUD()
#endif
g_hud.Init(windowWidth, windowHeight);
g_hud.AddRadioButton(0, "CPU (K)", true, 10, 10, callbackKernel, kCPU, 'k');
int compute_pulldown = g_hud.AddPullDown("Compute (k) :", 10, 10, 300, callbackKernel, 'k');
g_hud.AddPullDownButton(compute_pulldown, "CPU", kCPU);
#ifdef OPENSUBDIV_HAS_OPENMP
g_hud.AddRadioButton(0, "OPENMP", false, 10, 30, callbackKernel, kOPENMP, 'k');
g_hud.AddPullDownButton(compute_pulldown, "OpenMP", kOPENMP);
#endif
#ifdef OPENSUBDIV_HAS_TBB
g_hud.AddRadioButton(0, "TBB", false, 10, 50, callbackKernel, kTBB, 'k');
g_hud.AddPullDownButton(compute_pulldown, "TBB", kTBB);
#endif
g_hud.AddCheckBox("Cage Edges (H)", true, 350, 10, callbackDisplayCageEdges, 0, 'h');
@ -1087,7 +1088,7 @@ initHUD()
int pulldown_handle = g_hud.AddPullDown("Shape :", -300, 10, 300, callbackModel, 'n');
for (int i = 0; i < (int)g_defaultShapes.size(); ++i) {
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str());
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str(),i);
}
}

View File

@ -1680,55 +1680,56 @@ initHUD()
#endif
g_hud.Init(windowWidth, windowHeight);
g_hud.AddRadioButton(0, "CPU (K)", true, 10, 10, callbackKernel, kCPU, 'k');
g_hud.AddRadioButton(1, "Wire (W)", g_displayStyle == kWire, 10, 10, callbackDisplayStyle, 0, 'w');
g_hud.AddRadioButton(1, "Shaded", g_displayStyle == kShaded, 10, 30, callbackDisplayStyle, 1, 'w');
g_hud.AddRadioButton(1, "Wire+Shaded", g_displayStyle == kWireShaded, 10, 50, callbackDisplayStyle, 2, 'w');
g_hud.AddRadioButton(1, "Varying color", g_displayStyle == kVaryingColor, 10, 70, callbackDisplayStyle, 3, 'w');
g_hud.AddRadioButton(1, "FaceVarying color", g_displayStyle == kFaceVaryingColor, 10, 90, callbackDisplayStyle, 4, 'w');
g_hud.AddCheckBox("Cage Edges (H)", g_drawCageEdges != 0,
200, 10, callbackCheckBox, kHUD_CB_DISPLAY_CAGE_EDGES, 'h');
g_hud.AddCheckBox("Cage Verts (J)", g_drawCageVertices != 0,
200, 30, callbackCheckBox, kHUD_CB_DISPLAY_CAGE_VERTS, 'j');
g_hud.AddCheckBox("Animate vertices (M)", g_moveScale != 0,
200, 50, callbackCheckBox, kHUD_CB_ANIMATE_VERTICES, 'm');
g_hud.AddCheckBox("Patch Color (P)", g_displayPatchColor != 0,
200, 70, callbackCheckBox, kHUD_CB_DISPLAY_PATCH_COLOR, 'p');
g_hud.AddCheckBox("Screen space LOD (V)", g_screenSpaceTess != 0,
200, 90, callbackCheckBox, kHUD_CB_VIEW_LOD, 'v');
g_hud.AddCheckBox("Fractional spacing (T)", g_fractionalSpacing != 0,
200, 110, callbackCheckBox, kHUD_CB_FRACTIONAL_SPACING, 't');
g_hud.AddCheckBox("Frustum Patch Culling (B)", g_patchCull != 0,
200, 130, callbackCheckBox, kHUD_CB_PATCH_CULL, 'b');
g_hud.AddCheckBox("Freeze (spc)", g_freeze != 0,
200, 150, callbackCheckBox, kHUD_CB_FREEZE, ' ');
int compute_pulldown = g_hud.AddPullDown("Compute (k) :", 450, 10, 300, callbackKernel, 'k');
g_hud.AddPullDownButton(compute_pulldown, "CPU", kCPU);
#ifdef OPENSUBDIV_HAS_OPENMP
g_hud.AddRadioButton(0, "OPENMP", false, 10, 30, callbackKernel, kOPENMP, 'k');
g_hud.AddPullDownButton(compute_pulldown, "OpenMP", kOPENMP);
#endif
#ifdef OPENSUBDIV_HAS_TBB
g_hud.AddRadioButton(0, "TBB", false, 10, 50, callbackKernel, kTBB, 'k');
g_hud.AddPullDownButton(compute_pulldown, "TBB", kTBB);
#endif
#ifdef OPENSUBDIV_HAS_GCD
g_hud.AddRadioButton(0, "GCD", false, 10, 70, callbackKernel, kGCD, 'k');
g_hud.AddPullDownButton(compute_pulldown, "GCD", kGCD);
#endif
#ifdef OPENSUBDIV_HAS_CUDA
g_hud.AddRadioButton(0, "CUDA", false, 10, 90, callbackKernel, kCUDA, 'k');
g_hud.AddPullDownButton(compute_pulldown, "CUDA", kCUDA);
#endif
#ifdef OPENSUBDIV_HAS_OPENCL
g_hud.AddRadioButton(0, "OPENCL", false, 10, 110, callbackKernel, kCL, 'k');
g_hud.AddPullDownButton(compute_pulldown, "OpenCL", kCL);
#endif
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
g_hud.AddRadioButton(0, "GLSL TransformFeedback", false, 10, 130, callbackKernel, kGLSL, 'k');
g_hud.AddPullDownButton(compute_pulldown, "GLSL TransformFeedback", kGLSL);
#endif
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
// Must also check at run time for OpenGL 4.3
if (GLEW_VERSION_4_3) {
g_hud.AddRadioButton(0, "GLSL Compute", false, 10, 150, callbackKernel, kGLSLCompute, 'k');
g_hud.AddPullDownButton(compute_pulldown, "GLSL Compute", kGLSLCompute);
}
#endif
g_hud.AddRadioButton(1, "Wire (W)", g_displayStyle == kWire, 200, 10, callbackDisplayStyle, 0, 'w');
g_hud.AddRadioButton(1, "Shaded", g_displayStyle == kShaded, 200, 30, callbackDisplayStyle, 1, 'w');
g_hud.AddRadioButton(1, "Wire+Shaded", g_displayStyle == kWireShaded, 200, 50, callbackDisplayStyle, 2, 'w');
g_hud.AddRadioButton(1, "Varying color", g_displayStyle == kVaryingColor, 200, 70, callbackDisplayStyle, 3, 'w');
g_hud.AddRadioButton(1, "FaceVarying color", g_displayStyle == kFaceVaryingColor, 200, 90, callbackDisplayStyle, 4, 'w');
g_hud.AddCheckBox("Cage Edges (H)", g_drawCageEdges != 0,
350, 10, callbackCheckBox, kHUD_CB_DISPLAY_CAGE_EDGES, 'h');
g_hud.AddCheckBox("Cage Verts (J)", g_drawCageVertices != 0,
350, 30, callbackCheckBox, kHUD_CB_DISPLAY_CAGE_VERTS, 'j');
g_hud.AddCheckBox("Animate vertices (M)", g_moveScale != 0,
350, 50, callbackCheckBox, kHUD_CB_ANIMATE_VERTICES, 'm');
g_hud.AddCheckBox("Patch Color (P)", g_displayPatchColor != 0,
350, 70, callbackCheckBox, kHUD_CB_DISPLAY_PATCH_COLOR, 'p');
g_hud.AddCheckBox("Screen space LOD (V)", g_screenSpaceTess != 0,
350, 90, callbackCheckBox, kHUD_CB_VIEW_LOD, 'v');
g_hud.AddCheckBox("Fractional spacing (T)", g_fractionalSpacing != 0,
350, 110, callbackCheckBox, kHUD_CB_FRACTIONAL_SPACING, 't');
g_hud.AddCheckBox("Frustum Patch Culling (B)", g_patchCull != 0,
350, 130, callbackCheckBox, kHUD_CB_PATCH_CULL, 'b');
g_hud.AddCheckBox("Freeze (spc)", g_freeze != 0,
350, 150, callbackCheckBox, kHUD_CB_FREEZE, ' ');
if (OpenSubdiv::OsdGLDrawContext::SupportsAdaptiveTessellation())
g_hud.AddCheckBox("Adaptive (`)", g_adaptive!=0, 10, 190, callbackAdaptive, 0, '`');
@ -1738,9 +1739,9 @@ initHUD()
g_hud.AddRadioButton(3, level, i==2, 10, 210+i*20, callbackLevel, i, '0'+(i%10));
}
int pulldown_handle = g_hud.AddPullDown("Shape :", -300, 10, 300, callbackModel, 'n');
int shapes_pulldown = g_hud.AddPullDown("Shape (n) :", -300, 10, 300, callbackModel, 'n');
for (int i = 0; i < (int)g_defaultShapes.size(); ++i) {
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str());
g_hud.AddPullDownButton(shapes_pulldown, g_defaultShapes[i].name.c_str(),i);
}
}

View File

@ -1064,7 +1064,7 @@ initHUD()
int pulldown_handle = g_hud.AddPullDown("Shape :", -300, 10, 300, callbackModel, 'n');
for (int i = 0; i < (int)g_defaultShapes.size(); ++i) {
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str());
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str(),i);
}
}

View File

@ -1176,7 +1176,7 @@ initHUD()
int pulldown_handle = g_hud.AddPullDown("Shape :", -300, 10, 300, callbackModel, 'n');
for (int i = 0; i < (int)g_defaultShapes.size(); ++i) {
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str());
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str(),i);
}
}

View File

@ -80,6 +80,11 @@ OpenSubdiv::OsdCpuComputeController * g_cpuComputeController = NULL;
OpenSubdiv::OsdOmpComputeController * g_ompComputeController = NULL;
#endif
#ifdef OPENSUBDIV_HAS_TBB
#include <osd/tbbComputeController.h>
OpenSubdiv::OsdTbbComputeController *g_tbbComputeController = NULL;
#endif
#ifdef OPENSUBDIV_HAS_OPENCL
#include <osd/clGLVertexBuffer.h>
#include <osd/clComputeContext.h>
@ -157,10 +162,11 @@ typedef OpenSubdiv::HbrHalfedge<OpenSubdiv::OsdVertex> OsdHbrHalfedge;
enum KernelType { kCPU = 0,
kOPENMP = 1,
kCUDA = 2,
kCL = 3,
kGLSL = 4,
kGLSLCompute = 5 };
kTBB = 2,
kCUDA = 3,
kCL = 4,
kGLSL = 5,
kGLSLCompute = 6 };
enum HudCheckBox { HUD_CB_ADAPTIVE,
HUD_CB_DISPLAY_OCCLUSION,
@ -1065,6 +1071,20 @@ createOsdMesh(int level, int kernel)
numVaryingElements,
level, bits);
#endif
#ifdef OPENSUBDIV_HAS_TBB
} else if (kernel == kTBB) {
if (not g_tbbComputeController) {
g_tbbComputeController = new OpenSubdiv::OsdTbbComputeController();
}
g_mesh = new OpenSubdiv::OsdMesh<OpenSubdiv::OsdCpuGLVertexBuffer,
OpenSubdiv::OsdTbbComputeController,
OpenSubdiv::OsdGLDrawContext>(
g_tbbComputeController,
hmesh,
numVertexElements,
numVaryingElements,
level, bits);
#endif
#ifdef OPENSUBDIV_HAS_OPENCL
} else if (kernel == kCL) {
if (not g_clComputeController) {
@ -2015,6 +2035,10 @@ void uninitGL()
delete g_ompComputeController;
#endif
#ifdef OPENSUBDIV_HAS_TBB
delete g_tbbComputeController;
#endif
#ifdef OPENSUBDIV_HAS_OPENCL
delete g_clComputeController;
uninitCL(g_clContext, g_clQueue);
@ -2498,29 +2522,30 @@ int main(int argc, char ** argv)
#endif
g_hud.Init(windowWidth, windowHeight);
g_hud.AddRadioButton(HUD_RB_KERNEL, "CPU (K)", true,
10, 10, callbackKernel, kCPU, 'k');
int compute_pulldown = g_hud.AddPullDown("Compute (k) :", 450, 10, 300, callbackKernel, 'k');
g_hud.AddPullDownButton(compute_pulldown, "CPU", kCPU);
#ifdef OPENSUBDIV_HAS_OPENMP
g_hud.AddRadioButton(HUD_RB_KERNEL, "OPENMP", false,
10, 30, callbackKernel, kOPENMP, 'k');
g_hud.AddPullDownButton(compute_pulldown, "OpenMP", kOPENMP);
#endif
#ifdef OPENSUBDIV_HAS_TBB
g_hud.AddPullDownButton(compute_pulldown, "TBB", kTBB);
#endif
#ifdef OPENSUBDIV_HAS_GCD
g_hud.AddPullDownButton(compute_pulldown, "GCD", kGCD);
#endif
#ifdef OPENSUBDIV_HAS_CUDA
g_hud.AddRadioButton(HUD_RB_KERNEL, "CUDA", false,
10, 50, callbackKernel, kCUDA, 'k');
g_hud.AddPullDownButton(compute_pulldown, "CUDA", kCUDA);
#endif
#ifdef OPENSUBDIV_HAS_OPENCL
g_hud.AddRadioButton(HUD_RB_KERNEL, "OPENCL", false,
10, 70, callbackKernel, kCL, 'k');
g_hud.AddPullDownButton(compute_pulldown, "OpenCL", kCL);
#endif
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
g_hud.AddRadioButton(HUD_RB_KERNEL, "GLSL Transform Feedback", false,
10, 90, callbackKernel, kGLSL, 'k');
g_hud.AddPullDownButton(compute_pulldown, "GLSL TransformFeedback", kGLSL);
#endif
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
// Must also check at run time for OpenGL 4.3
if (GLEW_VERSION_4_3) {
g_hud.AddRadioButton(HUD_RB_KERNEL, "GLSL Compute", false,
10, 110, callbackKernel, kGLSLCompute, 'k');
g_hud.AddPullDownButton(compute_pulldown, "GLSL Compute", kGLSLCompute);
}
#endif

View File

@ -1311,7 +1311,7 @@ initHUD()
int pulldown_handle = g_hud.AddPullDown("Shape :", -300, 10, 300, callbackModel, 'n');
for (int i = 0; i < (int)g_defaultShapes.size(); ++i) {
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str());
g_hud.AddPullDownButton(pulldown_handle, g_defaultShapes[i].name.c_str(),i);
}
}