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)
48static GLfloat colorButtonHighlight[4] = {.5f,.5f,.5f,.5f};
49static GLfloat colorButtonCTRL[4] = {.6f,.6f,.6f,.5f};
51static GLfloat colorClear[4] = {0.24f,0.27f,0.34f,1.0f};
52#define LIME {.8f,1.0f,0.0f,1.0f}
56static GLfloat colorButtonIcon[4] = HIGHLIGHT;
57static GLfloat colorStatusbarText[4] = HIGHLIGHT;
58static GLfloat colorMessageText[4] = HIGHLIGHT;
60static int ui_color_changed = -1;
62void 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;
73static 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"
84static GLbyte fShaderStr[] =
85#ifdef GL_ES_VERSION_2_0
86 "precision mediump float; \n"
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"
97GLuint 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 );
140GLuint 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"
219GLubyte 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];
339typedef struct _buttonSet buttonSet;
355 buttonSet *buttonset;
361 pmenuItem_t ** items;
396typedef struct {
int x;
int y;}
XY;
402static ivec4 defaultViewport = {0,0,400,400};
413 int statusbar_pinned;
433 struct Uni_String *myline;
435 char messagebar[200];
438 char * optionsVal[LENOPTIONS];
442 int bmScaleForOptions;
449 GLuint programObject;
457 GLfloat textColor[4];
462 int side_top, side_bottom;
464void *statusbar_constructor(){
469void statusbar_init(
struct tstatusbar *t){
472 t->prv = statusbar_constructor();
475 ppstatusbar p = (ppstatusbar)t->prv;
478 p->wantStatusbar = 1;
479 p->wantButtons = p->wantStatusbar;
481 p->showStatus = p->wantStatusbar;
492 p->fontInitialized = 0;
495 p->optionsLoaded = 0;
500 p->bmScaleForOptions = 2;
502 p->bmScaleForOptions = 1;
504 p->bmScaleRegular = 1;
506 p->bmScaleRegular = 2;
507 p->bmScaleForOptions = 2;
509 p->bmScale = p->bmScaleRegular;
510 p->statusBarSize = p->bmScaleRegular * 16;
511 p->statusBarRows = 1;
513 p->pfont.cheight = 0;
515 p->pfont.lumalpha = NULL;
516 p->pmenu.items = MALLOC(pmenuItem_t *, MAXBUT *
sizeof(pmenuItem_t));
517 for(i=0;i<MAXBUT;i++) p->pmenu.items[i].butStatus = 0;
518 p->pmenu.bitems = (barItem *)malloc(MAXBUT *
sizeof(barItem));
519 bzero(p->pmenu.bitems,MAXBUT *
sizeof(barItem));
522 p->buttonSize = BUTSIZE;
524 p->textColor[3] = 1.0f;
527 p->vport = defaultViewport;
528 p->clipPlane = p->statusBarSize;
534static void init_ProgramObject(){
535 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
538 p->programObject = esLoadProgram ( (
const char*) vShaderStr, (
const char *)fShaderStr );
540 p->positionLoc = glGetAttribLocation ( p->programObject,
"a_position" );
541 p->texCoordLoc = glGetAttribLocation ( p->programObject,
"a_texCoord" );
543 p->textureLoc = glGetUniformLocation ( p->programObject,
"Texture0" );
544 p->color4fLoc = glGetUniformLocation ( p->programObject,
"Color4f" );
546static int lenOptions = 35;
548void statusbar_clear(
struct tstatusbar *t){
552 ppstatusbar p = (ppstatusbar)t->prv;
554 glDeleteTextures(1, &(p->pfont.textureID));
555 glDeleteTextures(1, &(p->pmenu.textureID));
557 ml_delete_all(p->conlist);
559 for(i=0;i<lenOptions;i++)
562 FREE_IF_NZ(p->optionsVal[i]);
565 for(i=0;i<p->pmenu.nitems;i++)
566 FREE_IF_NZ(p->pmenu.items[i].lumalpha);
567 FREE_IF_NZ(p->pmenu.lumalpha);
568 FREE_IF_NZ(p->pmenu.items);
569 FREE_IF_NZ(p->pmenu.vert);
570 FREE_IF_NZ(p->pmenu.ind);
571 FREE_IF_NZ(p->pfont.lumalpha);
574void fwMakeRasterFonts()
576 int i,j,k,m,w,h,bytewidth,bit;
578 int ichar,isize, irow, icol, irowheight,icolwidth, iwidth, iheight;
580 GLubyte *cdata, *row;
583 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
587 p->pfont.cheight = 15;
595 height = (float)iheight;
596 width = (float)iwidth;
599 isize = iheight * iwidth * 2;
601 p->pfont.lumalpha = MALLOC(GLubyte *, isize);
603 memset(p->pfont.lumalpha,0,isize);
604 white[0] = white[1] = (GLubyte)255;
607 p->pfont.have[m] = 0;
611 ichar = fwLetters8x15[m][0];
612 if(ichar == 255)
break;
613 p->pfont.have[ichar] = 1;
614 cdata = &fwLetters8x15[m][7];
615 w = fwLetters8x15[m][1];
616 h = fwLetters8x15[m][2];
620 p->pfont.tex[0][0][ichar] = (GLfloat)(icol * icolwidth);
621 p->pfont.tex[1][0][ichar] = (GLfloat)(irow * irowheight);
622 p->pfont.tex[0][1][ichar] = p->pfont.tex[0][0][ichar] + p->pfont.cwidth;
623 p->pfont.tex[1][1][ichar] = p->pfont.tex[1][0][ichar] + p->pfont.cheight;
624 p->pfont.owh[0][0][ichar] = p->pfont.owh[1][0][ichar] = 0.0f;
625 p->pfont.owh[0][1][ichar] = (GLfloat)p->pfont.cwidth;
626 p->pfont.owh[1][1][ichar] = (GLfloat)p->pfont.cheight;
629 p->pfont.tex[0][j][ichar] /= width;
630 p->pfont.tex[1][j][ichar] /= height;
632 bytewidth = ((w-1)/8 +1);
635 row = &cdata[j*bytewidth];
640 bit = row[k] & (1<<((bytewidth*8)-i-1))? 1 : 0;
645 ip = (irow*irowheight +j)*iwidth;
646 ip += icol*icolwidth + i;
647 memcpy(&p->pfont.lumalpha[ip*2],white,2);
656 fp = fopen(
"hud_junk_0.txt",
"w+");
657 fprintf(fp,
"char data\n");
660 ichar = fwLetters8x15[m][0];
661 if(ichar == 255)
break;
662 fprintf(fp,
"%c %d ",(
char)ichar,ichar);
663 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]);
664 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]);
670 glGenTextures(1, &(p->pfont.textureID));
672 glBindTexture(GL_TEXTURE_2D, p->pfont.textureID);
674 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
675 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
677 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, iwidth, iheight, 0, GL_LUMINANCE_ALPHA , GL_UNSIGNED_BYTE, p->pfont.lumalpha);
687 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
690 p->fontInitialized = 1;
694void printString(
char *s){}
695FXY screen2normalizedScreen( GLfloat x, GLfloat y);
696FXY screen2normalizedScreenScale( GLfloat x, GLfloat y);
705void printString3_old(GLfloat sx, GLfloat sy,
char *s,
int len)
713 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
718 int sizeoftex, sizeofvert, sizeofind;
725 sizeofvert = len1 *
sizeof(GLfloat) * 4 * 3;
726 sizeoftex = len1 *
sizeof(GLfloat) * 4 * 2;
727 sizeofind = len1 *
sizeof(GLuint) * 2 * 3;
728 vert = (GLfloat*)alloca(sizeofvert);
729 tex = (GLfloat*)alloca(sizeoftex);
730 ind = (GLuint*)alloca(sizeofind);
740 if (ichar ==
'\t') ichar =
' ';
741 if(p->pfont.have[ichar])
743 charScreenSize = screen2normalizedScreenScale(p->pfont.owh[0][1][ichar]*p->bmScale,p->pfont.owh[1][1][ichar]*p->bmScale);
748 vert[i*4*3 +4] = y + charScreenSize.y;
750 vert[i*4*3 +6] = x + charScreenSize.x;
751 vert[i*4*3 +7] = y + charScreenSize.y;
753 vert[i*4*3 +9] = x + charScreenSize.x;
756 x = x + charScreenSize.x;
757 tex[i*4*2 +0] = p->pfont.tex[0][0][ichar];
758 tex[i*4*2 +1] = p->pfont.tex[1][0][ichar];
759 tex[i*4*2 +2] = p->pfont.tex[0][0][ichar];
760 tex[i*4*2 +3] = p->pfont.tex[1][1][ichar];
761 tex[i*4*2 +4] = p->pfont.tex[0][1][ichar];
762 tex[i*4*2 +5] = p->pfont.tex[1][1][ichar];
763 tex[i*4*2 +6] = p->pfont.tex[0][1][ichar];
764 tex[i*4*2 +7] = p->pfont.tex[1][0][ichar];
765 ind[i*3*2 +0] = i*4 + 0;
766 ind[i*3*2 +1] = i*4 + 1;
767 ind[i*3*2 +2] = i*4 + 2;
768 ind[i*3*2 +3] = i*4 + 2;
769 ind[i*3*2 +4] = i*4 + 3;
770 ind[i*3*2 +5] = i*4 + 0;
776 glActiveTexture ( GL_TEXTURE0 );
777 glBindTexture ( GL_TEXTURE_2D, p->pfont.textureID );
779 glVertexAttribPointer ( p->positionLoc, 3, GL_FLOAT,
782 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
785 glEnableVertexAttribArray ( p->positionLoc );
786 glEnableVertexAttribArray ( p->texCoordLoc );
788 glUniform1i ( p->textureLoc, 0 );
789 glDrawElements ( GL_TRIANGLES, i*3*2, GL_UNSIGNED_INT, ind );
802void printString3(GLfloat sx, GLfloat sy,
char *s,
int len)
811 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
816 int sizeoftex, sizeofvert, sizeofind;
822 glActiveTexture ( GL_TEXTURE0 );
823 glBindTexture ( GL_TEXTURE_2D, p->pfont.textureID );
825 glUniform1i ( p->textureLoc, 0 );
827 glEnableVertexAttribArray ( p->positionLoc );
828 glEnableVertexAttribArray ( p->texCoordLoc );
839 if (ichar ==
'\t') ichar =
' ';
840 if(p->pfont.have[ichar])
842 charScreenSize = screen2normalizedScreenScale(p->pfont.owh[0][1][ichar]*p->bmScale,p->pfont.owh[1][1][ichar]*p->bmScale);
847 vert[4] = y + charScreenSize.y;
849 vert[6] = x + charScreenSize.x;
850 vert[7] = y + charScreenSize.y;
852 vert[9] = x + charScreenSize.x;
855 x = x + charScreenSize.x;
856 tex[0] = p->pfont.tex[0][0][ichar];
857 tex[1] = p->pfont.tex[1][0][ichar];
858 tex[2] = p->pfont.tex[0][0][ichar];
859 tex[3] = p->pfont.tex[1][1][ichar];
860 tex[4] = p->pfont.tex[0][1][ichar];
861 tex[5] = p->pfont.tex[1][1][ichar];
862 tex[6] = p->pfont.tex[0][1][ichar];
863 tex[7] = p->pfont.tex[1][0][ichar];
873 glVertexAttribPointer ( p->positionLoc, 3, GL_FLOAT,
876 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
879 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_INT, ind );
888void printString2(GLfloat sx, GLfloat sy,
char *s){
889 printString3(sx,sy,s,strlen(s));
891void render_init(
void);
922char * optionsText[] = {
931"Eyebase - object space",
933"Your Eyebase = fiducials",
945" mouse emulate-multitouch multitouch gesture",
948"screen orientation \36 \37",
950" flat gouraud phong wire",
951" draw bounding boxes",
953"depth slices auto 1 2 3",
955"texture modulate or replace mat.diffuse:",
956" by file_version v3.3- replace v4.0+ modulate",
967char *colorschemenames [] = {
979void fwl_setPickraySide(
int ipreferredSide,
int either);
980void fwl_getPickraySide(
int *ipreferredSide,
int *either);
981int fwl_getOrientation();
982int fwl_getOrientation2();
983void fwl_setOrientation2(
int degrees);
984int fwl_getShadingStyle();
988 int i,j,k,m, iside, ieither, shadingStyle;
990 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
993 for(i=0;i<lenOptions;i++)
995 if(!p->optionsVal[i])
996 p->optionsVal[i] = MALLOC(
char*, 55);
997 for(j=0;j<48;j++) p->optionsVal[i][j] =
' ';
998 p->optionsVal[i][47] =
'\0';
1000 p->optionsVal[1][0] = 034;
1001 p->optionsVal[2][0] = 034;
1002 p->optionsVal[3][0] = 034;
1003 p->optionsVal[4][0] = 034;
1004 p->optionsVal[5][0] = 034;
1005 p->optionsVal[6][0] = 034;
1006 p->optionsVal[7][0] = 034;
1009 p->optionsVal[1][0] = 035;
1011 p->optionsVal[2][0] = 035;
1013 p->optionsVal[3][0] = 035;
1015 p->optionsVal[4][0] = 035;
1016 if(
viewer->shutterGlasses)
1017 p->optionsVal[5][0] = 035;
1019 p->optionsVal[6][0] = 035;
1021 p->optionsVal[7][0] = 035;
1022 sprintf(p->optionsVal[9],
" %4.3f",
viewer->eyedist);
1023 sprintf(p->optionsVal[11],
" %4.3f",
viewer->screendist);
1027 k = getAnaglyphPrimarySide(j,i);
1028 p->optionsVal[14+i][j+1] = (k ? 035 :
' ');
1031 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
1032 p->optionsVal[17][0] = p->statusbar_pinned ? 035 : 034;
1033 p->optionsVal[18][0] = p->menubar_pinned ? 035 : 034;
1034 sprintf(p->optionsVal[20],
" %s ",fwl_get_ui_colorschemename());
1035 sprintf(p->optionsVal[21],
" %4d",abs(fwl_get_target_fps()));
1038 p->optionsVal[22][0] = p->optionsVal[22][8] = p->optionsVal[22][29] = p->optionsVal[22][42] = 034;
1039 switch(fwl_get_touchtype()){
1040 case 0: p->optionsVal[22][0] = 035;
break;
1041 case 1: p->optionsVal[22][8] = 035;
break;
1042 case 2: p->optionsVal[22][29] = 035;
break;
1043 case 3: p->optionsVal[22][42] = 035;
break;
1046 fwl_getPickraySide(&iside,&ieither);
1047 p->optionsVal[24][1] = p->optionsVal[24][7] = p->optionsVal[24][14] = 034;
1048 if(iside==0) p->optionsVal[24][1] = 035;
1049 else p->optionsVal[24][7] = 035;
1050 if(ieither) p->optionsVal[24][14] = 035;
1051 sprintf(p->optionsVal[25],
" %4d",fwl_getOrientation2());
1052 shadingStyle = fwl_getShadingStyle();
1053 p->optionsVal[27][1] = p->optionsVal[27][7] = p->optionsVal[27][16] = p->optionsVal[27][23] =034;
1054 switch(shadingStyle){
1055 case 0: p->optionsVal[27][1] = 035;
break;
1056 case 1: p->optionsVal[27][7] = 035;
break;
1057 case 2: p->optionsVal[27][16] = 035;
break;
1058 case 3: p->optionsVal[27][23] = 035;
break;
1062 p->optionsVal[28][0] = 034;
1063 if(fwl_getDrawBoundingBoxes())
1064 p->optionsVal[28][0] = 035;
1065 p->optionsVal[29][0] = 034;
1066 if(fwl_getShowViewpoints())
1067 p->optionsVal[29][0] = 035;
1068 m = fwl_get_depth_slices();
1069 p->optionsVal[30][13] = p->optionsVal[30][19] = p->optionsVal[30][23] = p->optionsVal[30][27] =034;
1072 case 0: p->optionsVal[30][13] = 035;
break;
1073 case 1: p->optionsVal[30][19] = 035;
break;
1074 case 2: p->optionsVal[30][23] = 035;
break;
1075 case 3: p->optionsVal[30][27] = 035;
break;
1077 p->optionsVal[31][0] = 034;
1078 if(fwl_get_allow_DIS())
1079 p->optionsVal[31][0] = 035;
1080 m = fwl_get_modulation();
1084 p->optionsVal[33][0] = p->optionsVal[33][19] = p->optionsVal[33][35] =034;
1086 case 0: p->optionsVal[33][0] = 035;
break;
1087 case 1: p->optionsVal[33][19] = 035;
break;
1088 case 2: p->optionsVal[33][35] = 035;
break;
1090 p->optionsVal[34][0] = 034;
1091 if (fwl_getDrawRig())
1092 p->optionsVal[34][0] = 035;
1094 p->optionsLoaded = 1;
1096void updateOptionsVal()
1103char * optionsCase[] = {
1126"hhhhhh iiiiiiiiiiiiiiiiiii jjjjjjjjjjj kkkkkkkkkk",
1137"eeeee ffffffff ggggggg",
1142XY mouse2screen(
int x,
int y)
1150XY screen2text(
int x,
int y)
1155 ttglobal tg = gglobal();
1156 p = (ppstatusbar)tg->statusbar.prv;
1158 topOffset = p->side_top;
1159 if(p->pmenu.top) topOffset += p->buttonSize;
1160 rc.x = x/(p->bmWH.x*p->bmScale) -1;
1161 rc.y = (int)((p->vport.H -y - topOffset)/(p->bmWH.y*p->bmScale)) +1;
1165XY text2screen(
int col,
int row)
1170 ttglobal tg = gglobal();
1171 p = (ppstatusbar)tg->statusbar.prv;
1172 topOffset = p->side_top;
1173 if(p->pmenu.top) topOffset += p->buttonSize;
1174 xy.x = (col+1)*p->bmWH.x*p->bmScale;
1175 xy.y = p->vport.H - topOffset - (row+1)*p->bmWH.y*p->bmScale;
1178FXY screen2normalizedScreenScale( GLfloat x, GLfloat y)
1181 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
1184 xy.x = ((GLfloat)x/(GLfloat)p->vport.W * 2.0f);
1185 xy.y = ((GLfloat)y/(GLfloat)p->vport.H * 2.0f);
1188FXY screen2normalizedScreen( GLfloat x, GLfloat y)
1192 xy = screen2normalizedScreenScale(x,y);
1200 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
1203 if(!p->optionsLoaded) initOptionsVal();
1206 p->bmScale = p->bmScaleForOptions;
1207 for(j=0;j<lenOptions;j++)
1210 XY xy0 = text2screen(0,j);
1211 xy = screen2normalizedScreen( (GLfloat)xy0.x, (GLfloat)xy0.y);
1212 printString2(xy.x,xy.y,p->optionsVal[j]);
1213 printString2(xy.x,xy.y,optionsText[j]);
1215 p->bmScale = p->bmScaleRegular;
1218int handleOptionPress(
int mouseX,
int mouseY)
1228 ttglobal tg = gglobal();
1229 p = (ppstatusbar)tg->statusbar.prv;
1233 p->bmScale = p->bmScaleForOptions;
1234 xys = mouse2screen(mouseX,mouseY);
1236 if (Viewer()->updown) p->side_top = p->vport.H / 2;
1237 xyt = screen2text(xys.x,xys.y);
1239 if( 0 <= xyt.y && xyt.y < lenOptions )
1241 int len = (int) strlen(optionsCase[xyt.y]);
1245 opt = optionsCase[xyt.y][xyt.x];
1248 if(opt ==
' ')
return 0;
1249 p->bmScale = p->bmScaleRegular;
1257 printf(
"toggle EAI");
1267 toggleOrSetStereo(opt-
'0');
1270 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
1271 p->statusbar_pinned = 1 - p->statusbar_pinned;
1272 fwl_set_sbh_pin(p->statusbar_pinned,p->menubar_pinned);
1275 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
1276 p->menubar_pinned = 1 - p->menubar_pinned;
1277 fwl_set_sbh_pin(p->statusbar_pinned,p->menubar_pinned);
1280 fwl_next_ui_colorscheme();
1285 setAnaglyphPrimarySide(opt-
'r',0);
1290 setAnaglyphPrimarySide(opt-
'u',1);
1295 setAnaglyphPrimarySide(opt-
'x',2);
1300 printf(
"reduce eyebase");
1306 printf(
"increase eyebase");
1312 printf(
"reduce screendist");
1313 viewer->screendist -= .02;
1316 case 'h': fwl_set_touchtype(0);
break;
1317 case 'i': fwl_set_touchtype(1);
break;
1318 case 'j': fwl_set_touchtype(2);
break;
1319 case 'k': fwl_set_touchtype(3);
break;
1322 printf(
"set screendist");
1326 printf(
"increase screendist");
1327 viewer->screendist += .02;
1334 printf(
"reduce toe-in");
1335 viewer->stereoParameter *= .9;
1340 printf(
"set toe-in");
1344 printf(
"increase toe-in");
1345 viewer->stereoParameter *= 1.1;
1347 viewer->stereoParameter = min(
viewer->stereoParameter,.01);
1355 tfps = abs(fwl_get_target_fps());
1356 i15 = (int)((
double)tfps / 15.0 + .5);
1357 if(opt ==
'K') i15 /= 2;
1358 if(opt ==
'L') i15 = max(1,i15*2);
1359 if(i15 < 1) tfps = 7;
1360 else tfps = min(3840,(
int)15*i15);
1361 fwl_set_target_fps(tfps);
1368 fwl_getPickraySide(&iside,&ieither);
1370 ieither = 1 - ieither;
1374 fwl_setPickraySide(iside,ieither);
1378 fwl_setOrientation2((fwl_getOrientation2()+90) % 360);
1381 fwl_setOrientation2( (fwl_getOrientation2() + 360 -90) % 360);
1389 shadingStyle = opt -
'R';
1390 fwl_setShadingStyle(shadingStyle);
1394 fwl_setDrawBoundingBoxes(1 - fwl_getDrawBoundingBoxes());
1398 fwl_setShowViewpoints(1 - fwl_getShowViewpoints());
1406 fwl_set_depth_slices(opt -
'a');
1410 fwl_set_allow_DIS(1 - fwl_get_allow_DIS());
1417 fwl_set_modulation(opt -
'e');
1421 fwl_setDrawRig(1 - fwl_getDrawRig());
1437char * keyboardShortcutHelp[] = {
1439" movement: drag left/right for turns;",
1440" drag up/down for forward/backward",
1442" use the buttons for these motions:",
1443" bird: drag left/right for left/right turns",
1444" drag up/down for foreward/backward",
1446" translation up/down and left/right",
1447" rotation about the viewpoint/camera axis",
1449" rotation: drag left/right or up/down",
1450"Level to bound viewpoint",
1451"Flashlight/headlight",
1452"Collision (and for WALK also gravity)",
1453"Previous, Next viewpoint",
1455"Console messages from the program",
1458"Enter URL of .x3d or .wrl scene"
1461char * keyboardShortcutHelp[] = {
1463" movement: drag left/right for turns;",
1464" drag up/down for forward/backward",
1466" use the buttons for these motions:",
1467" bird: drag left/right for left/right turns",
1468" drag up/down for foreward/backward",
1470" translation up/down and left/right",
1471" rotation about the viewpoint/camera axis",
1473" rotation: drag left/right or up/down",
1474"Level to bound viewpoint",
1475"Flashlight/headlight",
1476"Collision (and for WALK also gravity)",
1477"Previous, Next viewpoint",
1479"Console messages from the program",
1483#elif defined(_MSC_VER_NOT)
1485char * keyboardShortcutHelp[] = {
1487" movement: drag left/right for turns;",
1488" drag up/down for forward/backward",
1490" use the keyboard for these motions:",
1491" 8 k rotation down/up",
1492" u o rotation left/right",
1493" 7 9 rotation about the Z axis",
1494" a z translation forwards/backwards",
1495" j l translation left/right",
1496" p ; translation up/down",
1497" or use arrow keys. to change keychord: press SHIFT->",
1499" rotation: drag left/right or up/down",
1500"EXPLORE Mode - use CTRL-click to recenter",
1501"hit spacebar to get console prompt :, then type help"
1504#elif defined(OLD_HELP)
1506char * keyboardShortcutHelp[] = {
1508" LMB rotation: MX rotation around Y axis; MY rotation around X axis",
1511" LMB movement: MX left/right turns; MY walk forward/backward",
1514" - use CTRL-click to recenter",
1515"Keyboard navigation",
1516" - use arrow keys. to change keychord: press SHIFT> or SHIFT<",
1518" e Switch to Examine navigation mode",
1519" w Switch to Walk navigation mode",
1520" v Go to next viewpoint in the scene",
1521" b Go to previous viewpoint in the scene",
1522" / Print current viewport local pose",
1523" h Toggle headlight",
1524" c Toggle collision detection",
1531char * keyboardShortcutHelp[] = {
1534"Keyboard Viewpoint change:",
1535" PgDn,PgUp,Home,End = Next,Prev,First,Last",
1536"Keyboard commands:",
1537" / Print current viewpoint pose",
1540"Keyboard navigation:",
1542" to change keychord: press SHIFT> or SHIFT<",
1543"Touch cursor control:",
1544" use both PEDAL % and HOVER ^ buttons to move cursor",
1545" use PEDAL % button to drag cursor around",
1550const char *libFreeWRL_get_version();
1551void printKeyboardHelp(ppstatusbar p)
1555 FXY fxy, fxy2, fxy3;
1556 GLfloat side_bottom_f;
1560 static const char *versionInfo =
"libfreeWRL version ";
1561 xy = text2screen(0,0);
1562 fxy = screen2normalizedScreen((GLfloat)xy.x,(GLfloat)xy.y);
1563 printString2(fxy.x,fxy.y,(
char *)versionInfo);
1564 xy = text2screen((
int)strlen(versionInfo),0);
1565 fxy = screen2normalizedScreen((GLfloat)xy.x,(GLfloat)xy.y);
1566 printString2(fxy.x,fxy.y,(
char*)libFreeWRL_get_version());
1570 fxy2 = screen2normalizedScreenScale((GLfloat)p->bmWH.x, (GLfloat)p->bmWH.y);
1571 fxy2.y *= p->bmScale;
1572 side_bottom_f = -1.0f;
1573 fxy3 = screen2normalizedScreenScale((GLfloat)0, (GLfloat)p->buttonRows * p->buttonSize);
1574 side_bottom_f += fxy3.y;
1577 while(keyboardShortcutHelp[j] != NULL)
1581 printString2(-1.0f, side_bottom_f + (lenhelp-j)*fxy2.y, keyboardShortcutHelp[j]);
1583 if(p->show_status && j > lenhelp)
break;
1587void hudSetConsoleMessage(
char *buffer)
1593 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
1605 last = ml_new(buffer);
1609 ml_append(p->conlist,last);
1611 if( p->concount > 50 )
1614 free((
char*)p->conlist->elem);
1615 p->conlist = ml_delete_self(p->conlist, p->conlist);
1620void printConsoleText()
1626 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
1632 s_list_t *_list = p->conlist;
1634 xybottom = screen2text(0,p->side_bottom);
1635 jstart = max(0,p->concount-(xybottom.y - 3));
1636 for(__l=_list;__l!=NULL;)
1638 next = ml_next(__l);
1642 XY xy = text2screen(0,j-jstart);
1643 fxy = screen2normalizedScreen((GLfloat)xy.x,(GLfloat)xy.y);
1644 printString2(fxy.x,fxy.y,__l->elem);
1691} button_helps [] = {
1692{ACTION_WALK,
"WALK"},
1697{ACTION_FLY,
"FLY {yaw-z,xy,yaw-pitch,roll}"},
1698{ACTION_EXAMINE,
"EXAMINE"},
1699{ACTION_EXPLORE,
"EXPLORE {examine,recenter}"},
1700{ACTION_SPHERICAL,
"SPHERICAL {pan,zoom}"},
1701{ACTION_TURNTABLE,
"TURNTABLE"},
1702{ACTION_LOOKAT,
"LOOKAT"},
1704{ACTION_YAWZ,
"FLY yaw-z"},
1705{ACTION_YAWPITCH,
"FLY yaw-pitch"},
1706{ACTION_ROLL,
"FLY roll"},
1707{ACTION_XY,
"FLY xy"},
1708{ACTION_DIST,
"DIST (for examine,explore,turntable)"},
1709{ACTION_SHIFT,
"SHIFT Key (turns off sensors)"},
1710{ACTION_HOVER,
"HOVER up-drag isOver mode"},
1711{ACTION_PEDAL,
"PEDAL drags in-scene cursor"},
1712{ACTION_LEVEL,
"LEVEL to bound VP (ViewPoint)"},
1713{ACTION_HEADLIGHT,
"HEADLIGHT"},
1714{ACTION_COLLISION,
"COLLISION (and gravity)"},
1715{ACTION_PREV,
"Prev VP"},
1716{ACTION_NEXT,
"Next VP"},
1717{ACTION_HELP,
"Help"},
1718{ACTION_MESSAGES,
"Console"},
1719{ACTION_OPTIONS,
"Options"},
1720{ACTION_RELOAD,
"Reload"},
1722{ACTION_FILE,
"FILE"},
1723{ACTION_VIEWALL,
"VIEWALL"},
1724{ACTION_BLANK, NULL},
1726const char *help_for_action(
int action){
1728 struct button_help *bh;
1731 bh = &button_helps[i];
1732 if(bh->action == action)
break;
1734 }
while(bh->action != ACTION_BLANK);
1738void convertPng2hexAlpha()
1753 static int mbuts = 1;
1754 static char * butFnames[] = {
"pan.png"};
1755 textureTableIndexStruct_s butts;
1757 FILE* out = fopen(
"hudIcons_octalpha_h",
"w+");
1765 for(ii=0;ii<mbuts;ii++)
1767 int j,k,l,g,rgbmax[3];
1768 texture_load_from_file(&butts, butFnames[ii]);
1774 for(j=0;j<3;j++) rgbmax[j] = 0;
1775 for(j=0;j<butts.x;j++)
1777 for(k=0;k<butts.y;k++)
1781 g = butts.texdata[j*w*4 + k*4 + l];
1782 rgbmax[l] = g > rgbmax[l] ? g : rgbmax[l];
1787 for(j=0;j<butts.x;j++)
1789 for(k=0;k<butts.y;k++)
1796 h = butts.texdata[j*w*4 + k*4 + l];
1797 h = (int)((
float)h/(
float)rgbmax[l]*255.0f);
1802 g = g > 255? 255 : g;
1804 butts.texdata[j*w*4 + k*4 + l] = g;
1811 strcpy(butname,butFnames[ii]);
1812 for(j=0;j<(int)strlen(butname);j++)
1813 if(butname[j] ==
'.') {butname[j] =
'\0';
break;}
1814 fprintf(out,
"GLubyte %s[] = {\n",butname);
1821 unsigned char *data;
1829 data = &butts.texdata[0];
1830 for(i=0;i<size;i+=4)
1834 datai = (int)(((
float) data[i] * (
float)data[i+3])/255.0f);
1839 if( datai ==
'"' || datai ==
'\\') {sprintf(str,
"\\%c",datai); lastoct =
false;}
1840 else if( datai >=
'0' && datai <=
'9' && lastoct && lastlen < 4) {sprintf(str,
"\"\"%c",datai); lastoct =
false;}
1841 else if( datai > 32 && datai < 127 ) {sprintf(str,
"%c",datai); lastoct =
false;}
1842 else {sprintf(str,
"\\%o",datai); lastoct =
true;}
1843 fprintf(out,
"%s",str);
1844 m = (int) strlen(str);
1849 fprintf(out,
"\"\n\"");
1853 fprintf(out,
"\"\n");
1856 fprintf(out,
"};\n");
1869 int i, buttonAtlasSizeCol, buttonAtlasSizeRow, buttonAtlasSquared;
1870 ttglobal tg = gglobal();
1871 ppstatusbar p = (ppstatusbar)tg->statusbar.prv;
1872 p->clipPlane = p->statusBarSize;
1875 if(p->buttonType == 0){
1876 convertPng2hexAlpha();
1879 if(p->buttonType == 1)
1884 static GLubyte * buttonlist [] = {
1886 yawz, xy, yawpitch, roll,
1887 explore, spherical, turntable, lookat, pan, distance, viewall,
1888 shift, hover, pedal, level, headlight,
1889 collision, prev, next, help, messages,
1890 options, reload, url, file, blank
1892 static int actionlist [] = {
1893 ACTION_WALK, ACTION_FLY, ACTION_EXAMINE,
1894 ACTION_YAWZ, ACTION_XY, ACTION_YAWPITCH, ACTION_ROLL,
1895 ACTION_EXPLORE, ACTION_SPHERICAL, ACTION_TURNTABLE, ACTION_LOOKAT, ACTION_PAN, ACTION_DIST, ACTION_VIEWALL,
1896 ACTION_SHIFT, ACTION_HOVER, ACTION_PEDAL, ACTION_LEVEL, ACTION_HEADLIGHT,
1897 ACTION_COLLISION, ACTION_PREV,ACTION_NEXT, ACTION_HELP, ACTION_MESSAGES,
1898 ACTION_OPTIONS,ACTION_RELOAD, ACTION_URL, ACTION_FILE, ACTION_BLANK,
1900 static int NACTION = 29;
1902 static int radiosets [][10] = {
1903 {9,ACTION_FLY,ACTION_WALK,ACTION_EXAMINE,ACTION_EXPLORE,ACTION_SPHERICAL,ACTION_TURNTABLE,ACTION_LOOKAT,ACTION_PAN,ACTION_DIST},
1904 {3,ACTION_MESSAGES,ACTION_OPTIONS,ACTION_HELP},
1910 static int toggles [] = {
1911 ACTION_COLLISION,ACTION_HEADLIGHT,ACTION_SHIFT,ACTION_HOVER,ACTION_PEDAL,
1912 ACTION_HELP,ACTION_MESSAGES,ACTION_OPTIONS,0
1914 static int togglesets [][8] = {{ACTION_FLY,4,ACTION_YAWZ, ACTION_XY, ACTION_YAWPITCH, ACTION_ROLL},{0}};
1916 static int mainbar_linux [] = {
1917 ACTION_WALK, ACTION_FLY, ACTION_EXAMINE,
1918 ACTION_EXPLORE, ACTION_SPHERICAL, ACTION_TURNTABLE, ACTION_LOOKAT, ACTION_VIEWALL, ACTION_PAN, ACTION_DIST,
1919 ACTION_SHIFT, ACTION_HOVER, ACTION_PEDAL, ACTION_LEVEL, ACTION_HEADLIGHT, ACTION_COLLISION, ACTION_PREV,
1920 ACTION_NEXT, ACTION_HELP, ACTION_MESSAGES, ACTION_OPTIONS,
1925 static int *mainbar = NULL;
1927 p->pmenu.nitems = NACTION;
1928 mainbar = mainbar_linux;
1934 p->pmenu.nbitems = i;
1935 }
while(mainbar[i]>-1);
1937#if defined(QNX) || defined(KIOSK)
1938 p->pmenu.top =
true;
1940 p->pmenu.top =
false;
1948 buttonAtlasSizeCol = 8;
1949 buttonAtlasSizeRow = 4;
1950 buttonAtlasSquared = buttonAtlasSizeCol*buttonAtlasSizeRow;
1951 p->pmenu.lumalpha = MALLOC(GLubyte*, 32*32*2 *buttonAtlasSquared);
1952 memset(p->pmenu.lumalpha,0,32*32*2 *buttonAtlasSquared);
1953 p->pmenu.vert= MALLOC(GLfloat*, 3*4*buttonAtlasSquared*
sizeof(GLfloat));
1955 p->pmenu.ind = MALLOC(GLuint*, 3*2*buttonAtlasSquared*
sizeof(GLuint));
1956 p->pmenu.yoffset = 0;
1957 if(p->pmenu.top) p->pmenu.yoffset = p->vport.H - p->buttonSize;
1958 for(i=0;i<p->pmenu.nitems;i++)
1963 p->pmenu.items[i].action = actionlist[i];
1964 p->pmenu.items[i].help = help_for_action(actionlist[i]);
1965 p->pmenu.items[i].isToggle =
false;
1966 p->pmenu.items[i].buttonset = NULL;
1968 while(toggles[j] > 0)
1970 if(p->pmenu.items[i].action == toggles[j])
1972 p->pmenu.items[i].isToggle =
true;
1977 p->pmenu.items[i].radioset = NULL;
1978 p->pmenu.items[i].isRadio =
false;
1980 while(radiosets[j][0] > 0)
1982 for(k=1;k<=radiosets[j][0];k++)
1983 if(p->pmenu.items[i].action == radiosets[j][k])
1985 p->pmenu.items[i].isRadio =
true;
1986 p->pmenu.items[i].radioset = &radiosets[j][0];
1993 p->pmenu.items[i].height = 32;
1994 p->pmenu.items[i].width = 32;
1995 p->pmenu.items[i].lumalpha = MALLOC(GLubyte*, 32 * 32 * 2);
2000 int ibyte, ibit, color;
2003 ibyte = (j*32 + k)/8;
2004 ibit = (j*32 + k)%8;
2005 color = buttonlist[i][ibyte] & (1<<(7-ibit))? 255 : 0;
2009 color = buttonlist[i][ibyte];
2011 p->pmenu.items[i].lumalpha[(j*32 +k)*2 +0] = color;
2012 p->pmenu.items[i].lumalpha[(j*32 +k)*2 +1] = color;
2016 irow = i / buttonAtlasSizeCol;
2017 icol = i % buttonAtlasSizeCol;
2022 p->pmenu.lumalpha[(irow*32 +j)*32*2*buttonAtlasSizeCol + (icol*32 +k)*2 + 0] = p->pmenu.items[i].lumalpha[(j*32 +k)*2 +0];
2023 p->pmenu.lumalpha[(irow*32 +j)*32*2*buttonAtlasSizeCol + (icol*32 +k)*2 + 1] = p->pmenu.items[i].lumalpha[(j*32 +k)*2 +1];
2027 p->pmenu.items[i].tex0[0][0] = (GLfloat)(icol*32 + 0)/(GLfloat)(32*buttonAtlasSizeCol);
2028 p->pmenu.items[i].tex0[1][0] = (GLfloat)(irow*32 + 0)/(GLfloat)(32*buttonAtlasSizeRow);
2029 p->pmenu.items[i].tex0[0][1] = (GLfloat)(icol*32 +32)/(GLfloat)(32*buttonAtlasSizeCol);
2030 p->pmenu.items[i].tex0[1][1] = (GLfloat)(irow*32 +32)/(GLfloat)(32*buttonAtlasSizeRow);
2044 p->pmenu.items[i].tex[kt +0] = p->pmenu.items[i].tex0[0][j];
2045 p->pmenu.items[i].tex[kt +1] = p->pmenu.items[i].tex0[1][k];
2050 glGenTextures(1, &(p->pmenu.textureID));
2051 glBindTexture(GL_TEXTURE_2D, p->pmenu.textureID);
2052 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
2053 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
2055 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 32*buttonAtlasSizeCol, 32*buttonAtlasSizeRow, 0, GL_LUMINANCE_ALPHA , GL_UNSIGNED_BYTE, p->pmenu.lumalpha);
2061 togset = togglesets[kset];
2063 int k, ipact, nact, iact;
2066 for(k=0;k<p->pmenu.nitems;k++){
2067 if(ipact == p->pmenu.items[k].action){
2069 p->pmenu.items[k].buttonset = malloc(
sizeof(buttonSet));
2070 p->pmenu.items[k].buttonset->n = nact;
2071 p->pmenu.items[k].buttonset->index = 0;
2072 p->pmenu.items[k].buttonset->items = malloc(nact *
sizeof(
void*));
2073 for(m=0;m<nact;m++){
2075 p->pmenu.items[k].buttonset->items[m] = NULL;
2077 for(n=0;n<p->pmenu.nitems;n++){
2078 if(iact == p->pmenu.items[n].action){
2079 p->pmenu.items[k].buttonset->items[m] = &p->pmenu.items[n];
2087 togset = togglesets[kset];
2092 for(i=0;i<p->pmenu.nbitems;i++)
2094 int j, k, mi, mv, kv;
2097 int bz = p->buttonSize;
2100 p->pmenu.bitems[i].butrect[0] = 5+(i*bz);
2101 p->pmenu.bitems[i].butrect[1] = 0;
2102 p->pmenu.bitems[i].butrect[2] = 5+(i*bz)+bz;
2103 p->pmenu.bitems[i].butrect[3] = bz;
2117 xyxy[1].x = (GLfloat)p->buttonSize;
2118 xyxy[1].y = (GLfloat)p->buttonSize;
2119 dx = xyxy[1].x - xyxy[0].x;
2125 p->pmenu.bitems[i].vert[kv +0] = p->pmenu.vert[mv+kv +0] = xyxy[j].x + (GLfloat)(i*dx);
2126 p->pmenu.bitems[i].vert[kv +1] = p->pmenu.vert[mv+kv +1] = xyxy[k].y;
2127 p->pmenu.bitems[i].vert[kv +2] = p->pmenu.vert[mv+kv +2] = 0.0f;
2139 p->pmenu.ind[mi +0] = (GLuint)(i*4) +0;
2140 p->pmenu.ind[mi +1] = (GLuint)(i*4) +1;
2141 p->pmenu.ind[mi +2] = (GLuint)(i*4) +3;
2142 p->pmenu.ind[mi +3] = (GLuint)(i*4) +0;
2143 p->pmenu.ind[mi +4] = (GLuint)(i*4) +3;
2144 p->pmenu.ind[mi +5] = (GLuint)(i*4) +2;
2147 for(j=0;j<p->pmenu.nitems;j++){
2148 if(mainbar[i] == p->pmenu.items[j].action){
2149 p->pmenu.bitems[i].item = &p->pmenu.items[j];
2161int getMenuItemByAction(
int iaction)
2164 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
2165 for(i=0;i<p->pmenu.nitems;i++)
2166 if(p->pmenu.items[i].action == iaction)
2171void setRadioPalsOff(
int *ipals,
int iaction)
2175 ttglobal tg = gglobal();
2176 p = (ppstatusbar)tg->statusbar.prv;
2178 for(j=1;j<=ipals[0];j++)
2180 if(ipals[j] != iaction)
2182 i = getMenuItemByAction(ipals[j]);
2184 p->pmenu.items[i].butStatus = 0;
2190void setMenuButton_collision(
int val){
2192 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
2193 i = getMenuItemByAction(ACTION_COLLISION);
2195 p->pmenu.items[i].butStatus = val;
2197void setMenuButton_consoleText(
int val){
2199 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
2200 i = getMenuItemByAction(ACTION_MESSAGES);
2202 p->pmenu.items[i].butStatus = val;
2204void setMenuButton_texSize(
int size){
2206 printf(
"text size=%d\n",size);
2209void setMenuButton_headlight(
int val){
2211 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
2212 i = getMenuItemByAction(ACTION_HEADLIGHT);
2214 p->pmenu.items[i].butStatus = val;
2216void setMenuButton_shift(
int val){
2218 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
2219 i = getMenuItemByAction(ACTION_SHIFT);
2221 p->pmenu.items[i].butStatus = val;
2223void setMenuButton_hover(
int val){
2225 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
2226 i = getMenuItemByAction(ACTION_HOVER);
2228 p->pmenu.items[i].butStatus = val;
2230void setMenuButton_pedal(
int val){
2232 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
2233 i = getMenuItemByAction(ACTION_PEDAL);
2235 p->pmenu.items[i].butStatus = val;
2237void setMenuButton_ctrl(
int ctrl){
2243static int chord2action [] = {ACTION_YAWZ,ACTION_YAWPITCH,ACTION_ROLL,ACTION_XY};
2245void setMenuButton_navModes(
int type,
int dragchord)
2247 int i, newval, iaction;
2248 ppstatusbar p = (ppstatusbar)gglobal()->statusbar.prv;
2253 iaction = ACTION_EXAMINE;
2256 case VIEWER_EXAMINE:
2257 iaction = ACTION_EXAMINE;
2261 iaction = ACTION_WALK;
2264 case VIEWER_TURNTABLE:
2265 iaction = ACTION_TURNTABLE;
2269 iaction = ACTION_LOOKAT;
2272 case VIEWER_EXPLORE:
2273 iaction = ACTION_EXPLORE;
2276 case VIEWER_SPHERICAL:
2277 iaction = ACTION_SPHERICAL;
2281 iaction = ACTION_DIST;
2285 iaction = ACTION_PAN;
2289#if defined(QNX) || defined(KIOSK)
2290 iaction = ACTION_FLY2;
2292 iaction = ACTION_FLY;
2300 i = getMenuItemByAction(iaction);
2302 if(p->pmenu.items[i].buttonset){
2304 if(iaction == p->pmenu.items[i].action){
2309 if(p->pmenu.items[i].buttonset){
2310 for(j=0;j<p->pmenu.items[i].buttonset->n;j++){
2311 if(p->pmenu.items[i].buttonset->items[j]->action == chord2action[dragchord]){
2312 p->pmenu.items[i].buttonset->index = j;
2322 if(p->pmenu.items[i].isRadio)
2323 setRadioPalsOff(p->pmenu.items[i].radioset,iaction);
2324 p->pmenu.items[i].butStatus = newval;
2329int viewer_getDragChord();
2330void viewer_setDragChord(
int chord);
2333void updateButtonStatus()
2343 int headlight, collision,
navmode, dragchord, ctrl, shift, hover, pedal, consoletext;
2345 headlight = fwl_get_headlight();
2346 collision = fwl_getCollision();
2348 dragchord = viewer_getDragChord();
2349 shift = fwl_getShift();
2350 hover = fwl_getHover();
2351 pedal = fwl_getPedal();
2352 ctrl = fwl_getCtrl();
2353 consoletext = getShowConsoleText();
2356 setMenuButton_shift(shift);
2357 setMenuButton_hover(hover);
2358 setMenuButton_pedal(pedal);
2359 setMenuButton_ctrl(ctrl);
2360 setMenuButton_navModes(
navmode,dragchord);
2361 setMenuButton_headlight(headlight);
2362 setMenuButton_collision(collision);
2363 setMenuButton_consoleText(consoletext);
2367void updateConsoleStatus()
2372 nlines = fwg_get_unread_message_count();
2373 for (i = 0; i<nlines; i++)
2375 buffer = fwg_get_last_message();
2376 hudSetConsoleMessage(buffer);
2382int handleButtonOver(
int mouseX,
int mouseY)
2389 ttglobal tg = gglobal();
2390 p = (ppstatusbar)tg->statusbar.prv;
2398 y = p->vport.H - mouseY;
2400 y = mouseY - p->pmenu.yoffset;
2404 ihalf = (p->pmenu.nbitems + 1)/p->buttonRows;
2405 for(i=0;i<p->pmenu.nbitems;i++)
2407 int j,xx,yy,butrect[4];
2408 for(j=0;j<4;j++) butrect[j] = p->pmenu.bitems[i].butrect[j];
2412 xx = x + ihalf * p->buttonSize;
2413 yy = y - p->buttonSize;
2415 if(xx > butrect[0] && xx < butrect[2]
2416 && yy > butrect[1] && yy < butrect[3] )
2425char *frontend_pick_URL(
void);
2426char *frontend_pick_file(
void);
2427void toggleMenu(
int val)
2430 ttglobal tg = gglobal();
2431 p = (ppstatusbar)tg->statusbar.prv;
2433 p->showButtons = val > 0 ? 1 : 0;
2438int action2chord(
int iaction){
2439 int ichord = CHORD_YAWZ;
2441 case ACTION_YAWZ: ichord = CHORD_YAWZ;
break;
2442 case ACTION_XY: ichord = CHORD_XY;
break;
2443 case ACTION_YAWPITCH: ichord = CHORD_YAWPITCH;
break;
2444 case ACTION_ROLL: ichord = CHORD_ROLL;
break;
2445 default: ichord = 0;
break;
2450int handleButtonRelease(
int mouseX,
int mouseY)
2457 int i,x,y,ihit,iaction,ihalf;
2460 ttglobal tg = gglobal();
2461 p = (ppstatusbar)tg->statusbar.prv;
2469 y = p->vport.H - mouseY;
2471 y = mouseY - p->pmenu.yoffset;
2472 ihalf = (p->pmenu.nbitems + 1)/p->buttonRows;
2474 for(i=0;i<p->pmenu.nbitems;i++)
2476 int j,xx,yy,butrect[4];
2477 for(j=0;j<4;j++) butrect[j] = p->pmenu.bitems[i].butrect[j];
2481 xx = x + ihalf * p->buttonSize;
2482 yy = y - p->buttonSize;
2484 if(xx > butrect[0] && xx < butrect[2]
2485 && yy > butrect[1] && yy < butrect[3] )
2488 iaction = p->pmenu.bitems[i].item->action;
2489 if(p->pmenu.bitems[i].item->butStatus && p->pmenu.bitems[i].item->buttonset ){
2491 p->pmenu.bitems[i].item->buttonset->index++;
2492 p->pmenu.bitems[i].item->buttonset->index = (p->pmenu.bitems[i].item->buttonset->index % 4);
2494 if(p->pmenu.bitems[i].item->isRadio)
2496 setRadioPalsOff(p->pmenu.bitems[i].item->radioset,iaction);
2497 if(p->pmenu.bitems[i].item->isToggle )
2498 p->pmenu.bitems[i].item->butStatus = 1 - p->pmenu.bitems[i].item->butStatus;
2500 p->pmenu.bitems[i].item->butStatus = 1;
2502 else if(p->pmenu.bitems[i].item->isToggle)
2503 p->pmenu.bitems[i].item->butStatus = 1 - p->pmenu.bitems[i].item->butStatus;
2507 fwl_set_viewer_type (VIEWER_WALK);
break;
2517 fwl_set_viewer_type(VIEWER_FLY);
2518 if(p->pmenu.bitems[i].item->buttonset){
2519 int iact, idx, ichord;
2520 idx = p->pmenu.bitems[i].item->buttonset->index;
2521 iact = p->pmenu.bitems[i].item->buttonset->items[idx]->action;
2522 ichord = action2chord(iact);
2523 viewer_setDragChord(ichord);
2526 case ACTION_EXPLORE:
2527 fwl_set_viewer_type(VIEWER_EXPLORE);
break;
2529 fwl_set_viewer_type(VIEWER_LOOKAT);
break;
2530 case ACTION_EXAMINE:
2531 fwl_set_viewer_type (VIEWER_EXAMINE);
break;
2532 case ACTION_SPHERICAL:
2533 fwl_set_viewer_type(VIEWER_SPHERICAL);
break;
2534 case ACTION_TURNTABLE:
2535 fwl_set_viewer_type(VIEWER_TURNTABLE);
break;
2537 fwl_set_viewer_type(VIEWER_PAN);
break;
2539 fwl_set_viewer_type(VIEWER_DIST);
break;
2540 case ACTION_SHIFT: fwl_setShift(p->pmenu.bitems[i].item->butStatus);
break;
2541 case ACTION_HOVER: fwl_setHover(p->pmenu.bitems[i].item->butStatus);
2543 case ACTION_PEDAL: fwl_setPedal(p->pmenu.bitems[i].item->butStatus);
break;
2544 case ACTION_VIEWALL: viewer_viewall();
break;
2545 case ACTION_LEVEL: viewer_level_to_bound();
break;
2546 case ACTION_HEADLIGHT: fwl_toggle_headlight();
break;
2547 case ACTION_COLLISION: toggle_collision();
break;
2548 case ACTION_PREV: fwl_Prev_ViewPoint();
break;
2549 case ACTION_NEXT: fwl_Next_ViewPoint();
break;
2552 if(!p->pmenu.bitems[i].item->butStatus)
2554 update_status(NULL);
2557 case ACTION_MESSAGES:
2559 update_status(NULL);
2560 showConsoleText(p->pmenu.bitems[i].item->butStatus);
2562 case ACTION_OPTIONS:
2564 update_status(NULL);
2572 #if defined(_MSC_VER) || defined(QNX)
2574 char *fname = frontend_pick_URL();
2577 fwl_replaceWorldNeeded(fname);
2590 #if defined(_MSC_VER) || defined(QNX)
2592 char *fname = frontend_pick_file();
2595 fwl_replaceWorldNeeded(fname);
2608 return ihit == -1 ? 0 : 1;
2610void updateButtonVertices()
2612 int i,j,k,kv,mv,ihalf;
2617 ttglobal tg = gglobal();
2618 p = (ppstatusbar)tg->statusbar.prv;
2621 if(p->pmenu.top) p->pmenu.yoffset = (p->vport.H - p->buttonSize - p->pmenu.yoffset);
2623 ihalf = (p->pmenu.nbitems + 1)/p->buttonRows;
2624 for(i=0;i<p->pmenu.nbitems;i++)
2626 int button_xoff, button_yoff;
2628 button_yoff = button_xoff = 0;
2631 button_yoff = p->buttonSize;
2632 button_xoff = -(ihalf * p->buttonSize);
2637 xx = p->pmenu.bitems[i].vert[kv +0];
2638 yy = p->pmenu.bitems[i].vert[kv +1];
2639 xy = screen2normalizedScreen(xx + button_xoff,yy + p->pmenu.yoffset + button_yoff + p->side_bottom);
2641 p->pmenu.vert[mv+kv +0] = xy.x;
2642 p->pmenu.vert[mv+kv +1] = xy.y;
2653 ttglobal tg = gglobal();
2654 p = (ppstatusbar)tg->statusbar.prv;
2659 updateButtonVertices();
2665 glScissor(p->vport.X,p->vport.Y + p->pmenu.yoffset+p->side_bottom,p->vport.W -itrim ,p->buttonSize*p->buttonRows);
2667 glEnable(GL_SCISSOR_TEST);
2669 glClearColor(colorClear[0],colorClear[1],colorClear[2],colorClear[3]);
2671 glClear(GL_COLOR_BUFFER_BIT);
2672 glDisable(GL_SCISSOR_TEST);
2675 glActiveTexture ( GL_TEXTURE0 );
2677 glBindTexture ( GL_TEXTURE_2D, p->pmenu.textureID );
2679 ctrl = fwl_getCtrl();
2680 for(i=0;i<p->pmenu.nbitems;i++)
2683 bool highlightIt = p->pmenu.bitems[i].item->butStatus;
2684 do_ctrl = ctrl && i < 8;
2691 glUniform4f(p->color4fLoc,colorButtonCTRL[0],colorButtonCTRL[1],colorButtonCTRL[2],colorButtonCTRL[3]);
2693 glUniform4f(p->color4fLoc,colorButtonHighlight[0],colorButtonHighlight[1],colorButtonHighlight[2],colorButtonHighlight[3]);
2694 glVertexAttribPointer ( p->positionLoc, 3, GL_FLOAT,
2695 GL_FALSE, 0, &(p->pmenu.vert[i*3*4]) );
2697 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2698 GL_FALSE, 0, p->pmenu.items[p->pmenu.nitems-1].tex );
2699 glEnableVertexAttribArray ( p->positionLoc );
2700 glEnableVertexAttribArray ( p->texCoordLoc );
2701 glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_INT, p->pmenu.ind );
2705 glVertexAttribPointer ( p->positionLoc, 3, GL_FLOAT,
2706 GL_FALSE, 0, &(p->pmenu.vert[i*3*4]) );
2710 if(p->pmenu.bitems[i].item->buttonset){
2712 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2713 GL_FALSE, 0, p->pmenu.bitems[i].item->buttonset->items[p->pmenu.bitems[i].item->buttonset->index]->tex );
2715 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2716 GL_FALSE, 0, p->pmenu.bitems[i].item->tex );
2719 glUniform4f(p->color4fLoc,colorButtonIcon[0],colorButtonIcon[1],colorButtonIcon[2],colorButtonIcon[3]);
2720 glEnableVertexAttribArray ( p->positionLoc );
2721 glEnableVertexAttribArray ( p->texCoordLoc );
2722 glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_INT, p->pmenu.ind );
2745void updateViewportSize();
2746void fwl_getWindowSize(
int *width,
int *height);
2747void statusbarHud_DrawCursor(GLint textureID,
int x,
int y){
2748GLfloat cursorVert[] = {
2755GLfloat cursorTex[] = {
2762 GLuint ind[] = {0,1,2,3,4,5};
2766 int i,j,screenWidth,screenHeight;
2767 GLfloat cursorVert2[18];
2770 ttglobal tg = gglobal();
2771 p = (ppstatusbar)tg->statusbar.prv;
2773 finishedWithGlobalShader();
2774 glDepthMask(GL_FALSE);
2775 glDisable(GL_DEPTH_TEST);
2776 if(p->programObject == 0) init_ProgramObject();
2777 glUseProgram ( p->programObject );
2780 fwl_getWindowSize(&screenWidth,&screenHeight);
2781 xy = mouse2screen(x,y);
2783 FW_GL_VIEWPORT(0,0,screenWidth,screenHeight);
2785 fxy.x = ((GLfloat)xy.x/(GLfloat)screenWidth * 2.0f);
2786 fxy.y = ((GLfloat)xy.y/(GLfloat)screenHeight * 2.0f);
2794 cursorVert2[i*3 + j] = cursorVert[i*3 +j];
2795 cursorVert2[i*3 +0] += fxy.x;
2796 cursorVert2[i*3 +1] += fxy.y;
2805 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
2806 GL_FALSE, 0, cursorVert2 );
2808 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2809 GL_FALSE, 0, cursorTex );
2810 glUniform4f(p->color4fLoc,0.7f,0.7f,0.9f,1.0f);
2811 glEnableVertexAttribArray (p->positionLoc );
2812 glEnableVertexAttribArray ( p->texCoordLoc);
2815 glActiveTexture ( GL_TEXTURE0 );
2816 glBindTexture ( GL_TEXTURE_2D, textureID );
2819 glUniform1i ( p->textureLoc, 0 );
2820 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_INT, ind );
2826 glEnable(GL_DEPTH_TEST);
2827 glDepthMask(GL_TRUE);
2828 restoreGlobalShader();
2831void updateViewCursorStyle(
int cstyle);
2832void fwl_set_frontend_using_cursor(
int on);
2833bool showAction(ppstatusbar p,
int action)
2835 int item = getMenuItemByAction(action);
2838 return p->pmenu.items[item].butStatus;
2842int overMenubar(ppstatusbar p,
int mouseY){
2850 y = p->vport.H - mouseY;
2852 y = mouseY - p->pmenu.yoffset;
2853 if( y >= 0 && y <= p->buttonSize * p->buttonRows) isOver = 1;
2857int overStatusbar(ppstatusbar p,
int mouseY){
2861 if(mouseY < p->statusBarSize * p->statusBarRows) isOver = 1;
2893void updateViewportSize(){
2896 ttglobal tg = gglobal();
2897 p = (ppstatusbar)tg->statusbar.prv;
2899 vportstack = (Stack*)tg->Mainloop._vportstack;
2900 p->vport = stack_top(
ivec4,vportstack);
2902void updateSBHRows(){
2904 ttglobal tg = gglobal();
2905 p = (ppstatusbar)tg->statusbar.prv;
2907 if(p->vport.W < ((p->buttonSize * p->pmenu.nbitems) + 10)){
2909 p->statusBarRows = 1;
2912 p->statusBarRows = 1;
2915int handleStatusbarHud1(
int mev,
int butnum,
int mouseX,
int mouseY,
int windex)
2919 ttglobal tg = gglobal();
2920 p = (ppstatusbar)tg->statusbar.prv;
2926 if ((mev == ButtonPress) || (mev == ButtonRelease) )
2932 if(overMenubar(p,mouseY))
2934 if (mev == ButtonRelease){
2935 ihit = handleButtonRelease(mouseX,mouseYY);
2939 p->menubar_pinned = 1 - p->menubar_pinned;
2940 fwl_get_sbh_pin(&p->statusbar_pinned, &p->menubar_pinned);
2941 p->menubar_pinned = 1 - p->menubar_pinned;
2942 fwl_set_sbh_pin(p->statusbar_pinned, p->menubar_pinned);
2943 if(!p->menubar_pinned)
2946 if(!p->statusbar_pinned && !p->showStatus)
2950 if (mev == ButtonPress){
2951 if (showAction(p, ACTION_HELP)) {
2953 ib_over = handleButtonOver(mouseX, mouseYY);
2955 update_status((
char *)p->pmenu.bitems[ib_over].item->help);
2957 update_status(NULL);
2961 }
else if(overStatusbar(p,mouseY)){
2963 if(mev == ButtonRelease){
2964 if(p->wantButtons && !p->showButtons) toggleMenu(1);
2965 if(p->wantStatusbar && !p->statusbar_pinned ) p->showStatus = 1 - p->showStatus;
2970 if (!ihit && showAction(p, ACTION_OPTIONS))
2972 if (mev == ButtonPress)
2973 ihit = handleOptionPress(mouseX,mouseYY);
2978 if (mev == MotionNotify)
2983#elif defined(_MSC_VER)
2986 static int lastover;
2987 if (p->vport.H - mouseYY < 16)
2990 toggleMenu(1 - p->showButtons);
2998 if (p->showButtons == 1){
3002 ihit = handleButtonOver(mouseX,mouseYY);
3012 if(overMenubar(p,mouseY) || overStatusbar(p,mouseY))
3014 p->showButtons = p->wantButtons;
3016 if(overMenubar(p,mouseY)){
3018 if(TRUE || showAction(p, ACTION_HELP)) {
3020 ib_over = handleButtonOver(mouseX,mouseYY);
3022 update_status((
char *)p->pmenu.bitems[ib_over].item->help);
3024 update_status(NULL);
3033 p->showButtons = p->menubar_pinned;
3034 update_status(NULL);
3038 if (showAction(p, ACTION_OPTIONS))
3060int getCursorStyle();
3061int statusbar_handle_mouse1(
int mev,
int butnum,
int mouseX,
int yup,
int windex)
3063 int vpx, vpy, iret, ihandled;
3064 ttglobal tg = gglobal();
3065 ppstatusbar p = (ppstatusbar)tg->statusbar.prv;
3066 updateViewportSize();
3070 vpy = yup - p->vport.Y;
3071 vpx = mouseX - p->vport.X;
3072 ihandled = handleStatusbarHud1(mev, butnum, vpx, vpy, windex);
3075 fwl_set_frontend_using_cursor(FALSE);
3077 fwl_set_frontend_using_cursor(TRUE);
3082int statusbar_handle_mouse(
int mev,
int butnum,
int mouseX,
int mouseY)
3084 return statusbar_handle_mouse1(mev,butnum,mouseX,mouseY,0);
3087char *getMessageBar();
3088char *fwl_getKeyChord();
3089void fwl_setClipPlane(
int height);
3090int fwl_get_sbh_wantMenubar();
3091int fwl_get_sbh_wantStatusbar();
3092void drawStatusBarSide()
3095void update_pinned(){
3097 ttglobal tg = gglobal();
3098 p = (ppstatusbar)tg->statusbar.prv;
3099 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
3100 p->wantButtons = fwl_get_sbh_wantMenubar();
3101 p->wantStatusbar = fwl_get_sbh_wantStatusbar();
3103void update_density(){
3104 float density_factor;
3107 ttglobal tg = gglobal();
3108 p = (ppstatusbar)tg->statusbar.prv;
3109 density_factor = fwl_getDensityFactor();
3110 ifactor = (int)(density_factor + .5f);
3111 ifactor = max(1,ifactor);
3112 p->bmScaleRegular = ifactor;
3113 p->bmScale = ifactor;
3114 p->bmScaleForOptions = ifactor;
3116 p->statusBarSize = p->bmScaleRegular * 16;
3117 p->buttonSize = (int)(density_factor * 32);
3119int statusbar_getClipPlane(){
3121 int statusbar_height, menubar_height;
3123 ttglobal tg = gglobal();
3124 p = (ppstatusbar)tg->statusbar.prv;
3130 statusbar_height = (p->statusbar_pinned && p->wantStatusbar)? p->statusBarSize * p->statusBarRows : 0;
3131 menubar_height = (p->menubar_pinned && p->wantButtons) ? p->buttonSize * p->buttonRows : 0;
3132 vrml_clipplane = statusbar_height + menubar_height;
3133 return vrml_clipplane;
3166 int i,nsides, menu_over_status;
3167 GLfloat side_bottom_f;
3169 ttglobal tg = gglobal();
3170 p = (ppstatusbar)tg->statusbar.prv;
3178 if(!p->fontInitialized) initFont();
3179 if(p->programObject == 0) init_ProgramObject();
3182 updateViewportSize();
3185 updateButtonStatus();
3186 updateConsoleStatus();
3188 glDepthMask(GL_FALSE);
3189 glDisable(GL_DEPTH_TEST);
3191 glUseProgram ( p->programObject );
3192 glViewport(p->vport.X, p->vport.Y, p->vport.W, p->vport.H);
3194 p->show_menu = p->wantButtons && (p->menubar_pinned || p->showButtons);
3195 menu_over_status = !p->menubar_pinned && p->showButtons;
3196 p->show_status = p->wantStatusbar && ((p->showStatus || p->statusbar_pinned) && !menu_over_status);
3197 p->show_status = p->show_status || showAction(p, ACTION_HELP);
3202 p->pmenu.yoffset = p->show_status ? p->statusBarSize * p->statusBarRows : 0;
3205 p->clipPlane = (p->show_menu ? p->buttonSize * p->buttonRows : 0) + p->show_status ? p->statusBarSize * p->statusBarRows : 0;
3214 if (Viewer()->updown) nsides = 2;
3215 for (i = 0; i < nsides; i++)
3219 side_bottom_f = -1.0f;
3220 if (Viewer()->updown){
3222 p->side_top = i*(p->vport.H / 2);
3223 p->side_bottom = (1 -i) *(p->vport.H /2);
3224 if(i == 0) side_bottom_f = 0.0f;
3233 int sblen, sslen,itrim;
3243 glScissor(p->vport.X, p->vport.Y + p->side_bottom, p->vport.W -itrim, p->statusBarSize * p->statusBarRows);
3244 glEnable(GL_SCISSOR_TEST);
3246 glClearColor(colorClear[0],colorClear[1],colorClear[2],colorClear[3]);
3247 glClear(GL_COLOR_BUFFER_BIT);
3248 glDisable(GL_SCISSOR_TEST);
3252 glUniform4f(p->color4fLoc,colorStatusbarText[0],colorStatusbarText[1],colorStatusbarText[2],colorStatusbarText[3]);
3253 xy = screen2normalizedScreenScale((GLfloat)p->bmWH.x, (GLfloat)p->bmWH.y);
3256 sblen = (int)(2.0f/xy.x);
3260 char *ppss = getSensorStatus();
3267 sslen = strlen(ppss);
3269 printString2(-1.0f, side_bottom_f, pp);
3273 int len, istart, istart1, ilen, lenk, lenkk;
3274 char *strfps, *strdist, *strstatus, *strAkeys;
3277 strAkeys = fwl_getKeyChord();
3278 lenkk = lenk = strlen(strAkeys);
3280 strstatus = getMenuStatus();
3283 len = strlen(strstatus);
3291 if(max(istart1,35) + len + 9 < sblen) {
3293 istart = max(istart1,35);
3294 }
else if(istart1 + len + 9 < sblen){
3297 }
else if(istart1 + len + lenkk < sblen){
3300 }
else if(p->buttonRows == 2){
3303 ilen = sblen - istart;
3307 ilen = sblen - istart - lenkk;
3312 printString3(-1.0f + xy.x * istart, side_bottom_f, strstatus, ilen);
3317 printString3(1.0f - xy.x*(lenk + 4), side_bottom_f, strAkeys,lenk);
3320 strfps = getFpsBar();
3321 printString2(1.0f - xy.x*(4), side_bottom_f, strfps);
3322 strdist = getDistBar();
3323 printString2(1.0f - xy.x*(22), side_bottom_f, strdist);
3329 glUniform4f(p->color4fLoc,colorMessageText[0],colorMessageText[1],colorMessageText[2],colorMessageText[3]);
3331 if (showAction(p, ACTION_HELP))
3332 printKeyboardHelp(p);
3333 if (showAction(p, ACTION_MESSAGES))
3335 if (showAction(p, ACTION_OPTIONS))
3343 glDisableVertexAttribArray( p->texCoordLoc );
3348 glEnable(GL_DEPTH_TEST);
3353int statusbar_getClipPlane(){
3356int statusbar_handle_mouse1(
int mev,
int butnum,
int mouseX,
int yup,
int windex){