29 #include <libFreeWRL.h>
30 #include <scenegraph/Viewer.h>
31 #include <opengl/OpenGL_Utils.h>
32 #include <opengl/Textures.h>
33 #include <opengl/LoadTextures.h>
34 #include "scenegraph/RenderFuncs.h"
44 #if defined(STATUSBAR_HUD) || defined(STATUSBAR_STD)
48 static GLfloat colorButtonHighlight[4] = {.5f,.5f,.5f,.5f};
49 static GLfloat colorButtonCTRL[4] = {.6f,.6f,.6f,.5f};
51 static GLfloat colorClear[4] = {0.24f,0.27f,0.34f,1.0f};
52 #define LIME {.8f,1.0f,0.0f,1.0f}
55 #define HIGHLIGHT LIME
56 static GLfloat colorButtonIcon[4] = HIGHLIGHT;
57 static GLfloat colorStatusbarText[4] = HIGHLIGHT;
58 static GLfloat colorMessageText[4] = HIGHLIGHT;
60 static int ui_color_changed = -1;
62 void update_ui_colors(){
64 ic = fwl_get_ui_color_changed();
65 if( ic != ui_color_changed){
66 fwl_get_ui_color(
"panel",colorClear);
67 fwl_get_ui_color(
"menuIcon",colorButtonIcon);
68 fwl_get_ui_color(
"statusText",colorStatusbarText);
69 fwl_get_ui_color(
"messageText",colorMessageText);
70 ui_color_changed = ic;
73 static GLbyte vShaderStr[] =
74 "attribute vec4 a_position; \n"
75 "attribute vec2 a_texCoord; \n"
76 "varying vec2 v_texCoord; \n"
79 " gl_Position = a_position; \n"
80 " v_texCoord = a_texCoord; \n"
84 static GLbyte fShaderStr[] =
85 #ifdef GL_ES_VERSION_2_0
86 "precision mediump float; \n"
87 #endif //GL_ES_VERSION_2_0
88 "varying vec2 v_texCoord; \n"
89 "uniform sampler2D Texture0; \n"
90 "uniform vec4 Color4f; \n"
93 " gl_FragColor = Color4f * texture2D( Texture0, v_texCoord ); \n"
97 GLuint esLoadShader ( GLenum type,
const char *shaderSrc )
102 shader = glCreateShader ( type );
108 glShaderSource ( shader, 1, &shaderSrc, NULL );
111 glCompileShader ( shader );
114 glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );
120 glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
124 char* infoLog = MALLOC(
void *,
sizeof(
char) * infoLen );
126 glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );
127 printf (
"Error compiling shader:\n%s\n", infoLog );
132 glDeleteShader ( shader );
140 GLuint esLoadProgram (
const char *vertShaderSrc,
const char *fragShaderSrc )
143 GLuint fragmentShader;
144 GLuint programObject;
148 vertexShader = esLoadShader ( GL_VERTEX_SHADER, vertShaderSrc );
149 if ( vertexShader == 0 )
152 fragmentShader = esLoadShader ( GL_FRAGMENT_SHADER, fragShaderSrc );
153 if ( fragmentShader == 0 )
155 glDeleteShader( vertexShader );
160 programObject = glCreateProgram ( );
162 if ( programObject == 0 )
165 glAttachShader ( programObject, vertexShader );
166 glAttachShader ( programObject, fragmentShader );
169 glLinkProgram ( programObject );
172 glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );
178 glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );
182 char* infoLog = MALLOC(
void *,
sizeof(
char) * infoLen );
184 glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );
185 printf (
"Error linking program:\n%s\n", infoLog );
190 glDeleteProgram ( programObject );
195 glDeleteShader ( vertexShader );
196 glDeleteShader ( fragmentShader );
198 return programObject;
203 #include "hudIcons_octalpha.h"
219 GLubyte fwLetters8x15[][22] = {
220 {28,8,15,0,0,8,0,0x0,0x0,0x0,0xfe,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xfe,0x0,0x0,0x0},
221 {29,8,15,0,0,8,0,0x0,0x0,0x0,0xfe,0x82,0x92,0xba,0xca,0x8a,0x86,0x86,0xfe,0x4,0x2,0x2},
222 {30,8,15,0,0,8,0,0x0,0x0,0x0,0x4,0xc,0x1c,0x3c,0x7c,0xfc,0x7c,0x3c,0x1c,0xc,0x4,0x0},
223 {31,8,15,0,0,8,0,0x0,0x0,0x0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x0},
224 {32,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
225 {33,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x20,0x20,0x0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0},
226 {35,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x24,0x24,0x24,0xfe,0x24,0x24,0x24,0xfe,0x24,0x0,0x0},
227 {36,8,15,0,0,8,0,0x0,0x0,0x0,0x10,0x38,0x54,0x94,0x14,0x18,0x10,0x70,0x90,0x94,0x78,0x10},
228 {37,8,15,0,0,8,0,0x0,0x0,0x0,0x80,0x44,0x4a,0x2a,0x34,0x10,0x10,0x48,0xa8,0xa4,0x44,0x0},
229 {38,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x74,0x88,0x94,0xa0,0x40,0x40,0xa0,0x90,0x50,0x20,0x0},
230 {39,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x20,0x20,0x30,0x30,0x0,0x0},
231 {40,8,15,0,0,8,0,0x0,0x0,0x0,0x8,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x8},
232 {41,8,15,0,0,8,0,0x0,0x0,0x40,0x20,0x10,0x10,0x8,0x8,0x8,0x8,0x8,0x10,0x10,0x20,0x40},
233 {42,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x54,0x38,0x38,0x54,0x10,0x0,0x0,0x0},
234 {43,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x10,0x10,0x10,0xfe,0x10,0x10,0x10,0x10,0x0,0x0,0x0},
235 {44,8,15,0,0,8,0,0x0,0x0,0x20,0x10,0x18,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
236 {45,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0x0},
237 {46,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
238 {47,8,15,0,0,8,0,0x0,0x0,0x40,0x40,0x20,0x20,0x10,0x10,0x8,0x8,0x4,0x4,0x2,0x2,0x0},
239 {48,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x78,0x84,0x84,0xc4,0xa4,0x9c,0x84,0x84,0x84,0x78,0x0},
240 {49,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x30,0x10,0x0},
241 {50,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0xfe,0x80,0x40,0x20,0x10,0x8,0x6,0x82,0x82,0x7c,0x0},
242 {51,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x78,0x84,0x4,0x4,0x4,0x18,0x4,0x4,0x84,0x78,0x0},
243 {52,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x8,0x8,0x8,0x8,0xfc,0x88,0x48,0x28,0x18,0x8,0x0},
244 {53,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x78,0x84,0x4,0x4,0x84,0xf8,0x80,0x80,0x80,0xfc,0x0},
245 {54,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x7c,0x84,0x82,0xc2,0xa4,0x98,0x80,0x84,0x44,0x38,0x0},
246 {55,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x20,0x20,0x10,0x10,0x10,0x10,0x8,0x4,0x4,0xfc,0x0},
247 {56,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x78,0x84,0x84,0x84,0x84,0x84,0x78,0x84,0x84,0x78,0x0},
248 {57,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x78,0x84,0x4,0x34,0x4c,0x84,0x84,0x84,0x44,0x38,0x0},
249 {58,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x30,0x30,0x0,0x0,0x0,0x30,0x30,0x0,0x0,0x0,0x0},
250 {59,8,15,0,0,8,0,0x0,0x40,0x20,0x10,0x30,0x30,0x0,0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0},
251 {60,8,15,0,0,8,0,0x0,0x0,0x0,0x4,0x8,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x8,0x4,0x0},
252 {61,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0xf8,0x0,0x0,0x0,0x0},
253 {62,8,15,0,0,8,0,0x0,0x0,0x80,0x40,0x20,0x10,0x8,0x4,0x4,0x8,0x10,0x20,0x40,0x80,0x0},
254 {63,8,15,0,0,8,0,0x0,0x0,0x0,0x10,0x10,0x0,0x0,0x10,0x18,0x4,0x2,0x82,0x44,0x38,0x0},
255 {64,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x38,0x44,0x80,0x98,0xa4,0xa4,0x9c,0x84,0x48,0x30,0x0},
256 {65,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x84,0x84,0xfc,0x84,0x48,0x48,0x48,0x30,0x30,0x0,0x0},
257 {66,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0xf8,0x84,0x84,0x84,0x84,0xf8,0x84,0x84,0x84,0xf8,0x0},
258 {67,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x78,0x84,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x78,0x0},
259 {68,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0xf0,0x88,0x84,0x84,0x84,0x84,0x84,0x88,0xf0,0x0,0x0},
260 {69,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0xfc,0x80,0x80,0x80,0x80,0xf0,0x80,0x80,0xfc,0x0,0x0},
261 {70,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0xf0,0x80,0x80,0x80,0xfe,0x0},
262 {71,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x7a,0x86,0x82,0x82,0x82,0x8c,0x80,0x80,0x44,0x38,0x0},
263 {72,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x84,0x84,0x84,0x84,0xfc,0x84,0x84,0x84,0x84,0x84,0x0},
264 {73,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x0},
265 {74,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x70,0x88,0x88,0x8,0x8,0x8,0x8,0x8,0x8,0x18,0x0},
266 {75,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x86,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x84,0x80,0x0},
267 {76,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0xfc,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0},
268 {77,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x82,0x82,0x92,0x92,0xaa,0xaa,0xc6,0xc6,0x82,0x82,0x0},
269 {78,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x84,0x8c,0x8c,0x94,0x94,0xa4,0xa4,0xc4,0xc4,0x84,0x0},
270 {79,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x78,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x78,0x0},
271 {80,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0xb8,0xc4,0x84,0x84,0x84,0xf8,0x0},
272 {81,8,15,0,0,8,0,0x0,0x4,0x18,0x20,0x7c,0xa2,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x7c,0x0},
273 {82,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x82,0x84,0x8c,0x88,0xfc,0x82,0x82,0x82,0x82,0xfc,0x0},
274 {83,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x78,0x84,0x4,0x4,0x18,0x60,0x80,0x80,0x84,0x7c,0x0},
275 {84,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xfe,0x0},
276 {85,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x7c,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x0},
277 {86,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x10,0x10,0x28,0x44,0x44,0x44,0x44,0x82,0x82,0x82,0x0},
278 {87,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x44,0x44,0xaa,0xaa,0x92,0x92,0x92,0x82,0x82,0x0,0x0},
279 {88,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x84,0x84,0x48,0x48,0x30,0x30,0x4c,0x44,0x84,0x84,0x0},
280 {89,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x10,0x10,0x10,0x10,0x10,0x28,0x28,0x44,0x82,0x82,0x0},
281 {90,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0xfe,0x80,0x40,0x40,0x20,0x10,0x8,0x4,0x4,0xfe,0x0},
282 {91,8,15,0,0,8,0,0x0,0x0,0x0,0xe0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xe0,0x0},
283 {92,8,15,0,0,8,0,0x0,0x0,0x4,0x4,0x8,0x8,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x0},
284 {93,8,15,0,0,8,0,0x0,0x0,0x0,0x38,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x38,0x0},
285 {94,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x44,0x28,0x10,0x0},
286 {95,8,15,0,0,8,0,0x0,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
287 {96,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x40,0xc0,0xc0,0x0},
288 {97,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x74,0x88,0x98,0x68,0x8,0x88,0x70,0x0,0x0,0x0,0x0},
289 {98,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0xb8,0xc4,0x84,0xc4,0xc4,0xb8,0x80,0x80,0x80,0x0,0x0},
290 {99,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x78,0x84,0x80,0x80,0x80,0x84,0x78,0x0,0x0,0x0,0x0},
291 {100,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x74,0x8c,0x8c,0x84,0x8c,0x74,0x4,0x4,0x4,0x0,0x0},
292 {101,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x78,0x84,0x80,0xbc,0xc4,0x84,0x78,0x0,0x0,0x0,0x0},
293 {102,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x20,0x20,0x20,0x20,0x78,0x20,0x20,0x24,0x3c,0x0,0x0},
294 {103,8,15,0,0,8,0,0x18,0x64,0x4,0x4,0x34,0x4c,0x84,0x84,0x84,0x8c,0x74,0x0,0x0,0x0,0x0},
295 {104,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x84,0x84,0x84,0x84,0x84,0xc4,0xb8,0x80,0x80,0x80,0x0},
296 {105,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x10,0x10,0x10,0x10,0x10,0x10,0x30,0x0,0x10,0x0,0x0},
297 {106,8,15,0,0,8,0,0x40,0xa0,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x30,0x0,0x10,0x0},
298 {107,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x84,0x98,0xb0,0xc0,0xa0,0x90,0x88,0x80,0x80,0x0,0x0},
299 {108,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x18,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x30,0x0,0x0},
300 {109,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x54,0x54,0x54,0x54,0x54,0x54,0xa8,0x0,0x0,0x0,0x0},
301 {110,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x84,0x84,0x84,0x84,0x84,0xc8,0xb8,0x0,0x0,0x0,0x0},
302 {111,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x78,0x84,0x84,0x84,0x84,0x84,0x78,0x0,0x0,0x0,0x0},
303 {112,8,15,0,0,8,0,0x80,0x80,0x80,0x80,0xb8,0xa4,0xc4,0x84,0x84,0xc4,0xa4,0x18,0x0,0x0,0x0},
304 {113,8,15,0,0,8,0,0x2,0x4,0x4,0x4,0x74,0x8c,0x8c,0x84,0x84,0x8c,0x74,0x0,0x0,0x0,0x0},
305 {114,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0xc0,0xa4,0xb8,0x0,0x0,0x0,0x0},
306 {115,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0xf8,0x84,0x4,0x38,0x40,0x84,0x78,0x0,0x0,0x0,0x0},
307 {116,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x30,0x28,0x20,0x20,0x20,0x20,0x78,0x20,0x20,0x0,0x0},
308 {117,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x74,0x4c,0x84,0x84,0x84,0x84,0x84,0x0,0x0,0x0,0x0},
309 {118,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x30,0x30,0x48,0x48,0x84,0x84,0x84,0x0,0x0,0x0,0x0},
310 {119,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x24,0x5a,0x92,0x92,0x82,0x82,0x82,0x0,0x0,0x0,0x0},
311 {120,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x84,0x84,0x48,0x30,0x48,0x84,0x84,0x0,0x0,0x0,0x0},
312 {121,8,15,0,0,8,0,0x38,0x44,0x84,0x4,0x74,0x8c,0x84,0x84,0x84,0x84,0x0,0x0,0x0,0x0,0x0},
313 {122,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0xfc,0x80,0x40,0x20,0x10,0x8,0xfc,0x0,0x0,0x0,0x0},
314 {123,8,15,0,0,8,0,0x0,0x0,0x30,0x40,0x40,0x40,0x40,0x40,0xc0,0x40,0x40,0x40,0x40,0x30,0x0},
315 {124,8,15,0,0,8,0,0x0,0x0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x0},
316 {125,8,15,0,0,8,0,0x0,0x0,0x0,0x60,0x10,0x10,0x10,0x10,0x18,0x10,0x10,0x10,0x10,0x60,0x0},
317 {126,8,15,0,0,8,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x98,0xb4,0x64,0x0,0x0,0x0,0x0,0x0},
318 {255,0,0,0,0,0,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
321 #if defined(QNX) || defined(KIOSK)
332 GLfloat tex[2][2][256];
333 GLfloat owh[2][2][256];
338 typedef struct buttonSet buttonSet;
354 buttonSet *buttonset;
357 typedef struct buttonSet {
360 pmenuItem_t ** items;
395 typedef struct {
int x;
int y;}
XY;
401 static ivec4 defaultViewport = {0,0,400,400};
410 int statusbar_pinned;
432 char messagebar[200];
435 char * optionsVal[30];
439 int bmScaleForOptions;
446 GLuint programObject;
454 GLfloat textColor[4];
459 int side_top, side_bottom;
461 void *statusbar_constructor(){
466 void statusbar_init(
struct tstatusbar *t){
469 t->prv = statusbar_constructor();
475 p->wantStatusbar = 1;
476 p->wantButtons = p->wantStatusbar;
477 p->showButtons = p->wantButtons;
478 p->showStatus = p->wantStatusbar;
489 p->fontInitialized = 0;
492 p->optionsLoaded = 0;
497 p->bmScaleForOptions = 2;
499 p->bmScaleForOptions = 1;
501 p->bmScaleRegular = 1;
503 p->bmScaleRegular = 2;
504 p->bmScaleForOptions = 2;
506 p->bmScale = p->bmScaleRegular;
507 p->statusBarSize = p->bmScaleRegular * 16;
508 p->statusBarRows = 1;
510 p->pfont.cheight = 0;
512 p->pfont.lumalpha = NULL;
513 p->pmenu.items = MALLOC(pmenuItem_t *, MAXBUT *
sizeof(pmenuItem_t));
514 for(i=0;i<MAXBUT;i++) p->pmenu.items[i].butStatus = 0;
515 p->pmenu.bitems = (barItem *)malloc(MAXBUT *
sizeof(barItem));
516 bzero(p->pmenu.bitems,MAXBUT *
sizeof(barItem));
519 p->buttonSize = BUTSIZE;
521 p->textColor[3] = 1.0f;
524 p->vport = defaultViewport;
525 p->clipPlane = p->statusBarSize;
531 void initProgramObject(){
535 p->programObject = esLoadProgram ( (
const char*) vShaderStr, (
const char *)fShaderStr );
537 p->positionLoc = glGetAttribLocation ( p->programObject,
"a_position" );
538 p->texCoordLoc = glGetAttribLocation ( p->programObject,
"a_texCoord" );
540 p->textureLoc = glGetUniformLocation ( p->programObject,
"Texture0" );
541 p->color4fLoc = glGetUniformLocation ( p->programObject,
"Color4f" );
543 static int lenOptions = 26;
544 void statusbar_clear(
struct tstatusbar *t){
550 glDeleteTextures(1, &(p->pfont.textureID));
551 glDeleteTextures(1, &(p->pmenu.textureID));
553 ml_delete_all(p->conlist);
555 for(i=0;i<lenOptions;i++)
558 FREE_IF_NZ(p->optionsVal[i]);
561 for(i=0;i<p->pmenu.nitems;i++)
562 FREE_IF_NZ(p->pmenu.items[i].lumalpha);
563 FREE_IF_NZ(p->pmenu.lumalpha);
564 FREE_IF_NZ(p->pmenu.items);
565 FREE_IF_NZ(p->pmenu.vert);
566 FREE_IF_NZ(p->pmenu.ind);
567 FREE_IF_NZ(p->pfont.lumalpha);
570 void fwMakeRasterFonts()
572 int i,j,k,m,w,h,bytewidth,bit;
574 int ichar,isize, irow, icol, irowheight,icolwidth, iwidth, iheight;
576 GLubyte *cdata, *row;
583 p->pfont.cheight = 15;
591 height = (float)iheight;
592 width = (float)iwidth;
595 isize = iheight * iwidth * 2;
597 p->pfont.lumalpha = MALLOC(GLubyte *, isize);
599 memset(p->pfont.lumalpha,0,isize);
600 white[0] = white[1] = (GLubyte)255;
603 p->pfont.have[m] = 0;
607 ichar = fwLetters8x15[m][0];
608 if(ichar == 255)
break;
609 p->pfont.have[ichar] = 1;
610 cdata = &fwLetters8x15[m][7];
611 w = fwLetters8x15[m][1];
612 h = fwLetters8x15[m][2];
616 p->pfont.tex[0][0][ichar] = (GLfloat)(icol * icolwidth);
617 p->pfont.tex[1][0][ichar] = (GLfloat)(irow * irowheight);
618 p->pfont.tex[0][1][ichar] = p->pfont.tex[0][0][ichar] + p->pfont.cwidth;
619 p->pfont.tex[1][1][ichar] = p->pfont.tex[1][0][ichar] + p->pfont.cheight;
620 p->pfont.owh[0][0][ichar] = p->pfont.owh[1][0][ichar] = 0.0f;
621 p->pfont.owh[0][1][ichar] = (GLfloat)p->pfont.cwidth;
622 p->pfont.owh[1][1][ichar] = (GLfloat)p->pfont.cheight;
625 p->pfont.tex[0][j][ichar] /= width;
626 p->pfont.tex[1][j][ichar] /= height;
628 bytewidth = ((w-1)/8 +1);
631 row = &cdata[j*bytewidth];
636 bit = row[k] & (1<<((bytewidth*8)-i-1))? 1 : 0;
641 ip = (irow*irowheight +j)*iwidth;
642 ip += icol*icolwidth + i;
643 memcpy(&p->pfont.lumalpha[ip*2],white,2);
652 fp = fopen(
"hud_junk_0.txt",
"w+");
653 fprintf(fp,
"char data\n");
656 ichar = fwLetters8x15[m][0];
657 if(ichar == 255)
break;
658 fprintf(fp,
"%c %d ",(
char)ichar,ichar);
659 fprintf(fp,
"tex %6.2f %6.2f %6.2f %6.2f",p->pfont.tex[0][0][ichar],p->pfont.tex[1][0][ichar],p->pfont.tex[0][1][ichar],p->pfont.tex[1][1][ichar]);
660 fprintf(fp,
"ohw %6.2f %6.2f %6.2f %6.2f",p->pfont.owh[0][0][ichar],p->pfont.owh[1][0][ichar],p->pfont.owh[0][1][ichar],p->pfont.owh[1][1][ichar]);
666 glGenTextures(1, &(p->pfont.textureID));
668 glBindTexture(GL_TEXTURE_2D, p->pfont.textureID);
670 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
671 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
673 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, iwidth, iheight, 0, GL_LUMINANCE_ALPHA , GL_UNSIGNED_BYTE, p->pfont.lumalpha);
686 p->fontInitialized = 1;
690 void printString(
char *s){}
691 FXY screen2normalizedScreen( GLfloat x, GLfloat y);
692 FXY screen2normalizedScreenScale( GLfloat x, GLfloat y);
701 void printString3(GLfloat sx, GLfloat sy,
char *s,
int len)
711 int sizeoftex, sizeofvert, sizeofind;
717 sizeofvert = len *
sizeof(GLfloat) * 4 * 3;
718 sizeoftex = len *
sizeof(GLfloat) * 4 * 2;
719 sizeofind = len *
sizeof(GLshort) * 2 * 3;
720 vert = (GLfloat*)alloca(sizeofvert);
721 tex = (GLfloat*)alloca(sizeoftex);
722 ind = (GLushort*)alloca(sizeofind);
732 if (ichar ==
'\t') ichar =
' ';
733 if(p->pfont.have[ichar])
735 charScreenSize = screen2normalizedScreenScale(p->pfont.owh[0][1][ichar]*p->bmScale,p->pfont.owh[1][1][ichar]*p->bmScale);
740 vert[i*4*3 +4] = y + charScreenSize.y;
742 vert[i*4*3 +6] = x + charScreenSize.x;
743 vert[i*4*3 +7] = y + charScreenSize.y;
745 vert[i*4*3 +9] = x + charScreenSize.x;
748 x = x + charScreenSize.x;
749 tex[i*4*2 +0] = p->pfont.tex[0][0][ichar];
750 tex[i*4*2 +1] = p->pfont.tex[1][0][ichar];
751 tex[i*4*2 +2] = p->pfont.tex[0][0][ichar];
752 tex[i*4*2 +3] = p->pfont.tex[1][1][ichar];
753 tex[i*4*2 +4] = p->pfont.tex[0][1][ichar];
754 tex[i*4*2 +5] = p->pfont.tex[1][1][ichar];
755 tex[i*4*2 +6] = p->pfont.tex[0][1][ichar];
756 tex[i*4*2 +7] = p->pfont.tex[1][0][ichar];
757 ind[i*3*2 +0] = i*4 + 0;
758 ind[i*3*2 +1] = i*4 + 1;
759 ind[i*3*2 +2] = i*4 + 2;
760 ind[i*3*2 +3] = i*4 + 2;
761 ind[i*3*2 +4] = i*4 + 3;
762 ind[i*3*2 +5] = i*4 + 0;
768 glActiveTexture ( GL_TEXTURE0 );
769 glBindTexture ( GL_TEXTURE_2D, p->pfont.textureID );
771 glVertexAttribPointer ( p->positionLoc, 3, GL_FLOAT,
774 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
777 glEnableVertexAttribArray ( p->positionLoc );
778 glEnableVertexAttribArray ( p->texCoordLoc );
780 glUniform1i ( p->textureLoc, 0 );
781 glDrawElements ( GL_TRIANGLES, i*3*2, GL_UNSIGNED_SHORT, ind );
788 void printString2(GLfloat sx, GLfloat sy,
char *s){
789 printString3(sx,sy,s,strlen(s));
791 void render_init(
void);
822 char * optionsText[] = {
829 "Eyebase - object space",
831 "Your Eyebase = fiducials",
842 "target FPS \36 \37",
843 " emulate multitouch (mousewheel)",
845 " left right either",
846 "screen orientation \36 \37",
848 " flat gouraud phong wire",
858 char *colorschemenames [] = {
870 void fwl_setPickraySide(
int ipreferredSide,
int either);
871 void fwl_getPickraySide(
int *ipreferredSide,
int *either);
872 int fwl_getOrientation();
873 int fwl_getOrientation2();
874 void fwl_setOrientation2(
int degrees);
875 int fwl_getShadingStyle();
876 void initOptionsVal()
878 int i,j,k, iside, ieither, shadingStyle;
883 for(i=0;i<lenOptions;i++)
885 if(!p->optionsVal[i])
886 p->optionsVal[i] = MALLOC(
char*, 30);
887 for(j=0;j<30;j++) p->optionsVal[i][j] =
' ';
888 p->optionsVal[i][29] =
'\0';
890 p->optionsVal[1][0] = 034;
891 p->optionsVal[2][0] = 034;
892 p->optionsVal[3][0] = 034;
893 p->optionsVal[4][0] = 034;
894 p->optionsVal[5][0] = 034;
896 if(!(viewer->sidebyside || viewer->updown || viewer->anaglyph || viewer->shutterGlasses))
897 p->optionsVal[1][0] = 035;
898 if(viewer->sidebyside)
899 p->optionsVal[2][0] = 035;
901 p->optionsVal[3][0] = 035;
903 p->optionsVal[4][0] = 035;
904 if(viewer->shutterGlasses)
905 p->optionsVal[5][0] = 035;
906 sprintf(p->optionsVal[7],
" %4.3f",viewer->eyedist);
907 sprintf(p->optionsVal[9],
" %4.3f",viewer->screendist);
911 k = getAnaglyphPrimarySide(j,i);
912 p->optionsVal[12+i][j+1] = (k ? 035 :
' ');
915 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
916 p->optionsVal[15][0] = p->statusbar_pinned ? 035 : 034;
917 p->optionsVal[16][0] = p->menubar_pinned ? 035 : 034;
918 sprintf(p->optionsVal[18],
" %s ",fwl_get_ui_colorschemename());
919 sprintf(p->optionsVal[19],
" %4d",fwl_get_target_fps());
920 p->optionsVal[20][0] = 034;
921 if(fwl_get_emulate_multitouch())
922 p->optionsVal[20][0] = 035;
923 fwl_getPickraySide(&iside,&ieither);
924 p->optionsVal[22][1] = p->optionsVal[22][7] = p->optionsVal[22][14] = 034;
925 if(iside==0) p->optionsVal[22][1] = 035;
926 else p->optionsVal[22][7] = 035;
927 if(ieither) p->optionsVal[22][14] = 035;
928 sprintf(p->optionsVal[23],
" %4d",fwl_getOrientation2());
929 shadingStyle = fwl_getShadingStyle();
930 p->optionsVal[25][1] = p->optionsVal[25][7] = p->optionsVal[25][16] = p->optionsVal[25][23] =034;
931 switch(shadingStyle){
932 case 0: p->optionsVal[25][1] = 035;
break;
933 case 1: p->optionsVal[25][7] = 035;
break;
934 case 2: p->optionsVal[25][16] = 035;
break;
935 case 3: p->optionsVal[25][23] = 035;
break;
940 p->optionsLoaded = 1;
942 void updateOptionsVal()
949 char * optionsCase[] = {
979 XY mouse2screen(
int x,
int y)
987 XY screen2text(
int x,
int y)
995 topOffset = p->side_top;
996 if(p->pmenu.top) topOffset += p->buttonSize;
997 rc.x = x/(p->bmWH.x*p->bmScale) -1;
998 rc.y = (int)((p->vport.H -y - topOffset)/(p->bmWH.y*p->bmScale));
1002 XY text2screen(
int col,
int row)
1009 topOffset = p->side_top;
1010 if(p->pmenu.top) topOffset += p->buttonSize;
1011 xy.x = (col+1)*p->bmWH.x*p->bmScale;
1012 xy.y = p->vport.H - topOffset - (row+2)*p->bmWH.y*p->bmScale;
1015 FXY screen2normalizedScreenScale( GLfloat x, GLfloat y)
1021 xy.x = ((GLfloat)x/(GLfloat)p->vport.W * 2.0f);
1022 xy.y = ((GLfloat)y/(GLfloat)p->vport.H * 2.0f);
1025 FXY screen2normalizedScreen( GLfloat x, GLfloat y)
1029 xy = screen2normalizedScreenScale(x,y);
1040 if(!p->optionsLoaded) initOptionsVal();
1043 p->bmScale = p->bmScaleForOptions;
1044 for(j=0;j<lenOptions;j++)
1047 XY xy0 = text2screen(0,j);
1048 xy = screen2normalizedScreen( (GLfloat)xy0.x, (GLfloat)xy0.y);
1049 printString2(xy.x,xy.y,p->optionsVal[j]);
1050 printString2(xy.x,xy.y,optionsText[j]);
1052 p->bmScale = p->bmScaleRegular;
1055 int handleOptionPress(
int mouseX,
int mouseY)
1070 p->bmScale = p->bmScaleForOptions;
1071 xys = mouse2screen(mouseX,mouseY);
1073 if (Viewer()->updown) p->side_top = p->vport.H / 2;
1074 xyt = screen2text(xys.x,xys.y);
1076 if( 0 <= xyt.y && xyt.y < lenOptions )
1078 int len = (int) strlen(optionsCase[xyt.y]);
1082 opt = optionsCase[xyt.y][xyt.x];
1085 if(opt ==
' ')
return 0;
1086 p->bmScale = p->bmScaleRegular;
1094 printf(
"toggle EAI");
1102 toggleOrSetStereo(opt-
'0');
1105 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
1106 p->statusbar_pinned = 1 - p->statusbar_pinned;
1107 fwl_set_sbh_pin(p->statusbar_pinned,p->menubar_pinned);
1110 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
1111 p->menubar_pinned = 1 - p->menubar_pinned;
1112 fwl_set_sbh_pin(p->statusbar_pinned,p->menubar_pinned);
1115 fwl_next_ui_colorscheme();
1120 setAnaglyphPrimarySide(opt-
'r',0);
1125 setAnaglyphPrimarySide(opt-
'u',1);
1130 setAnaglyphPrimarySide(opt-
'x',2);
1135 printf(
"reduce eyebase");
1136 viewer->eyedist *= .9;
1141 printf(
"increase eyebase");
1142 viewer->eyedist *= 1.1;
1147 printf(
"reduce screendist");
1148 viewer->screendist -= .02;
1152 fwl_set_emulate_multitouch(1 - fwl_get_emulate_multitouch());
1157 printf(
"set screendist");
1161 printf(
"increase screendist");
1162 viewer->screendist += .02;
1163 if(viewer->sidebyside)
1164 viewer->screendist = min(viewer->screendist,.375);
1169 printf(
"reduce toe-in");
1170 viewer->stereoParameter *= .9;
1175 printf(
"set toe-in");
1179 printf(
"increase toe-in");
1180 viewer->stereoParameter *= 1.1;
1181 if(viewer->sidebyside)
1182 viewer->stereoParameter = min(viewer->stereoParameter,.01);
1190 tfps = fwl_get_target_fps();
1191 i15 = (int)((
double)tfps / 15.0 + .5);
1192 if(opt ==
'K') i15 /= 2;
1193 if(opt ==
'L') i15 = max(1,i15*2);
1194 if(i15 < 1) tfps = 7;
1195 else tfps = min(3840,(
int)15*i15);
1196 fwl_set_target_fps(tfps);
1203 fwl_getPickraySide(&iside,&ieither);
1205 ieither = 1 - ieither;
1209 fwl_setPickraySide(iside,ieither);
1213 fwl_setOrientation2((fwl_getOrientation2()+90) % 360);
1216 fwl_setOrientation2( (fwl_getOrientation2() + 360 -90) % 360);
1224 shadingStyle = opt -
'R';
1225 fwl_setShadingStyle(shadingStyle);
1238 #if defined(QNX) //|| defined(_MSC_VER)
1240 char * keyboardShortcutHelp[] = {
1242 " movement: drag left/right for turns;",
1243 " drag up/down for forward/backward",
1245 " use the buttons for these motions:",
1246 " bird: drag left/right for left/right turns",
1247 " drag up/down for foreward/backward",
1249 " translation up/down and left/right",
1250 " rotation about the viewpoint/camera axis",
1252 " rotation: drag left/right or up/down",
1253 "Level to bound viewpoint",
1254 "Flashlight/headlight",
1255 "Collision (and for WALK also gravity)",
1256 "Previous, Next viewpoint",
1258 "Console messages from the program",
1260 "Reload last scene",
1261 "Enter URL of .x3d or .wrl scene"
1262 #elif defined(KIOSK) //|| defined(_MSC_VER)
1264 char * keyboardShortcutHelp[] = {
1266 " movement: drag left/right for turns;",
1267 " drag up/down for forward/backward",
1269 " use the buttons for these motions:",
1270 " bird: drag left/right for left/right turns",
1271 " drag up/down for foreward/backward",
1273 " translation up/down and left/right",
1274 " rotation about the viewpoint/camera axis",
1276 " rotation: drag left/right or up/down",
1277 "Level to bound viewpoint",
1278 "Flashlight/headlight",
1279 "Collision (and for WALK also gravity)",
1280 "Previous, Next viewpoint",
1282 "Console messages from the program",
1286 #elif defined(_MSC_VER_NOT)
1288 char * keyboardShortcutHelp[] = {
1290 " movement: drag left/right for turns;",
1291 " drag up/down for forward/backward",
1292 "Keyboard FLY Mode",
1293 " use the keyboard for these motions:",
1294 " 8 k rotation down/up",
1295 " u o rotation left/right",
1296 " 7 9 rotation about the Z axis",
1297 " a z translation forwards/backwards",
1298 " j l translation left/right",
1299 " p ; translation up/down",
1300 " or use arrow keys. to change keychord: press SHIFT->",
1302 " rotation: drag left/right or up/down",
1303 "EXPLORE Mode - use CTRL-click to recenter",
1304 "hit spacebar to get console prompt :, then type help"
1307 #elif defined(OLD_HELP)
1309 char * keyboardShortcutHelp[] = {
1311 " LMB rotation: MX rotation around Y axis; MY rotation around X axis",
1314 " LMB movement: MX left/right turns; MY walk forward/backward",
1317 " - use CTRL-click to recenter",
1318 "Keyboard navigation",
1319 " - use arrow keys. to change keychord: press SHIFT> or SHIFT<",
1321 " e Switch to Examine navigation mode",
1322 " w Switch to Walk navigation mode",
1323 " v Go to next viewpoint in the scene",
1324 " b Go to previous viewpoint in the scene",
1325 " / Print current viewport local pose",
1326 " h Toggle headlight",
1327 " c Toggle collision detection",
1334 char * keyboardShortcutHelp[] = {
1337 "Keyboard Viewpoint change:",
1338 " PgDn,PgUp,Home,End = Next,Prev,First,Last",
1339 "Keyboard commands:",
1340 " / Print current viewpoint pose",
1343 "Keyboard navigation:",
1345 " to change keychord: press SHIFT> or SHIFT<",
1346 "Touch cursor control:",
1347 " use both PEDAL % and HOVER ^ buttons to move cursor",
1348 " use PEDAL % button to drag cursor around",
1353 const char *libFreeWRL_get_version();
1358 FXY fxy, fxy2, fxy3;
1359 GLfloat side_bottom_f;
1363 static const char *versionInfo =
"libfreeWRL version ";
1364 xy = text2screen(0,0);
1365 fxy = screen2normalizedScreen((GLfloat)xy.x,(GLfloat)xy.y);
1366 printString2(fxy.x,fxy.y,(
char *)versionInfo);
1367 xy = text2screen((
int)strlen(versionInfo),0);
1368 fxy = screen2normalizedScreen((GLfloat)xy.x,(GLfloat)xy.y);
1369 printString2(fxy.x,fxy.y,(
char*)libFreeWRL_get_version());
1373 fxy2 = screen2normalizedScreenScale((GLfloat)p->bmWH.x, (GLfloat)p->bmWH.y);
1374 fxy2.y *= p->bmScale;
1375 side_bottom_f = -1.0f;
1376 fxy3 = screen2normalizedScreenScale((GLfloat)0, (GLfloat)p->buttonRows * p->buttonSize);
1377 side_bottom_f += fxy3.y;
1380 while(keyboardShortcutHelp[j] != NULL)
1384 printString2(-1.0f, side_bottom_f + (lenhelp-j)*fxy2.y, keyboardShortcutHelp[j]);
1386 if(p->show_status && j > lenhelp)
break;
1390 void hudSetConsoleMessage(
char *buffer)
1408 last = ml_new(buffer);
1412 ml_append(p->conlist,last);
1414 if( p->concount > 50 )
1417 free((
char*)p->conlist->elem);
1418 p->conlist = ml_delete_self(p->conlist, p->conlist);
1423 void printConsoleText()
1437 xybottom = screen2text(0,p->side_bottom);
1438 jstart = max(0,p->concount-(xybottom.y - 3));
1439 for(__l=_list;__l!=NULL;)
1441 next = ml_next(__l);
1445 XY xy = text2screen(0,j-jstart);
1446 fxy = screen2normalizedScreen((GLfloat)xy.x,(GLfloat)xy.y);
1447 printString2(fxy.x,fxy.y,__l->elem);
1489 struct button_help {
1492 } button_helps [] = {
1493 {ACTION_WALK,
"WALK"},
1494 {ACTION_FLY2,
"FLY2"},
1495 {ACTION_TILT,
"TILT"},
1496 {ACTION_TPLANE,
"TRANSLATE"},
1497 {ACTION_RPLANE,
"ROLL"},
1498 {ACTION_FLY,
"FLY {yaw-z,xy,yaw-pitch,roll}"},
1499 {ACTION_EXAMINE,
"EXAMINE"},
1500 {ACTION_EXPLORE,
"EXPLORE {examine,recenter}"},
1501 {ACTION_SPHERICAL,
"SPHERICAL {pan,zoom}"},
1502 {ACTION_TURNTABLE,
"TURNTABLE"},
1503 {ACTION_LOOKAT,
"LOOKAT"},
1504 {ACTION_YAWZ,
"FLY yaw-z"},
1505 {ACTION_YAWPITCH,
"FLY yaw-pitch"},
1506 {ACTION_ROLL,
"FLY roll"},
1507 {ACTION_XY,
"FLY xy"},
1508 {ACTION_DIST,
"DIST (for examine,explore,turntable)"},
1509 {ACTION_SHIFT,
"SHIFT Key (turns off sensors)"},
1510 {ACTION_HOVER,
"HOVER up-drag isOver mode"},
1511 {ACTION_PEDAL,
"PEDAL drags in-scene cursor"},
1512 {ACTION_LEVEL,
"LEVEL to bound VP (ViewPoint)"},
1513 {ACTION_HEADLIGHT,
"HEADLIGHT"},
1514 {ACTION_COLLISION,
"COLLISION (and gravity)"},
1515 {ACTION_PREV,
"Prev VP"},
1516 {ACTION_NEXT,
"Next VP"},
1517 {ACTION_HELP,
"Help"},
1518 {ACTION_MESSAGES,
"Console"},
1519 {ACTION_OPTIONS,
"Options"},
1520 {ACTION_RELOAD,
"Reload"},
1521 {ACTION_URL,
"URL"},
1522 {ACTION_FILE,
"FILE"},
1523 {ACTION_BLANK, NULL},
1525 const char *help_for_action(
int action){
1527 struct button_help *bh;
1530 bh = &button_helps[i];
1531 if(bh->action == action)
break;
1533 }
while(bh->action != ACTION_BLANK);
1537 void convertPng2hexAlpha()
1552 static int mbuts = 1;
1553 static char * butFnames[] = {
"hover.png"};
1556 FILE* out = fopen(
"hudIcons_octalpha_h",
"w+");
1564 for(ii=0;ii<mbuts;ii++)
1566 int j,k,l,g,rgbmax[3];
1567 texture_load_from_file(&butts, butFnames[ii]);
1573 for(j=0;j<3;j++) rgbmax[j] = 0;
1574 for(j=0;j<butts.x;j++)
1576 for(k=0;k<butts.y;k++)
1580 g = butts.texdata[j*w*4 + k*4 + l];
1581 rgbmax[l] = g > rgbmax[l] ? g : rgbmax[l];
1586 for(j=0;j<butts.x;j++)
1588 for(k=0;k<butts.y;k++)
1595 h = butts.texdata[j*w*4 + k*4 + l];
1596 h = (int)((
float)h/(float)rgbmax[l]*255.0f);
1601 g = g > 255? 255 : g;
1603 butts.texdata[j*w*4 + k*4 + l] = g;
1610 strcpy(butname,butFnames[ii]);
1611 for(j=0;j<(int)strlen(butname);j++)
1612 if(butname[j] ==
'.') {butname[j] =
'\0';
break;}
1613 fprintf(out,
"GLubyte %s[] = {\n",butname);
1620 unsigned char *data;
1628 data = &butts.texdata[0];
1629 for(i=0;i<size;i+=4)
1633 datai = (int)(((
float) data[i] * (
float)data[i+3])/255.0f);
1638 if( datai ==
'"' || datai ==
'\\') {sprintf(str,
"\\%c",datai); lastoct =
false;}
1639 else if( datai >=
'0' && datai <=
'9' && lastoct && lastlen < 4) {sprintf(str,
"\"\"%c",datai); lastoct =
false;}
1640 else if( datai > 32 && datai < 127 ) {sprintf(str,
"%c",datai); lastoct =
false;}
1641 else {sprintf(str,
"\\%o",datai); lastoct =
true;}
1642 fprintf(out,
"%s",str);
1643 m = (int) strlen(str);
1648 fprintf(out,
"\"\n\"");
1652 fprintf(out,
"\"\n");
1655 fprintf(out,
"};\n");
1668 int i, buttonAtlasSizeCol, buttonAtlasSizeRow, buttonAtlasSquared;
1671 p->clipPlane = p->statusBarSize;
1674 if(p->buttonType == 0){
1675 convertPng2hexAlpha();
1678 if(p->buttonType == 1)
1683 static GLubyte * buttonlist [] = {
1685 yawz, xy, yawpitch, roll,
1686 explore, spherical, turntable, lookat, distance,
1687 shift, hover, pedal, level, headlight,
1688 collision, prev, next, help, messages,
1689 options, reload, url, file, blank
1691 static int actionlist [] = {
1692 ACTION_WALK, ACTION_FLY, ACTION_EXAMINE,
1693 ACTION_YAWZ, ACTION_XY, ACTION_YAWPITCH, ACTION_ROLL,
1694 ACTION_EXPLORE, ACTION_SPHERICAL, ACTION_TURNTABLE, ACTION_LOOKAT, ACTION_DIST,
1695 ACTION_SHIFT, ACTION_HOVER, ACTION_PEDAL, ACTION_LEVEL, ACTION_HEADLIGHT,
1696 ACTION_COLLISION, ACTION_PREV,ACTION_NEXT, ACTION_HELP, ACTION_MESSAGES,
1697 ACTION_OPTIONS,ACTION_RELOAD, ACTION_URL, ACTION_FILE, ACTION_BLANK,
1699 static int NACTION = 27;
1701 static int radiosets [][9] = {
1702 {8,ACTION_FLY,ACTION_WALK,ACTION_EXAMINE,ACTION_EXPLORE,ACTION_SPHERICAL,ACTION_TURNTABLE,ACTION_LOOKAT,ACTION_DIST},
1703 {3,ACTION_MESSAGES,ACTION_OPTIONS,ACTION_HELP},
1709 static int toggles [] = {
1710 ACTION_COLLISION,ACTION_HEADLIGHT,ACTION_SHIFT,ACTION_HOVER,ACTION_PEDAL,
1711 ACTION_HELP,ACTION_MESSAGES,ACTION_OPTIONS,0
1713 static int togglesets [][8] = {{ACTION_FLY,4,ACTION_YAWZ, ACTION_XY, ACTION_YAWPITCH, ACTION_ROLL},{0}};
1715 static int mainbar_linux [] = {
1716 ACTION_WALK, ACTION_FLY, ACTION_EXAMINE,
1717 ACTION_EXPLORE, ACTION_SPHERICAL, ACTION_TURNTABLE, ACTION_LOOKAT, ACTION_DIST,
1718 ACTION_SHIFT, ACTION_HOVER, ACTION_PEDAL, ACTION_LEVEL, ACTION_HEADLIGHT, ACTION_COLLISION, ACTION_PREV,
1719 ACTION_NEXT, ACTION_HELP, ACTION_MESSAGES, ACTION_OPTIONS,
1724 static int *mainbar = NULL;
1726 p->pmenu.nitems = NACTION;
1727 mainbar = mainbar_linux;
1733 p->pmenu.nbitems = i;
1734 }
while(mainbar[i]>-1);
1736 #if defined(QNX) || defined(KIOSK)
1737 p->pmenu.top =
true;
1739 p->pmenu.top =
false;
1747 buttonAtlasSizeCol = 8;
1748 buttonAtlasSizeRow = 4;
1749 buttonAtlasSquared = buttonAtlasSizeCol*buttonAtlasSizeRow;
1750 p->pmenu.lumalpha = MALLOC(GLubyte*, 32*32*2 *buttonAtlasSquared);
1751 memset(p->pmenu.lumalpha,0,32*32*2 *buttonAtlasSquared);
1752 p->pmenu.vert= MALLOC(GLfloat*, 3*4*buttonAtlasSquared*
sizeof(GLfloat));
1754 p->pmenu.ind = MALLOC(GLushort*, 3*2*buttonAtlasSquared*
sizeof(GLushort));
1755 p->pmenu.yoffset = 0;
1756 if(p->pmenu.top) p->pmenu.yoffset = p->vport.H - p->buttonSize;
1757 for(i=0;i<p->pmenu.nitems;i++)
1762 p->pmenu.items[i].action = actionlist[i];
1763 p->pmenu.items[i].help = help_for_action(actionlist[i]);
1764 p->pmenu.items[i].isToggle =
false;
1765 p->pmenu.items[i].buttonset = NULL;
1767 while(toggles[j] > 0)
1769 if(p->pmenu.items[i].action == toggles[j])
1771 p->pmenu.items[i].isToggle =
true;
1776 p->pmenu.items[i].radioset = NULL;
1777 p->pmenu.items[i].isRadio =
false;
1779 while(radiosets[j][0] > 0)
1781 for(k=1;k<=radiosets[j][0];k++)
1782 if(p->pmenu.items[i].action == radiosets[j][k])
1784 p->pmenu.items[i].isRadio =
true;
1785 p->pmenu.items[i].radioset = &radiosets[j][0];
1792 p->pmenu.items[i].height = 32;
1793 p->pmenu.items[i].width = 32;
1794 p->pmenu.items[i].lumalpha = MALLOC(GLubyte*, 32 * 32 * 2);
1799 int ibyte, ibit, color;
1802 ibyte = (j*32 + k)/8;
1803 ibit = (j*32 + k)%8;
1804 color = buttonlist[i][ibyte] & (1<<(7-ibit))? 255 : 0;
1808 color = buttonlist[i][ibyte];
1810 p->pmenu.items[i].lumalpha[(j*32 +k)*2 +0] = color;
1811 p->pmenu.items[i].lumalpha[(j*32 +k)*2 +1] = color;
1815 irow = i / buttonAtlasSizeCol;
1816 icol = i % buttonAtlasSizeCol;
1821 p->pmenu.lumalpha[(irow*32 +j)*32*2*buttonAtlasSizeCol + (icol*32 +k)*2 + 0] = p->pmenu.items[i].lumalpha[(j*32 +k)*2 +0];
1822 p->pmenu.lumalpha[(irow*32 +j)*32*2*buttonAtlasSizeCol + (icol*32 +k)*2 + 1] = p->pmenu.items[i].lumalpha[(j*32 +k)*2 +1];
1826 p->pmenu.items[i].tex0[0][0] = (GLfloat)(icol*32 + 0)/(GLfloat)(32*buttonAtlasSizeCol);
1827 p->pmenu.items[i].tex0[1][0] = (GLfloat)(irow*32 + 0)/(GLfloat)(32*buttonAtlasSizeRow);
1828 p->pmenu.items[i].tex0[0][1] = (GLfloat)(icol*32 +32)/(GLfloat)(32*buttonAtlasSizeCol);
1829 p->pmenu.items[i].tex0[1][1] = (GLfloat)(irow*32 +32)/(GLfloat)(32*buttonAtlasSizeRow);
1843 p->pmenu.items[i].tex[kt +0] = p->pmenu.items[i].tex0[0][j];
1844 p->pmenu.items[i].tex[kt +1] = p->pmenu.items[i].tex0[1][k];
1849 glGenTextures(1, &(p->pmenu.textureID));
1850 glBindTexture(GL_TEXTURE_2D, p->pmenu.textureID);
1851 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
1852 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
1854 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 32*buttonAtlasSizeCol, 32*buttonAtlasSizeRow, 0, GL_LUMINANCE_ALPHA , GL_UNSIGNED_BYTE, p->pmenu.lumalpha);
1860 togset = togglesets[kset];
1862 int k, ipact, nact, iact;
1865 for(k=0;k<p->pmenu.nitems;k++){
1866 if(ipact == p->pmenu.items[k].action){
1868 p->pmenu.items[k].buttonset = malloc(
sizeof(buttonSet));
1869 p->pmenu.items[k].buttonset->n = nact;
1870 p->pmenu.items[k].buttonset->index = 0;
1871 p->pmenu.items[k].buttonset->items = malloc(nact *
sizeof(
void*));
1872 for(m=0;m<nact;m++){
1874 p->pmenu.items[k].buttonset->items[m] = NULL;
1876 for(n=0;n<p->pmenu.nitems;n++){
1877 if(iact == p->pmenu.items[n].action){
1878 p->pmenu.items[k].buttonset->items[m] = &p->pmenu.items[n];
1886 togset = togglesets[kset];
1891 for(i=0;i<p->pmenu.nbitems;i++)
1893 int j, k, mi, mv, kv;
1896 int bz = p->buttonSize;
1899 p->pmenu.bitems[i].butrect[0] = 5+(i*bz);
1900 p->pmenu.bitems[i].butrect[1] = 0;
1901 p->pmenu.bitems[i].butrect[2] = 5+(i*bz)+bz;
1902 p->pmenu.bitems[i].butrect[3] = bz;
1916 xyxy[1].x = (GLfloat)p->buttonSize;
1917 xyxy[1].y = (GLfloat)p->buttonSize;
1918 dx = xyxy[1].x - xyxy[0].x;
1924 p->pmenu.bitems[i].vert[kv +0] = p->pmenu.vert[mv+kv +0] = xyxy[j].x + (GLfloat)(i*dx);
1925 p->pmenu.bitems[i].vert[kv +1] = p->pmenu.vert[mv+kv +1] = xyxy[k].y;
1926 p->pmenu.bitems[i].vert[kv +2] = p->pmenu.vert[mv+kv +2] = 0.0f;
1938 p->pmenu.ind[mi +0] = (GLushort)(i*4) +0;
1939 p->pmenu.ind[mi +1] = (GLushort)(i*4) +1;
1940 p->pmenu.ind[mi +2] = (GLushort)(i*4) +3;
1941 p->pmenu.ind[mi +3] = (GLushort)(i*4) +0;
1942 p->pmenu.ind[mi +4] = (GLushort)(i*4) +3;
1943 p->pmenu.ind[mi +5] = (GLushort)(i*4) +2;
1946 for(j=0;j<p->pmenu.nitems;j++){
1947 if(mainbar[i] == p->pmenu.items[j].action){
1948 p->pmenu.bitems[i].item = &p->pmenu.items[j];
1960 int getMenuItemByAction(
int iaction)
1964 for(i=0;i<p->pmenu.nitems;i++)
1965 if(p->pmenu.items[i].action == iaction)
1970 void setRadioPalsOff(
int *ipals,
int iaction)
1977 for(j=1;j<=ipals[0];j++)
1979 if(ipals[j] != iaction)
1981 i = getMenuItemByAction(ipals[j]);
1983 p->pmenu.items[i].butStatus = 0;
1989 void setMenuButton_collision(
int val){
1992 i = getMenuItemByAction(ACTION_COLLISION);
1994 p->pmenu.items[i].butStatus = val;
1996 void setMenuButton_consoleText(
int val){
1999 i = getMenuItemByAction(ACTION_MESSAGES);
2001 p->pmenu.items[i].butStatus = val;
2003 void setMenuButton_texSize(
int size){
2005 printf(
"text size=%d\n",size);
2008 void setMenuButton_headlight(
int val){
2011 i = getMenuItemByAction(ACTION_HEADLIGHT);
2013 p->pmenu.items[i].butStatus = val;
2015 void setMenuButton_shift(
int val){
2018 i = getMenuItemByAction(ACTION_SHIFT);
2020 p->pmenu.items[i].butStatus = val;
2022 void setMenuButton_hover(
int val){
2025 i = getMenuItemByAction(ACTION_HOVER);
2027 p->pmenu.items[i].butStatus = val;
2029 void setMenuButton_pedal(
int val){
2032 i = getMenuItemByAction(ACTION_PEDAL);
2034 p->pmenu.items[i].butStatus = val;
2036 void setMenuButton_ctrl(
int ctrl){
2042 static int chord2action [] = {ACTION_YAWZ,ACTION_YAWPITCH,ACTION_ROLL,ACTION_XY};
2044 void setMenuButton_navModes(
int type,
int dragchord)
2046 int i, newval, iaction;
2052 iaction = ACTION_EXAMINE;
2055 case VIEWER_EXAMINE:
2056 iaction = ACTION_EXAMINE;
2060 iaction = ACTION_WALK;
2063 case VIEWER_TURNTABLE:
2064 iaction = ACTION_TURNTABLE;
2068 iaction = ACTION_LOOKAT;
2071 case VIEWER_EXPLORE:
2072 iaction = ACTION_EXPLORE;
2075 case VIEWER_SPHERICAL:
2076 iaction = ACTION_SPHERICAL;
2080 iaction = ACTION_DIST;
2084 #if defined(QNX) || defined(KIOSK)//|| defined(_MSC_VER)
2085 iaction = ACTION_FLY2;
2087 iaction = ACTION_FLY;
2095 i = getMenuItemByAction(iaction);
2097 if(p->pmenu.items[i].buttonset){
2099 if(iaction == p->pmenu.items[i].action){
2104 if(p->pmenu.items[i].buttonset){
2105 for(j=0;j<p->pmenu.items[i].buttonset->n;j++){
2106 if(p->pmenu.items[i].buttonset->items[j]->action == chord2action[dragchord]){
2107 p->pmenu.items[i].buttonset->index = j;
2117 if(p->pmenu.items[i].isRadio)
2118 setRadioPalsOff(p->pmenu.items[i].radioset,iaction);
2119 p->pmenu.items[i].butStatus = newval;
2124 int viewer_getDragChord();
2125 void viewer_setDragChord(
int chord);
2128 void updateButtonStatus()
2138 int headlight, collision,
navmode, dragchord, ctrl, shift, hover, pedal, consoletext;
2140 headlight = fwl_get_headlight();
2141 collision = fwl_getCollision();
2142 navmode = fwl_getNavMode();
2143 dragchord = viewer_getDragChord();
2144 shift = fwl_getShift();
2145 hover = fwl_getHover();
2146 pedal = fwl_getPedal();
2147 ctrl = fwl_getCtrl();
2148 consoletext = getShowConsoleText();
2151 setMenuButton_shift(shift);
2152 setMenuButton_hover(hover);
2153 setMenuButton_pedal(pedal);
2154 setMenuButton_ctrl(ctrl);
2155 setMenuButton_navModes(navmode,dragchord);
2156 setMenuButton_headlight(headlight);
2157 setMenuButton_collision(collision);
2158 setMenuButton_consoleText(consoletext);
2162 void updateConsoleStatus()
2167 nlines = fwg_get_unread_message_count();
2168 for (i = 0; i<nlines; i++)
2170 buffer = fwg_get_last_message();
2171 hudSetConsoleMessage(buffer);
2177 int handleButtonOver(
int mouseX,
int mouseY)
2193 y = p->vport.H - mouseY;
2195 y = mouseY - p->pmenu.yoffset;
2199 ihalf = (p->pmenu.nbitems + 1)/p->buttonRows;
2200 for(i=0;i<p->pmenu.nbitems;i++)
2202 int j,xx,yy,butrect[4];
2203 for(j=0;j<4;j++) butrect[j] = p->pmenu.bitems[i].butrect[j];
2207 xx = x + ihalf * p->buttonSize;
2208 yy = y - p->buttonSize;
2210 if(xx > butrect[0] && xx < butrect[2]
2211 && yy > butrect[1] && yy < butrect[3] )
2220 char *frontend_pick_URL(
void);
2221 char *frontend_pick_file(
void);
2222 void toggleMenu(
int val)
2228 p->showButtons = val > 0 ? 1 : 0;
2233 int action2chord(
int iaction){
2234 int ichord = CHORD_YAWZ;
2236 case ACTION_YAWZ: ichord = CHORD_YAWZ;
break;
2237 case ACTION_XY: ichord = CHORD_XY;
break;
2238 case ACTION_YAWPITCH: ichord = CHORD_YAWPITCH;
break;
2239 case ACTION_ROLL: ichord = CHORD_ROLL;
break;
2240 default: ichord = 0;
break;
2245 int handleButtonRelease(
int mouseX,
int mouseY)
2252 int i,x,y,ihit,iaction,ihalf;
2264 y = p->vport.H - mouseY;
2266 y = mouseY - p->pmenu.yoffset;
2267 ihalf = (p->pmenu.nbitems + 1)/p->buttonRows;
2269 for(i=0;i<p->pmenu.nbitems;i++)
2271 int j,xx,yy,butrect[4];
2272 for(j=0;j<4;j++) butrect[j] = p->pmenu.bitems[i].butrect[j];
2276 xx = x + ihalf * p->buttonSize;
2277 yy = y - p->buttonSize;
2279 if(xx > butrect[0] && xx < butrect[2]
2280 && yy > butrect[1] && yy < butrect[3] )
2283 iaction = p->pmenu.bitems[i].item->action;
2284 if(p->pmenu.bitems[i].item->butStatus && p->pmenu.bitems[i].item->buttonset ){
2286 p->pmenu.bitems[i].item->buttonset->index++;
2287 p->pmenu.bitems[i].item->buttonset->index = (p->pmenu.bitems[i].item->buttonset->index % 4);
2289 if(p->pmenu.bitems[i].item->isRadio)
2291 setRadioPalsOff(p->pmenu.bitems[i].item->radioset,iaction);
2292 if(p->pmenu.bitems[i].item->isToggle )
2293 p->pmenu.bitems[i].item->butStatus = 1 - p->pmenu.bitems[i].item->butStatus;
2295 p->pmenu.bitems[i].item->butStatus = 1;
2297 else if(p->pmenu.bitems[i].item->isToggle)
2298 p->pmenu.bitems[i].item->butStatus = 1 - p->pmenu.bitems[i].item->butStatus;
2302 fwl_set_viewer_type (VIEWER_WALK);
break;
2304 fwl_set_viewer_type (VIEWER_FLY2);
break;
2306 fwl_set_viewer_type (VIEWER_TILT);
break;
2308 fwl_set_viewer_type (VIEWER_TPLANE);
break;
2310 fwl_set_viewer_type (VIEWER_RPLANE);
break;
2312 fwl_set_viewer_type(VIEWER_FLY);
2313 if(p->pmenu.bitems[i].item->buttonset){
2314 int iact, idx, ichord;
2315 idx = p->pmenu.bitems[i].item->buttonset->index;
2316 iact = p->pmenu.bitems[i].item->buttonset->items[idx]->action;
2317 ichord = action2chord(iact);
2318 viewer_setDragChord(ichord);
2321 case ACTION_EXPLORE:
2322 fwl_set_viewer_type(VIEWER_EXPLORE);
break;
2324 fwl_set_viewer_type(VIEWER_LOOKAT);
break;
2325 case ACTION_EXAMINE:
2326 fwl_set_viewer_type (VIEWER_EXAMINE);
break;
2327 case ACTION_SPHERICAL:
2328 fwl_set_viewer_type(VIEWER_SPHERICAL);
break;
2329 case ACTION_TURNTABLE:
2330 fwl_set_viewer_type(VIEWER_TURNTABLE);
break;
2332 fwl_set_viewer_type(VIEWER_DIST);
break;
2333 case ACTION_SHIFT: fwl_setShift(p->pmenu.bitems[i].item->butStatus);
break;
2334 case ACTION_HOVER: fwl_setHover(p->pmenu.bitems[i].item->butStatus);
2336 case ACTION_PEDAL: fwl_setPedal(p->pmenu.bitems[i].item->butStatus);
break;
2337 case ACTION_LEVEL: viewer_level_to_bound();
break;
2338 case ACTION_HEADLIGHT: fwl_toggle_headlight();
break;
2339 case ACTION_COLLISION: toggle_collision();
break;
2340 case ACTION_PREV: fwl_Prev_ViewPoint();
break;
2341 case ACTION_NEXT: fwl_Next_ViewPoint();
break;
2344 if(!p->pmenu.bitems[i].item->butStatus)
2346 update_status(NULL);
2349 case ACTION_MESSAGES:
2351 update_status(NULL);
2352 showConsoleText(p->pmenu.bitems[i].item->butStatus);
2354 case ACTION_OPTIONS:
2356 update_status(NULL);
2364 #if defined(_MSC_VER) || defined(QNX)
2366 char *fname = frontend_pick_URL();
2369 fwl_replaceWorldNeeded(fname);
2382 #if defined(_MSC_VER) || defined(QNX)
2384 char *fname = frontend_pick_file();
2387 fwl_replaceWorldNeeded(fname);
2400 return ihit == -1 ? 0 : 1;
2402 void updateButtonVertices()
2404 int i,j,k,kv,mv,ihalf;
2413 if(p->pmenu.top) p->pmenu.yoffset = (p->vport.H - p->buttonSize - p->pmenu.yoffset);
2415 ihalf = (p->pmenu.nbitems + 1)/p->buttonRows;
2416 for(i=0;i<p->pmenu.nbitems;i++)
2418 int button_xoff, button_yoff;
2420 button_yoff = button_xoff = 0;
2423 button_yoff = p->buttonSize;
2424 button_xoff = -(ihalf * p->buttonSize);
2429 xx = p->pmenu.bitems[i].vert[kv +0];
2430 yy = p->pmenu.bitems[i].vert[kv +1];
2431 xy = screen2normalizedScreen(xx + button_xoff,yy + p->pmenu.yoffset + button_yoff + p->side_bottom);
2433 p->pmenu.vert[mv+kv +0] = xy.x;
2434 p->pmenu.vert[mv+kv +1] = xy.y;
2440 void renderButtons()
2451 updateButtonVertices();
2457 glScissor(p->vport.X,p->vport.Y + p->pmenu.yoffset+p->side_bottom,p->vport.W -itrim ,p->buttonSize*p->buttonRows);
2459 glEnable(GL_SCISSOR_TEST);
2461 glClearColor(colorClear[0],colorClear[1],colorClear[2],colorClear[3]);
2463 glClear(GL_COLOR_BUFFER_BIT);
2464 glDisable(GL_SCISSOR_TEST);
2467 glActiveTexture ( GL_TEXTURE0 );
2469 glBindTexture ( GL_TEXTURE_2D, p->pmenu.textureID );
2471 ctrl = fwl_getCtrl();
2472 for(i=0;i<p->pmenu.nbitems;i++)
2475 bool highlightIt = p->pmenu.bitems[i].item->butStatus;
2476 do_ctrl = ctrl && i < 8;
2483 glUniform4f(p->color4fLoc,colorButtonCTRL[0],colorButtonCTRL[1],colorButtonCTRL[2],colorButtonCTRL[3]);
2485 glUniform4f(p->color4fLoc,colorButtonHighlight[0],colorButtonHighlight[1],colorButtonHighlight[2],colorButtonHighlight[3]);
2486 glVertexAttribPointer ( p->positionLoc, 3, GL_FLOAT,
2487 GL_FALSE, 0, &(p->pmenu.vert[i*3*4]) );
2489 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2490 GL_FALSE, 0, p->pmenu.items[p->pmenu.nitems-1].tex );
2491 glEnableVertexAttribArray ( p->positionLoc );
2492 glEnableVertexAttribArray ( p->texCoordLoc );
2493 glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, p->pmenu.ind );
2497 glVertexAttribPointer ( p->positionLoc, 3, GL_FLOAT,
2498 GL_FALSE, 0, &(p->pmenu.vert[i*3*4]) );
2502 if(p->pmenu.bitems[i].item->buttonset){
2504 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2505 GL_FALSE, 0, p->pmenu.bitems[i].item->buttonset->items[p->pmenu.bitems[i].item->buttonset->index]->tex );
2507 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2508 GL_FALSE, 0, p->pmenu.bitems[i].item->tex );
2511 glUniform4f(p->color4fLoc,colorButtonIcon[0],colorButtonIcon[1],colorButtonIcon[2],colorButtonIcon[3]);
2512 glEnableVertexAttribArray ( p->positionLoc );
2513 glEnableVertexAttribArray ( p->texCoordLoc );
2514 glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, p->pmenu.ind );
2533 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
2534 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
2537 void updateViewportSize();
2538 void fwl_getWindowSize(
int *width,
int *height);
2539 void statusbarHud_DrawCursor(GLint textureID,
int x,
int y){
2540 GLfloat cursorVert[] = {
2547 GLfloat cursorTex[] = {
2554 GLushort ind[] = {0,1,2,3,4,5};
2558 int i,j,screenWidth,screenHeight;
2559 GLfloat cursorVert2[18];
2565 FW_GL_DEPTHMASK(GL_FALSE);
2566 glDisable(GL_DEPTH_TEST);
2567 if(p->programObject == 0) initProgramObject();
2568 glUseProgram ( p->programObject );
2571 fwl_getWindowSize(&screenWidth,&screenHeight);
2572 xy = mouse2screen(x,y);
2574 FW_GL_VIEWPORT(0,0,screenWidth,screenHeight);
2576 fxy.x = ((GLfloat)xy.x/(GLfloat)screenWidth * 2.0f);
2577 fxy.y = ((GLfloat)xy.y/(GLfloat)screenHeight * 2.0f);
2585 cursorVert2[i*3 + j] = cursorVert[i*3 +j];
2586 cursorVert2[i*3 +0] += fxy.x;
2587 cursorVert2[i*3 +1] += fxy.y;
2596 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
2597 GL_FALSE, 0, cursorVert2 );
2599 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2600 GL_FALSE, 0, cursorTex );
2601 glUniform4f(p->color4fLoc,0.7f,0.7f,0.9f,1.0f);
2602 glEnableVertexAttribArray (p->positionLoc );
2603 glEnableVertexAttribArray ( p->texCoordLoc);
2606 glActiveTexture ( GL_TEXTURE0 );
2607 glBindTexture ( GL_TEXTURE_2D, textureID );
2610 glUniform1i ( p->textureLoc, 0 );
2611 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_SHORT, ind );
2613 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
2614 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
2617 glEnable(GL_DEPTH_TEST);
2618 FW_GL_DEPTHMASK(GL_TRUE);
2619 restoreGlobalShader();
2622 void updateViewCursorStyle(
int cstyle);
2623 void fwl_set_frontend_using_cursor(
int on);
2626 int item = getMenuItemByAction(action);
2629 return p->pmenu.items[item].butStatus;
2641 y = p->vport.H - mouseY;
2643 y = mouseY - p->pmenu.yoffset;
2644 if( y >= 0 && y <= p->buttonSize * p->buttonRows) isOver = 1;
2652 if(mouseY < p->statusBarSize * p->statusBarRows) isOver = 1;
2684 void updateViewportSize(){
2690 vportstack = (
Stack*)tg->Mainloop._vportstack;
2691 p->vport = stack_top(
ivec4,vportstack);
2693 void updateSBHRows(){
2698 if(p->vport.W < ((p->buttonSize * p->pmenu.nbitems) + 10)){
2700 p->statusBarRows = 1;
2703 p->statusBarRows = 1;
2706 int handleStatusbarHud1(
int mev,
int butnum,
int mouseX,
int mouseY,
int windex)
2717 if ((mev == ButtonPress) || (mev == ButtonRelease) )
2723 if(overMenubar(p,mouseY))
2725 if (mev == ButtonRelease){
2726 ihit = handleButtonRelease(mouseX,mouseYY);
2730 p->menubar_pinned = 1 - p->menubar_pinned;
2731 fwl_get_sbh_pin(&p->statusbar_pinned, &p->menubar_pinned);
2732 p->menubar_pinned = 1 - p->menubar_pinned;
2733 fwl_set_sbh_pin(p->statusbar_pinned, p->menubar_pinned);
2734 if(!p->menubar_pinned)
2737 if(!p->statusbar_pinned && !p->showStatus)
2741 if (mev == ButtonPress){
2742 if (showAction(p, ACTION_HELP)) {
2744 ib_over = handleButtonOver(mouseX, mouseYY);
2746 update_status((
char *)p->pmenu.bitems[ib_over].item->help);
2748 update_status(NULL);
2752 }
else if(overStatusbar(p,mouseY)){
2754 if(mev == ButtonRelease){
2755 if(p->wantButtons && !p->showButtons) toggleMenu(1);
2756 if(p->wantStatusbar && !p->statusbar_pinned ) p->showStatus = 1 - p->showStatus;
2761 if (!ihit && showAction(p, ACTION_OPTIONS))
2763 if (mev == ButtonPress)
2764 ihit = handleOptionPress(mouseX,mouseYY);
2769 if (mev == MotionNotify)
2774 #elif defined(_MSC_VER)
2777 static int lastover;
2778 if (p->vport.H - mouseYY < 16)
2781 toggleMenu(1 - p->showButtons);
2789 if (p->showButtons == 1){
2793 ihit = handleButtonOver(mouseX,mouseYY);
2803 if(overMenubar(p,mouseY) || overStatusbar(p,mouseY))
2805 p->showButtons = p->wantButtons;
2807 if(overMenubar(p,mouseY)){
2809 if(showAction(p, ACTION_HELP)){
2811 ib_over = handleButtonOver(mouseX,mouseYY);
2813 update_status((
char *)p->pmenu.bitems[ib_over].item->help);
2815 update_status(NULL);
2824 p->showButtons = p->menubar_pinned;
2828 if (showAction(p, ACTION_OPTIONS))
2850 int getCursorStyle();
2851 int statusbar_handle_mouse1(
int mev,
int butnum,
int mouseX,
int yup,
int windex)
2853 int vpx, vpy, iret, ihandled;
2856 updateViewportSize();
2860 vpy = yup - p->vport.Y;
2861 vpx = mouseX - p->vport.X;
2862 ihandled = handleStatusbarHud1(mev, butnum, vpx, vpy, windex);
2865 fwl_set_frontend_using_cursor(FALSE);
2867 fwl_set_frontend_using_cursor(TRUE);
2872 int statusbar_handle_mouse(
int mev,
int butnum,
int mouseX,
int mouseY)
2874 return statusbar_handle_mouse1(mev,butnum,mouseX,mouseY,0);
2877 char *getMessageBar();
2878 char *fwl_getKeyChord();
2879 void fwl_setClipPlane(
int height);
2880 int fwl_get_sbh_wantMenubar();
2881 int fwl_get_sbh_wantStatusbar();
2882 void drawStatusBarSide()
2885 void update_pinned(){
2889 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
2890 p->wantButtons = fwl_get_sbh_wantMenubar();
2891 p->wantStatusbar = fwl_get_sbh_wantStatusbar();
2893 void update_density(){
2894 float density_factor;
2899 density_factor = fwl_getDensityFactor();
2900 ifactor = (int)(density_factor + .5f);
2901 ifactor = max(1,ifactor);
2902 p->bmScaleRegular = ifactor;
2903 p->bmScale = ifactor;
2904 p->bmScaleForOptions = ifactor;
2906 p->statusBarSize = p->bmScaleRegular * 16;
2907 p->buttonSize = (int)(density_factor * 32);
2909 int statusbar_getClipPlane(){
2911 int statusbar_height, menubar_height;
2920 statusbar_height = (p->statusbar_pinned && p->wantStatusbar)? p->statusBarSize * p->statusBarRows : 0;
2921 menubar_height = (p->menubar_pinned && p->wantButtons) ? p->buttonSize * p->buttonRows : 0;
2922 vrml_clipplane = statusbar_height + menubar_height;
2923 return vrml_clipplane;
2927 void drawStatusBar()
2955 int i,nsides, menu_over_status;
2956 GLfloat side_bottom_f;
2967 if(!p->fontInitialized) initFont();
2968 if(p->programObject == 0) initProgramObject();
2971 updateViewportSize();
2974 updateButtonStatus();
2975 updateConsoleStatus();
2977 glDepthMask(GL_FALSE);
2978 glDisable(GL_DEPTH_TEST);
2980 glUseProgram ( p->programObject );
2981 glViewport(p->vport.X, p->vport.Y, p->vport.W, p->vport.H);
2983 p->show_menu = p->wantButtons && (p->menubar_pinned || p->showButtons);
2984 menu_over_status = !p->menubar_pinned && p->showButtons;
2985 p->show_status = p->wantStatusbar && ((p->showStatus || p->statusbar_pinned) && !menu_over_status);
2986 p->show_status = p->show_status || showAction(p, ACTION_HELP);
2992 p->pmenu.yoffset = p->show_status ? p->statusBarSize * p->statusBarRows : 0;
2995 p->clipPlane = (p->show_menu ? p->buttonSize * p->buttonRows : 0) + p->show_status ? p->statusBarSize * p->statusBarRows : 0;
3004 if (Viewer()->updown) nsides = 2;
3005 for (i = 0; i < nsides; i++)
3009 side_bottom_f = -1.0f;
3010 if (Viewer()->updown){
3012 p->side_top = i*(p->vport.H / 2);
3013 p->side_bottom = (1 -i) *(p->vport.H /2);
3014 if(i == 0) side_bottom_f = 0.0f;
3021 glDepthMask(GL_TRUE);
3022 if (p->posType == 1) {
3023 glEnable(GL_DEPTH_TEST);
3030 int sblen, sslen,itrim;
3039 glScissor(p->vport.X, p->vport.Y + p->side_bottom, p->vport.W -itrim, p->statusBarSize * p->statusBarRows);
3040 glEnable(GL_SCISSOR_TEST);
3042 glClearColor(colorClear[0],colorClear[1],colorClear[2],colorClear[3]);
3043 glClear(GL_COLOR_BUFFER_BIT);
3044 glDisable(GL_SCISSOR_TEST);
3048 glDisable(GL_DEPTH_TEST);
3051 glUniform4f(p->color4fLoc,colorStatusbarText[0],colorStatusbarText[1],colorStatusbarText[2],colorStatusbarText[3]);
3052 xy = screen2normalizedScreenScale((GLfloat)p->bmWH.x, (GLfloat)p->bmWH.y);
3055 sblen = (int)(2.0f/xy.x);
3063 printString2(-1.0f, side_bottom_f, pp);
3067 int len, istart,istart1,ilen,lenk,lenkk;
3068 char *strfps, *strdist, *strstatus, *strAkeys;
3071 strAkeys = fwl_getKeyChord();
3072 lenkk = lenk = strlen(strAkeys);
3074 strstatus = getMenuStatus();
3075 len = strlen(strstatus);
3079 if(max(istart1,35) + len + 9 < sblen) {
3081 istart = max(istart1,35);
3082 }
else if(istart1 + len + 9 < sblen){
3085 }
else if(istart1 + len + lenkk < sblen){
3088 }
else if(p->buttonRows == 2){
3091 ilen = sblen - istart;
3095 ilen = sblen - istart - lenkk;
3100 printString3(-1.0f + xy.x*istart, side_bottom_f, strstatus,ilen);
3104 printString3(1.0f - xy.x*(lenk + 4), side_bottom_f, strAkeys,lenk);
3107 strfps = getFpsBar();
3108 printString2(1.0f - xy.x*(4), side_bottom_f, strfps);
3109 strdist = getDistBar();
3110 printString2(1.0f - xy.x*(22), side_bottom_f, strdist);
3116 glUniform4f(p->color4fLoc,colorMessageText[0],colorMessageText[1],colorMessageText[2],colorMessageText[3]);
3118 if (showAction(p, ACTION_HELP))
3119 printKeyboardHelp(p);
3120 if (showAction(p, ACTION_MESSAGES))
3122 if (showAction(p, ACTION_OPTIONS))
3127 glEnable(GL_DEPTH_TEST);
3130 #else //ifdef STATUSBAR_HUD
3132 int statusbar_getClipPlane(){
3135 int statusbar_handle_mouse1(
int mev,
int butnum,
int mouseX,
int yup,
int windex){