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};
411 int statusbar_pinned;
433 char messagebar[200];
436 char * optionsVal[35];
440 int bmScaleForOptions;
447 GLuint programObject;
455 GLfloat textColor[4];
460 int side_top, side_bottom;
462void *statusbar_constructor(){
467void statusbar_init(
struct tstatusbar *t){
470 t->prv = statusbar_constructor();
476 p->wantStatusbar = 1;
477 p->wantButtons = p->wantStatusbar;
479 p->showStatus = p->wantStatusbar;
490 p->fontInitialized = 0;
493 p->optionsLoaded = 0;
498 p->bmScaleForOptions = 2;
500 p->bmScaleForOptions = 1;
502 p->bmScaleRegular = 1;
504 p->bmScaleRegular = 2;
505 p->bmScaleForOptions = 2;
507 p->bmScale = p->bmScaleRegular;
508 p->statusBarSize = p->bmScaleRegular * 16;
509 p->statusBarRows = 1;
511 p->pfont.cheight = 0;
513 p->pfont.lumalpha = NULL;
514 p->pmenu.items = MALLOC(pmenuItem_t *, MAXBUT *
sizeof(pmenuItem_t));
515 for(i=0;i<MAXBUT;i++) p->pmenu.items[i].butStatus = 0;
516 p->pmenu.bitems = (barItem *)malloc(MAXBUT *
sizeof(barItem));
517 bzero(p->pmenu.bitems,MAXBUT *
sizeof(barItem));
520 p->buttonSize = BUTSIZE;
522 p->textColor[3] = 1.0f;
525 p->vport = defaultViewport;
526 p->clipPlane = p->statusBarSize;
532static void init_ProgramObject(){
536 p->programObject = esLoadProgram ( (
const char*) vShaderStr, (
const char *)fShaderStr );
538 p->positionLoc = glGetAttribLocation ( p->programObject,
"a_position" );
539 p->texCoordLoc = glGetAttribLocation ( p->programObject,
"a_texCoord" );
541 p->textureLoc = glGetUniformLocation ( p->programObject,
"Texture0" );
542 p->color4fLoc = glGetUniformLocation ( p->programObject,
"Color4f" );
544static int lenOptions = 30;
545void statusbar_clear(
struct tstatusbar *t){
551 glDeleteTextures(1, &(p->pfont.textureID));
552 glDeleteTextures(1, &(p->pmenu.textureID));
554 ml_delete_all(p->conlist);
556 for(i=0;i<lenOptions;i++)
559 FREE_IF_NZ(p->optionsVal[i]);
562 for(i=0;i<p->pmenu.nitems;i++)
563 FREE_IF_NZ(p->pmenu.items[i].lumalpha);
564 FREE_IF_NZ(p->pmenu.lumalpha);
565 FREE_IF_NZ(p->pmenu.items);
566 FREE_IF_NZ(p->pmenu.vert);
567 FREE_IF_NZ(p->pmenu.ind);
568 FREE_IF_NZ(p->pfont.lumalpha);
571void fwMakeRasterFonts()
573 int i,j,k,m,w,h,bytewidth,bit;
575 int ichar,isize, irow, icol, irowheight,icolwidth, iwidth, iheight;
577 GLubyte *cdata, *row;
584 p->pfont.cheight = 15;
592 height = (float)iheight;
593 width = (float)iwidth;
596 isize = iheight * iwidth * 2;
598 p->pfont.lumalpha = MALLOC(GLubyte *, isize);
600 memset(p->pfont.lumalpha,0,isize);
601 white[0] = white[1] = (GLubyte)255;
604 p->pfont.have[m] = 0;
608 ichar = fwLetters8x15[m][0];
609 if(ichar == 255)
break;
610 p->pfont.have[ichar] = 1;
611 cdata = &fwLetters8x15[m][7];
612 w = fwLetters8x15[m][1];
613 h = fwLetters8x15[m][2];
617 p->pfont.tex[0][0][ichar] = (GLfloat)(icol * icolwidth);
618 p->pfont.tex[1][0][ichar] = (GLfloat)(irow * irowheight);
619 p->pfont.tex[0][1][ichar] = p->pfont.tex[0][0][ichar] + p->pfont.cwidth;
620 p->pfont.tex[1][1][ichar] = p->pfont.tex[1][0][ichar] + p->pfont.cheight;
621 p->pfont.owh[0][0][ichar] = p->pfont.owh[1][0][ichar] = 0.0f;
622 p->pfont.owh[0][1][ichar] = (GLfloat)p->pfont.cwidth;
623 p->pfont.owh[1][1][ichar] = (GLfloat)p->pfont.cheight;
626 p->pfont.tex[0][j][ichar] /= width;
627 p->pfont.tex[1][j][ichar] /= height;
629 bytewidth = ((w-1)/8 +1);
632 row = &cdata[j*bytewidth];
637 bit = row[k] & (1<<((bytewidth*8)-i-1))? 1 : 0;
642 ip = (irow*irowheight +j)*iwidth;
643 ip += icol*icolwidth + i;
644 memcpy(&p->pfont.lumalpha[ip*2],white,2);
653 fp = fopen(
"hud_junk_0.txt",
"w+");
654 fprintf(fp,
"char data\n");
657 ichar = fwLetters8x15[m][0];
658 if(ichar == 255)
break;
659 fprintf(fp,
"%c %d ",(
char)ichar,ichar);
660 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]);
661 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]);
667 glGenTextures(1, &(p->pfont.textureID));
669 glBindTexture(GL_TEXTURE_2D, p->pfont.textureID);
671 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
672 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
674 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, iwidth, iheight, 0, GL_LUMINANCE_ALPHA , GL_UNSIGNED_BYTE, p->pfont.lumalpha);
687 p->fontInitialized = 1;
691void printString(
char *s){}
692FXY screen2normalizedScreen( GLfloat x, GLfloat y);
693FXY screen2normalizedScreenScale( GLfloat x, GLfloat y);
702void printString3_old(GLfloat sx, GLfloat sy,
char *s,
int len)
715 int sizeoftex, sizeofvert, sizeofind;
722 sizeofvert = len1 *
sizeof(GLfloat) * 4 * 3;
723 sizeoftex = len1 *
sizeof(GLfloat) * 4 * 2;
724 sizeofind = len1 *
sizeof(GLshort) * 2 * 3;
725 vert = (GLfloat*)alloca(sizeofvert);
726 tex = (GLfloat*)alloca(sizeoftex);
727 ind = (GLushort*)alloca(sizeofind);
737 if (ichar ==
'\t') ichar =
' ';
738 if(p->pfont.have[ichar])
740 charScreenSize = screen2normalizedScreenScale(p->pfont.owh[0][1][ichar]*p->bmScale,p->pfont.owh[1][1][ichar]*p->bmScale);
745 vert[i*4*3 +4] = y + charScreenSize.y;
747 vert[i*4*3 +6] = x + charScreenSize.x;
748 vert[i*4*3 +7] = y + charScreenSize.y;
750 vert[i*4*3 +9] = x + charScreenSize.x;
753 x = x + charScreenSize.x;
754 tex[i*4*2 +0] = p->pfont.tex[0][0][ichar];
755 tex[i*4*2 +1] = p->pfont.tex[1][0][ichar];
756 tex[i*4*2 +2] = p->pfont.tex[0][0][ichar];
757 tex[i*4*2 +3] = p->pfont.tex[1][1][ichar];
758 tex[i*4*2 +4] = p->pfont.tex[0][1][ichar];
759 tex[i*4*2 +5] = p->pfont.tex[1][1][ichar];
760 tex[i*4*2 +6] = p->pfont.tex[0][1][ichar];
761 tex[i*4*2 +7] = p->pfont.tex[1][0][ichar];
762 ind[i*3*2 +0] = i*4 + 0;
763 ind[i*3*2 +1] = i*4 + 1;
764 ind[i*3*2 +2] = i*4 + 2;
765 ind[i*3*2 +3] = i*4 + 2;
766 ind[i*3*2 +4] = i*4 + 3;
767 ind[i*3*2 +5] = i*4 + 0;
773 glActiveTexture ( GL_TEXTURE0 );
774 glBindTexture ( GL_TEXTURE_2D, p->pfont.textureID );
776 glVertexAttribPointer ( p->positionLoc, 3, GL_FLOAT,
779 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
782 glEnableVertexAttribArray ( p->positionLoc );
783 glEnableVertexAttribArray ( p->texCoordLoc );
785 glUniform1i ( p->textureLoc, 0 );
786 glDrawElements ( GL_TRIANGLES, i*3*2, GL_UNSIGNED_SHORT, ind );
799void printString3(GLfloat sx, GLfloat sy,
char *s,
int len)
813 int sizeoftex, sizeofvert, sizeofind;
819 glActiveTexture ( GL_TEXTURE0 );
820 glBindTexture ( GL_TEXTURE_2D, p->pfont.textureID );
822 glUniform1i ( p->textureLoc, 0 );
824 glEnableVertexAttribArray ( p->positionLoc );
825 glEnableVertexAttribArray ( p->texCoordLoc );
836 if (ichar ==
'\t') ichar =
' ';
837 if(p->pfont.have[ichar])
839 charScreenSize = screen2normalizedScreenScale(p->pfont.owh[0][1][ichar]*p->bmScale,p->pfont.owh[1][1][ichar]*p->bmScale);
844 vert[4] = y + charScreenSize.y;
846 vert[6] = x + charScreenSize.x;
847 vert[7] = y + charScreenSize.y;
849 vert[9] = x + charScreenSize.x;
852 x = x + charScreenSize.x;
853 tex[0] = p->pfont.tex[0][0][ichar];
854 tex[1] = p->pfont.tex[1][0][ichar];
855 tex[2] = p->pfont.tex[0][0][ichar];
856 tex[3] = p->pfont.tex[1][1][ichar];
857 tex[4] = p->pfont.tex[0][1][ichar];
858 tex[5] = p->pfont.tex[1][1][ichar];
859 tex[6] = p->pfont.tex[0][1][ichar];
860 tex[7] = p->pfont.tex[1][0][ichar];
870 glVertexAttribPointer ( p->positionLoc, 3, GL_FLOAT,
873 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
876 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_SHORT, ind );
885void printString2(GLfloat sx, GLfloat sy,
char *s){
886 printString3(sx,sy,s,strlen(s));
888void render_init(
void);
919char * optionsText[] = {
926"Eyebase - object space",
928"Your Eyebase = fiducials",
940" emulate multitouch (mousewheel)",
943"screen orientation \36 \37",
945" flat gouraud phong wire",
946" draw bounding boxes",
947"depth slices auto 1 2 3",
949"mat modulation none matxtex matxcpvxtex",
959char *colorschemenames [] = {
971void fwl_setPickraySide(
int ipreferredSide,
int either);
972void fwl_getPickraySide(
int *ipreferredSide,
int *either);
973int fwl_getOrientation();
974int fwl_getOrientation2();
975void fwl_setOrientation2(
int degrees);
976int fwl_getShadingStyle();
979 int i,j,k,m, iside, ieither, shadingStyle;
984 for(i=0;i<lenOptions;i++)
986 if(!p->optionsVal[i])
987 p->optionsVal[i] = MALLOC(
char*, 48);
988 for(j=0;j<48;j++) p->optionsVal[i][j] =
' ';
989 p->optionsVal[i][47] =
'\0';
991 p->optionsVal[1][0] = 034;
992 p->optionsVal[2][0] = 034;
993 p->optionsVal[3][0] = 034;
994 p->optionsVal[4][0] = 034;
995 p->optionsVal[5][0] = 034;
998 p->optionsVal[1][0] = 035;
1000 p->optionsVal[2][0] = 035;
1002 p->optionsVal[3][0] = 035;
1004 p->optionsVal[4][0] = 035;
1005 if(
viewer->shutterGlasses)
1006 p->optionsVal[5][0] = 035;
1007 sprintf(p->optionsVal[7],
" %4.3f",
viewer->eyedist);
1008 sprintf(p->optionsVal[9],
" %4.3f",
viewer->screendist);
1012 k = getAnaglyphPrimarySide(j,i);
1013 p->optionsVal[12+i][j+1] = (k ? 035 :
' ');
1016 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
1017 p->optionsVal[15][0] = p->statusbar_pinned ? 035 : 034;
1018 p->optionsVal[16][0] = p->menubar_pinned ? 035 : 034;
1019 sprintf(p->optionsVal[18],
" %s ",fwl_get_ui_colorschemename());
1020 sprintf(p->optionsVal[19],
" %4d",abs(fwl_get_target_fps()));
1021 p->optionsVal[20][0] = 034;
1022 if(fwl_get_emulate_multitouch())
1023 p->optionsVal[20][0] = 035;
1024 fwl_getPickraySide(&iside,&ieither);
1025 p->optionsVal[22][1] = p->optionsVal[22][7] = p->optionsVal[22][14] = 034;
1026 if(iside==0) p->optionsVal[22][1] = 035;
1027 else p->optionsVal[22][7] = 035;
1028 if(ieither) p->optionsVal[22][14] = 035;
1029 sprintf(p->optionsVal[23],
" %4d",fwl_getOrientation2());
1030 shadingStyle = fwl_getShadingStyle();
1031 p->optionsVal[25][1] = p->optionsVal[25][7] = p->optionsVal[25][16] = p->optionsVal[25][23] =034;
1032 switch(shadingStyle){
1033 case 0: p->optionsVal[25][1] = 035;
break;
1034 case 1: p->optionsVal[25][7] = 035;
break;
1035 case 2: p->optionsVal[25][16] = 035;
break;
1036 case 3: p->optionsVal[25][23] = 035;
break;
1040 p->optionsVal[26][0] = 034;
1041 if(fwl_getDrawBoundingBoxes())
1042 p->optionsVal[26][0] = 035;
1043 m = fwl_get_depth_slices();
1044 p->optionsVal[27][13] = p->optionsVal[27][19] = p->optionsVal[27][23] = p->optionsVal[27][27] =034;
1047 case 0: p->optionsVal[27][13] = 035;
break;
1048 case 1: p->optionsVal[27][19] = 035;
break;
1049 case 2: p->optionsVal[27][23] = 035;
break;
1050 case 3: p->optionsVal[27][27] = 035;
break;
1052 p->optionsVal[28][0] = 034;
1053 if(fwl_get_allow_DIS())
1054 p->optionsVal[28][0] = 035;
1055 m = fwl_get_modulation();
1056 p->optionsVal[29][15] = p->optionsVal[29][21] = p->optionsVal[29][30] =034;
1058 case 0: p->optionsVal[29][15] = 035;
break;
1059 case 1: p->optionsVal[29][21] = 035;
break;
1060 case 2: p->optionsVal[29][30] = 035;
break;
1062 p->optionsLoaded = 1;
1064void updateOptionsVal()
1071char * optionsCase[] = {
1105XY mouse2screen(
int x,
int y)
1113XY screen2text(
int x,
int y)
1121 topOffset = p->side_top;
1122 if(p->pmenu.top) topOffset += p->buttonSize;
1123 rc.x = x/(p->bmWH.x*p->bmScale) -1;
1124 rc.y = (int)((p->vport.H -y - topOffset)/(p->bmWH.y*p->bmScale)) +1;
1128XY text2screen(
int col,
int row)
1135 topOffset = p->side_top;
1136 if(p->pmenu.top) topOffset += p->buttonSize;
1137 xy.x = (col+1)*p->bmWH.x*p->bmScale;
1138 xy.y = p->vport.H - topOffset - (row+1)*p->bmWH.y*p->bmScale;
1141FXY screen2normalizedScreenScale( GLfloat x, GLfloat y)
1147 xy.x = ((GLfloat)x/(GLfloat)p->vport.W * 2.0f);
1148 xy.y = ((GLfloat)y/(GLfloat)p->vport.H * 2.0f);
1151FXY screen2normalizedScreen( GLfloat x, GLfloat y)
1155 xy = screen2normalizedScreenScale(x,y);
1166 if(!p->optionsLoaded) initOptionsVal();
1169 p->bmScale = p->bmScaleForOptions;
1170 for(j=0;j<lenOptions;j++)
1173 XY xy0 = text2screen(0,j);
1174 xy = screen2normalizedScreen( (GLfloat)xy0.x, (GLfloat)xy0.y);
1175 printString2(xy.x,xy.y,p->optionsVal[j]);
1176 printString2(xy.x,xy.y,optionsText[j]);
1178 p->bmScale = p->bmScaleRegular;
1181int handleOptionPress(
int mouseX,
int mouseY)
1196 p->bmScale = p->bmScaleForOptions;
1197 xys = mouse2screen(mouseX,mouseY);
1199 if (Viewer()->updown) p->side_top = p->vport.H / 2;
1200 xyt = screen2text(xys.x,xys.y);
1202 if( 0 <= xyt.y && xyt.y < lenOptions )
1204 int len = (int) strlen(optionsCase[xyt.y]);
1208 opt = optionsCase[xyt.y][xyt.x];
1211 if(opt ==
' ')
return 0;
1212 p->bmScale = p->bmScaleRegular;
1220 printf(
"toggle EAI");
1228 toggleOrSetStereo(opt-
'0');
1231 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
1232 p->statusbar_pinned = 1 - p->statusbar_pinned;
1233 fwl_set_sbh_pin(p->statusbar_pinned,p->menubar_pinned);
1236 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
1237 p->menubar_pinned = 1 - p->menubar_pinned;
1238 fwl_set_sbh_pin(p->statusbar_pinned,p->menubar_pinned);
1241 fwl_next_ui_colorscheme();
1246 setAnaglyphPrimarySide(opt-
'r',0);
1251 setAnaglyphPrimarySide(opt-
'u',1);
1256 setAnaglyphPrimarySide(opt-
'x',2);
1261 printf(
"reduce eyebase");
1267 printf(
"increase eyebase");
1273 printf(
"reduce screendist");
1274 viewer->screendist -= .02;
1278 fwl_set_emulate_multitouch(1 - fwl_get_emulate_multitouch());
1283 printf(
"set screendist");
1287 printf(
"increase screendist");
1288 viewer->screendist += .02;
1295 printf(
"reduce toe-in");
1296 viewer->stereoParameter *= .9;
1301 printf(
"set toe-in");
1305 printf(
"increase toe-in");
1306 viewer->stereoParameter *= 1.1;
1308 viewer->stereoParameter = min(
viewer->stereoParameter,.01);
1316 tfps = abs(fwl_get_target_fps());
1317 i15 = (int)((
double)tfps / 15.0 + .5);
1318 if(opt ==
'K') i15 /= 2;
1319 if(opt ==
'L') i15 = max(1,i15*2);
1320 if(i15 < 1) tfps = 7;
1321 else tfps = min(3840,(
int)15*i15);
1322 fwl_set_target_fps(tfps);
1329 fwl_getPickraySide(&iside,&ieither);
1331 ieither = 1 - ieither;
1335 fwl_setPickraySide(iside,ieither);
1339 fwl_setOrientation2((fwl_getOrientation2()+90) % 360);
1342 fwl_setOrientation2( (fwl_getOrientation2() + 360 -90) % 360);
1350 shadingStyle = opt -
'R';
1351 fwl_setShadingStyle(shadingStyle);
1355 fwl_setDrawBoundingBoxes(1 - fwl_getDrawBoundingBoxes());
1363 fwl_set_depth_slices(opt -
'a');
1367 fwl_set_allow_DIS(1 - fwl_get_allow_DIS());
1374 fwl_set_modulation(opt -
'e');
1390char * keyboardShortcutHelp[] = {
1392" movement: drag left/right for turns;",
1393" drag up/down for forward/backward",
1395" use the buttons for these motions:",
1396" bird: drag left/right for left/right turns",
1397" drag up/down for foreward/backward",
1399" translation up/down and left/right",
1400" rotation about the viewpoint/camera axis",
1402" rotation: drag left/right or up/down",
1403"Level to bound viewpoint",
1404"Flashlight/headlight",
1405"Collision (and for WALK also gravity)",
1406"Previous, Next viewpoint",
1408"Console messages from the program",
1411"Enter URL of .x3d or .wrl scene"
1414char * keyboardShortcutHelp[] = {
1416" movement: drag left/right for turns;",
1417" drag up/down for forward/backward",
1419" use the buttons for these motions:",
1420" bird: drag left/right for left/right turns",
1421" drag up/down for foreward/backward",
1423" translation up/down and left/right",
1424" rotation about the viewpoint/camera axis",
1426" rotation: drag left/right or up/down",
1427"Level to bound viewpoint",
1428"Flashlight/headlight",
1429"Collision (and for WALK also gravity)",
1430"Previous, Next viewpoint",
1432"Console messages from the program",
1436#elif defined(_MSC_VER_NOT)
1438char * keyboardShortcutHelp[] = {
1440" movement: drag left/right for turns;",
1441" drag up/down for forward/backward",
1443" use the keyboard for these motions:",
1444" 8 k rotation down/up",
1445" u o rotation left/right",
1446" 7 9 rotation about the Z axis",
1447" a z translation forwards/backwards",
1448" j l translation left/right",
1449" p ; translation up/down",
1450" or use arrow keys. to change keychord: press SHIFT->",
1452" rotation: drag left/right or up/down",
1453"EXPLORE Mode - use CTRL-click to recenter",
1454"hit spacebar to get console prompt :, then type help"
1457#elif defined(OLD_HELP)
1459char * keyboardShortcutHelp[] = {
1461" LMB rotation: MX rotation around Y axis; MY rotation around X axis",
1464" LMB movement: MX left/right turns; MY walk forward/backward",
1467" - use CTRL-click to recenter",
1468"Keyboard navigation",
1469" - use arrow keys. to change keychord: press SHIFT> or SHIFT<",
1471" e Switch to Examine navigation mode",
1472" w Switch to Walk navigation mode",
1473" v Go to next viewpoint in the scene",
1474" b Go to previous viewpoint in the scene",
1475" / Print current viewport local pose",
1476" h Toggle headlight",
1477" c Toggle collision detection",
1484char * keyboardShortcutHelp[] = {
1487"Keyboard Viewpoint change:",
1488" PgDn,PgUp,Home,End = Next,Prev,First,Last",
1489"Keyboard commands:",
1490" / Print current viewpoint pose",
1493"Keyboard navigation:",
1495" to change keychord: press SHIFT> or SHIFT<",
1496"Touch cursor control:",
1497" use both PEDAL % and HOVER ^ buttons to move cursor",
1498" use PEDAL % button to drag cursor around",
1503const char *libFreeWRL_get_version();
1508 FXY fxy, fxy2, fxy3;
1509 GLfloat side_bottom_f;
1513 static const char *versionInfo =
"libfreeWRL version ";
1514 xy = text2screen(0,0);
1515 fxy = screen2normalizedScreen((GLfloat)xy.x,(GLfloat)xy.y);
1516 printString2(fxy.x,fxy.y,(
char *)versionInfo);
1517 xy = text2screen((
int)strlen(versionInfo),0);
1518 fxy = screen2normalizedScreen((GLfloat)xy.x,(GLfloat)xy.y);
1519 printString2(fxy.x,fxy.y,(
char*)libFreeWRL_get_version());
1523 fxy2 = screen2normalizedScreenScale((GLfloat)p->bmWH.x, (GLfloat)p->bmWH.y);
1524 fxy2.y *= p->bmScale;
1525 side_bottom_f = -1.0f;
1526 fxy3 = screen2normalizedScreenScale((GLfloat)0, (GLfloat)p->buttonRows * p->buttonSize);
1527 side_bottom_f += fxy3.y;
1530 while(keyboardShortcutHelp[j] != NULL)
1534 printString2(-1.0f, side_bottom_f + (lenhelp-j)*fxy2.y, keyboardShortcutHelp[j]);
1536 if(p->show_status && j > lenhelp)
break;
1540void hudSetConsoleMessage(
char *buffer)
1558 last = ml_new(buffer);
1562 ml_append(p->conlist,last);
1564 if( p->concount > 50 )
1567 free((
char*)p->conlist->elem);
1568 p->conlist = ml_delete_self(p->conlist, p->conlist);
1573void printConsoleText()
1587 xybottom = screen2text(0,p->side_bottom);
1588 jstart = max(0,p->concount-(xybottom.y - 3));
1589 for(__l=_list;__l!=NULL;)
1591 next = ml_next(__l);
1595 XY xy = text2screen(0,j-jstart);
1596 fxy = screen2normalizedScreen((GLfloat)xy.x,(GLfloat)xy.y);
1597 printString2(fxy.x,fxy.y,__l->elem);
1643} button_helps [] = {
1644{ACTION_WALK,
"WALK"},
1649{ACTION_FLY,
"FLY {yaw-z,xy,yaw-pitch,roll}"},
1650{ACTION_EXAMINE,
"EXAMINE"},
1651{ACTION_EXPLORE,
"EXPLORE {examine,recenter}"},
1652{ACTION_SPHERICAL,
"SPHERICAL {pan,zoom}"},
1653{ACTION_TURNTABLE,
"TURNTABLE"},
1654{ACTION_LOOKAT,
"LOOKAT"},
1655{ACTION_YAWZ,
"FLY yaw-z"},
1656{ACTION_YAWPITCH,
"FLY yaw-pitch"},
1657{ACTION_ROLL,
"FLY roll"},
1658{ACTION_XY,
"FLY xy"},
1659{ACTION_DIST,
"DIST (for examine,explore,turntable)"},
1660{ACTION_SHIFT,
"SHIFT Key (turns off sensors)"},
1661{ACTION_HOVER,
"HOVER up-drag isOver mode"},
1662{ACTION_PEDAL,
"PEDAL drags in-scene cursor"},
1663{ACTION_LEVEL,
"LEVEL to bound VP (ViewPoint)"},
1664{ACTION_HEADLIGHT,
"HEADLIGHT"},
1665{ACTION_COLLISION,
"COLLISION (and gravity)"},
1666{ACTION_PREV,
"Prev VP"},
1667{ACTION_NEXT,
"Next VP"},
1668{ACTION_HELP,
"Help"},
1669{ACTION_MESSAGES,
"Console"},
1670{ACTION_OPTIONS,
"Options"},
1671{ACTION_RELOAD,
"Reload"},
1673{ACTION_FILE,
"FILE"},
1674{ACTION_VIEWALL,
"VIEWALL"},
1675{ACTION_BLANK, NULL},
1677const char *help_for_action(
int action){
1679 struct button_help *bh;
1682 bh = &button_helps[i];
1683 if(bh->action == action)
break;
1685 }
while(bh->action != ACTION_BLANK);
1689void convertPng2hexAlpha()
1704 static int mbuts = 1;
1705 static char * butFnames[] = {
"viewall.png"};
1708 FILE* out = fopen(
"hudIcons_octalpha_h",
"w+");
1716 for(ii=0;ii<mbuts;ii++)
1718 int j,k,l,g,rgbmax[3];
1719 texture_load_from_file(&butts, butFnames[ii]);
1725 for(j=0;j<3;j++) rgbmax[j] = 0;
1726 for(j=0;j<butts.x;j++)
1728 for(k=0;k<butts.y;k++)
1732 g = butts.texdata[j*w*4 + k*4 + l];
1733 rgbmax[l] = g > rgbmax[l] ? g : rgbmax[l];
1738 for(j=0;j<butts.x;j++)
1740 for(k=0;k<butts.y;k++)
1747 h = butts.texdata[j*w*4 + k*4 + l];
1748 h = (int)((
float)h/(float)rgbmax[l]*255.0f);
1753 g = g > 255? 255 : g;
1755 butts.texdata[j*w*4 + k*4 + l] = g;
1762 strcpy(butname,butFnames[ii]);
1763 for(j=0;j<(int)strlen(butname);j++)
1764 if(butname[j] ==
'.') {butname[j] =
'\0';
break;}
1765 fprintf(out,
"GLubyte %s[] = {\n",butname);
1772 unsigned char *data;
1780 data = &butts.texdata[0];
1781 for(i=0;i<size;i+=4)
1785 datai = (int)(((
float) data[i] * (
float)data[i+3])/255.0f);
1790 if( datai ==
'"' || datai ==
'\\') {sprintf(str,
"\\%c",datai); lastoct =
false;}
1791 else if( datai >=
'0' && datai <=
'9' && lastoct && lastlen < 4) {sprintf(str,
"\"\"%c",datai); lastoct =
false;}
1792 else if( datai > 32 && datai < 127 ) {sprintf(str,
"%c",datai); lastoct =
false;}
1793 else {sprintf(str,
"\\%o",datai); lastoct =
true;}
1794 fprintf(out,
"%s",str);
1795 m = (int) strlen(str);
1800 fprintf(out,
"\"\n\"");
1804 fprintf(out,
"\"\n");
1807 fprintf(out,
"};\n");
1820 int i, buttonAtlasSizeCol, buttonAtlasSizeRow, buttonAtlasSquared;
1823 p->clipPlane = p->statusBarSize;
1826 if(p->buttonType == 0){
1827 convertPng2hexAlpha();
1830 if(p->buttonType == 1)
1835 static GLubyte * buttonlist [] = {
1837 yawz, xy, yawpitch, roll,
1838 explore, spherical, turntable, lookat, distance, viewall,
1839 shift, hover, pedal, level, headlight,
1840 collision, prev, next, help, messages,
1841 options, reload, url, file, blank
1843 static int actionlist [] = {
1844 ACTION_WALK, ACTION_FLY, ACTION_EXAMINE,
1845 ACTION_YAWZ, ACTION_XY, ACTION_YAWPITCH, ACTION_ROLL,
1846 ACTION_EXPLORE, ACTION_SPHERICAL, ACTION_TURNTABLE, ACTION_LOOKAT, ACTION_DIST, ACTION_VIEWALL,
1847 ACTION_SHIFT, ACTION_HOVER, ACTION_PEDAL, ACTION_LEVEL, ACTION_HEADLIGHT,
1848 ACTION_COLLISION, ACTION_PREV,ACTION_NEXT, ACTION_HELP, ACTION_MESSAGES,
1849 ACTION_OPTIONS,ACTION_RELOAD, ACTION_URL, ACTION_FILE, ACTION_BLANK,
1851 static int NACTION = 28;
1853 static int radiosets [][9] = {
1854 {8,ACTION_FLY,ACTION_WALK,ACTION_EXAMINE,ACTION_EXPLORE,ACTION_SPHERICAL,ACTION_TURNTABLE,ACTION_LOOKAT,ACTION_DIST},
1855 {3,ACTION_MESSAGES,ACTION_OPTIONS,ACTION_HELP},
1861 static int toggles [] = {
1862 ACTION_COLLISION,ACTION_HEADLIGHT,ACTION_SHIFT,ACTION_HOVER,ACTION_PEDAL,
1863 ACTION_HELP,ACTION_MESSAGES,ACTION_OPTIONS,0
1865 static int togglesets [][8] = {{ACTION_FLY,4,ACTION_YAWZ, ACTION_XY, ACTION_YAWPITCH, ACTION_ROLL},{0}};
1867 static int mainbar_linux [] = {
1868 ACTION_WALK, ACTION_FLY, ACTION_EXAMINE,
1869 ACTION_EXPLORE, ACTION_SPHERICAL, ACTION_TURNTABLE, ACTION_LOOKAT, ACTION_VIEWALL, ACTION_DIST,
1870 ACTION_SHIFT, ACTION_HOVER, ACTION_PEDAL, ACTION_LEVEL, ACTION_HEADLIGHT, ACTION_COLLISION, ACTION_PREV,
1871 ACTION_NEXT, ACTION_HELP, ACTION_MESSAGES, ACTION_OPTIONS,
1876 static int *mainbar = NULL;
1878 p->pmenu.nitems = NACTION;
1879 mainbar = mainbar_linux;
1885 p->pmenu.nbitems = i;
1886 }
while(mainbar[i]>-1);
1888#if defined(QNX) || defined(KIOSK)
1889 p->pmenu.top =
true;
1891 p->pmenu.top =
false;
1899 buttonAtlasSizeCol = 8;
1900 buttonAtlasSizeRow = 4;
1901 buttonAtlasSquared = buttonAtlasSizeCol*buttonAtlasSizeRow;
1902 p->pmenu.lumalpha = MALLOC(GLubyte*, 32*32*2 *buttonAtlasSquared);
1903 memset(p->pmenu.lumalpha,0,32*32*2 *buttonAtlasSquared);
1904 p->pmenu.vert= MALLOC(GLfloat*, 3*4*buttonAtlasSquared*
sizeof(GLfloat));
1906 p->pmenu.ind = MALLOC(GLushort*, 3*2*buttonAtlasSquared*
sizeof(GLushort));
1907 p->pmenu.yoffset = 0;
1908 if(p->pmenu.top) p->pmenu.yoffset = p->vport.H - p->buttonSize;
1909 for(i=0;i<p->pmenu.nitems;i++)
1914 p->pmenu.items[i].action = actionlist[i];
1915 p->pmenu.items[i].help = help_for_action(actionlist[i]);
1916 p->pmenu.items[i].isToggle =
false;
1917 p->pmenu.items[i].buttonset = NULL;
1919 while(toggles[j] > 0)
1921 if(p->pmenu.items[i].action == toggles[j])
1923 p->pmenu.items[i].isToggle =
true;
1928 p->pmenu.items[i].radioset = NULL;
1929 p->pmenu.items[i].isRadio =
false;
1931 while(radiosets[j][0] > 0)
1933 for(k=1;k<=radiosets[j][0];k++)
1934 if(p->pmenu.items[i].action == radiosets[j][k])
1936 p->pmenu.items[i].isRadio =
true;
1937 p->pmenu.items[i].radioset = &radiosets[j][0];
1944 p->pmenu.items[i].height = 32;
1945 p->pmenu.items[i].width = 32;
1946 p->pmenu.items[i].lumalpha = MALLOC(GLubyte*, 32 * 32 * 2);
1951 int ibyte, ibit, color;
1954 ibyte = (j*32 + k)/8;
1955 ibit = (j*32 + k)%8;
1956 color = buttonlist[i][ibyte] & (1<<(7-ibit))? 255 : 0;
1960 color = buttonlist[i][ibyte];
1962 p->pmenu.items[i].lumalpha[(j*32 +k)*2 +0] = color;
1963 p->pmenu.items[i].lumalpha[(j*32 +k)*2 +1] = color;
1967 irow = i / buttonAtlasSizeCol;
1968 icol = i % buttonAtlasSizeCol;
1973 p->pmenu.lumalpha[(irow*32 +j)*32*2*buttonAtlasSizeCol + (icol*32 +k)*2 + 0] = p->pmenu.items[i].lumalpha[(j*32 +k)*2 +0];
1974 p->pmenu.lumalpha[(irow*32 +j)*32*2*buttonAtlasSizeCol + (icol*32 +k)*2 + 1] = p->pmenu.items[i].lumalpha[(j*32 +k)*2 +1];
1978 p->pmenu.items[i].tex0[0][0] = (GLfloat)(icol*32 + 0)/(GLfloat)(32*buttonAtlasSizeCol);
1979 p->pmenu.items[i].tex0[1][0] = (GLfloat)(irow*32 + 0)/(GLfloat)(32*buttonAtlasSizeRow);
1980 p->pmenu.items[i].tex0[0][1] = (GLfloat)(icol*32 +32)/(GLfloat)(32*buttonAtlasSizeCol);
1981 p->pmenu.items[i].tex0[1][1] = (GLfloat)(irow*32 +32)/(GLfloat)(32*buttonAtlasSizeRow);
1995 p->pmenu.items[i].tex[kt +0] = p->pmenu.items[i].tex0[0][j];
1996 p->pmenu.items[i].tex[kt +1] = p->pmenu.items[i].tex0[1][k];
2001 glGenTextures(1, &(p->pmenu.textureID));
2002 glBindTexture(GL_TEXTURE_2D, p->pmenu.textureID);
2003 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
2004 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
2006 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 32*buttonAtlasSizeCol, 32*buttonAtlasSizeRow, 0, GL_LUMINANCE_ALPHA , GL_UNSIGNED_BYTE, p->pmenu.lumalpha);
2012 togset = togglesets[kset];
2014 int k, ipact, nact, iact;
2017 for(k=0;k<p->pmenu.nitems;k++){
2018 if(ipact == p->pmenu.items[k].action){
2020 p->pmenu.items[k].buttonset = malloc(
sizeof(buttonSet));
2021 p->pmenu.items[k].buttonset->n = nact;
2022 p->pmenu.items[k].buttonset->index = 0;
2023 p->pmenu.items[k].buttonset->items = malloc(nact *
sizeof(
void*));
2024 for(m=0;m<nact;m++){
2026 p->pmenu.items[k].buttonset->items[m] = NULL;
2028 for(n=0;n<p->pmenu.nitems;n++){
2029 if(iact == p->pmenu.items[n].action){
2030 p->pmenu.items[k].buttonset->items[m] = &p->pmenu.items[n];
2038 togset = togglesets[kset];
2043 for(i=0;i<p->pmenu.nbitems;i++)
2045 int j, k, mi, mv, kv;
2048 int bz = p->buttonSize;
2051 p->pmenu.bitems[i].butrect[0] = 5+(i*bz);
2052 p->pmenu.bitems[i].butrect[1] = 0;
2053 p->pmenu.bitems[i].butrect[2] = 5+(i*bz)+bz;
2054 p->pmenu.bitems[i].butrect[3] = bz;
2068 xyxy[1].x = (GLfloat)p->buttonSize;
2069 xyxy[1].y = (GLfloat)p->buttonSize;
2070 dx = xyxy[1].x - xyxy[0].x;
2076 p->pmenu.bitems[i].vert[kv +0] = p->pmenu.vert[mv+kv +0] = xyxy[j].x + (GLfloat)(i*dx);
2077 p->pmenu.bitems[i].vert[kv +1] = p->pmenu.vert[mv+kv +1] = xyxy[k].y;
2078 p->pmenu.bitems[i].vert[kv +2] = p->pmenu.vert[mv+kv +2] = 0.0f;
2090 p->pmenu.ind[mi +0] = (GLushort)(i*4) +0;
2091 p->pmenu.ind[mi +1] = (GLushort)(i*4) +1;
2092 p->pmenu.ind[mi +2] = (GLushort)(i*4) +3;
2093 p->pmenu.ind[mi +3] = (GLushort)(i*4) +0;
2094 p->pmenu.ind[mi +4] = (GLushort)(i*4) +3;
2095 p->pmenu.ind[mi +5] = (GLushort)(i*4) +2;
2098 for(j=0;j<p->pmenu.nitems;j++){
2099 if(mainbar[i] == p->pmenu.items[j].action){
2100 p->pmenu.bitems[i].item = &p->pmenu.items[j];
2112int getMenuItemByAction(
int iaction)
2116 for(i=0;i<p->pmenu.nitems;i++)
2117 if(p->pmenu.items[i].action == iaction)
2122void setRadioPalsOff(
int *ipals,
int iaction)
2129 for(j=1;j<=ipals[0];j++)
2131 if(ipals[j] != iaction)
2133 i = getMenuItemByAction(ipals[j]);
2135 p->pmenu.items[i].butStatus = 0;
2141void setMenuButton_collision(
int val){
2144 i = getMenuItemByAction(ACTION_COLLISION);
2146 p->pmenu.items[i].butStatus = val;
2148void setMenuButton_consoleText(
int val){
2151 i = getMenuItemByAction(ACTION_MESSAGES);
2153 p->pmenu.items[i].butStatus = val;
2155void setMenuButton_texSize(
int size){
2157 printf(
"text size=%d\n",size);
2160void setMenuButton_headlight(
int val){
2163 i = getMenuItemByAction(ACTION_HEADLIGHT);
2165 p->pmenu.items[i].butStatus = val;
2167void setMenuButton_shift(
int val){
2170 i = getMenuItemByAction(ACTION_SHIFT);
2172 p->pmenu.items[i].butStatus = val;
2174void setMenuButton_hover(
int val){
2177 i = getMenuItemByAction(ACTION_HOVER);
2179 p->pmenu.items[i].butStatus = val;
2181void setMenuButton_pedal(
int val){
2184 i = getMenuItemByAction(ACTION_PEDAL);
2186 p->pmenu.items[i].butStatus = val;
2188void setMenuButton_ctrl(
int ctrl){
2194static int chord2action [] = {ACTION_YAWZ,ACTION_YAWPITCH,ACTION_ROLL,ACTION_XY};
2196void setMenuButton_navModes(
int type,
int dragchord)
2198 int i, newval, iaction;
2204 iaction = ACTION_EXAMINE;
2207 case VIEWER_EXAMINE:
2208 iaction = ACTION_EXAMINE;
2212 iaction = ACTION_WALK;
2215 case VIEWER_TURNTABLE:
2216 iaction = ACTION_TURNTABLE;
2220 iaction = ACTION_LOOKAT;
2223 case VIEWER_EXPLORE:
2224 iaction = ACTION_EXPLORE;
2227 case VIEWER_SPHERICAL:
2228 iaction = ACTION_SPHERICAL;
2232 iaction = ACTION_DIST;
2236#if defined(QNX) || defined(KIOSK)
2237 iaction = ACTION_FLY2;
2239 iaction = ACTION_FLY;
2247 i = getMenuItemByAction(iaction);
2249 if(p->pmenu.items[i].buttonset){
2251 if(iaction == p->pmenu.items[i].action){
2256 if(p->pmenu.items[i].buttonset){
2257 for(j=0;j<p->pmenu.items[i].buttonset->n;j++){
2258 if(p->pmenu.items[i].buttonset->items[j]->action == chord2action[dragchord]){
2259 p->pmenu.items[i].buttonset->index = j;
2269 if(p->pmenu.items[i].isRadio)
2270 setRadioPalsOff(p->pmenu.items[i].radioset,iaction);
2271 p->pmenu.items[i].butStatus = newval;
2276int viewer_getDragChord();
2277void viewer_setDragChord(
int chord);
2280void updateButtonStatus()
2290 int headlight, collision,
navmode, dragchord, ctrl, shift, hover, pedal, consoletext;
2292 headlight = fwl_get_headlight();
2293 collision = fwl_getCollision();
2295 dragchord = viewer_getDragChord();
2296 shift = fwl_getShift();
2297 hover = fwl_getHover();
2298 pedal = fwl_getPedal();
2299 ctrl = fwl_getCtrl();
2300 consoletext = getShowConsoleText();
2303 setMenuButton_shift(shift);
2304 setMenuButton_hover(hover);
2305 setMenuButton_pedal(pedal);
2306 setMenuButton_ctrl(ctrl);
2307 setMenuButton_navModes(
navmode,dragchord);
2308 setMenuButton_headlight(headlight);
2309 setMenuButton_collision(collision);
2310 setMenuButton_consoleText(consoletext);
2314void updateConsoleStatus()
2319 nlines = fwg_get_unread_message_count();
2320 for (i = 0; i<nlines; i++)
2322 buffer = fwg_get_last_message();
2323 hudSetConsoleMessage(buffer);
2329int handleButtonOver(
int mouseX,
int mouseY)
2345 y = p->vport.H - mouseY;
2347 y = mouseY - p->pmenu.yoffset;
2351 ihalf = (p->pmenu.nbitems + 1)/p->buttonRows;
2352 for(i=0;i<p->pmenu.nbitems;i++)
2354 int j,xx,yy,butrect[4];
2355 for(j=0;j<4;j++) butrect[j] = p->pmenu.bitems[i].butrect[j];
2359 xx = x + ihalf * p->buttonSize;
2360 yy = y - p->buttonSize;
2362 if(xx > butrect[0] && xx < butrect[2]
2363 && yy > butrect[1] && yy < butrect[3] )
2372char *frontend_pick_URL(
void);
2373char *frontend_pick_file(
void);
2374void toggleMenu(
int val)
2380 p->showButtons = val > 0 ? 1 : 0;
2385int action2chord(
int iaction){
2386 int ichord = CHORD_YAWZ;
2388 case ACTION_YAWZ: ichord = CHORD_YAWZ;
break;
2389 case ACTION_XY: ichord = CHORD_XY;
break;
2390 case ACTION_YAWPITCH: ichord = CHORD_YAWPITCH;
break;
2391 case ACTION_ROLL: ichord = CHORD_ROLL;
break;
2392 default: ichord = 0;
break;
2397int handleButtonRelease(
int mouseX,
int mouseY)
2404 int i,x,y,ihit,iaction,ihalf;
2416 y = p->vport.H - mouseY;
2418 y = mouseY - p->pmenu.yoffset;
2419 ihalf = (p->pmenu.nbitems + 1)/p->buttonRows;
2421 for(i=0;i<p->pmenu.nbitems;i++)
2423 int j,xx,yy,butrect[4];
2424 for(j=0;j<4;j++) butrect[j] = p->pmenu.bitems[i].butrect[j];
2428 xx = x + ihalf * p->buttonSize;
2429 yy = y - p->buttonSize;
2431 if(xx > butrect[0] && xx < butrect[2]
2432 && yy > butrect[1] && yy < butrect[3] )
2435 iaction = p->pmenu.bitems[i].item->action;
2436 if(p->pmenu.bitems[i].item->butStatus && p->pmenu.bitems[i].item->buttonset ){
2438 p->pmenu.bitems[i].item->buttonset->index++;
2439 p->pmenu.bitems[i].item->buttonset->index = (p->pmenu.bitems[i].item->buttonset->index % 4);
2441 if(p->pmenu.bitems[i].item->isRadio)
2443 setRadioPalsOff(p->pmenu.bitems[i].item->radioset,iaction);
2444 if(p->pmenu.bitems[i].item->isToggle )
2445 p->pmenu.bitems[i].item->butStatus = 1 - p->pmenu.bitems[i].item->butStatus;
2447 p->pmenu.bitems[i].item->butStatus = 1;
2449 else if(p->pmenu.bitems[i].item->isToggle)
2450 p->pmenu.bitems[i].item->butStatus = 1 - p->pmenu.bitems[i].item->butStatus;
2454 fwl_set_viewer_type (VIEWER_WALK);
break;
2464 fwl_set_viewer_type(VIEWER_FLY);
2465 if(p->pmenu.bitems[i].item->buttonset){
2466 int iact, idx, ichord;
2467 idx = p->pmenu.bitems[i].item->buttonset->index;
2468 iact = p->pmenu.bitems[i].item->buttonset->items[idx]->action;
2469 ichord = action2chord(iact);
2470 viewer_setDragChord(ichord);
2473 case ACTION_EXPLORE:
2474 fwl_set_viewer_type(VIEWER_EXPLORE);
break;
2476 fwl_set_viewer_type(VIEWER_LOOKAT);
break;
2477 case ACTION_EXAMINE:
2478 fwl_set_viewer_type (VIEWER_EXAMINE);
break;
2479 case ACTION_SPHERICAL:
2480 fwl_set_viewer_type(VIEWER_SPHERICAL);
break;
2481 case ACTION_TURNTABLE:
2482 fwl_set_viewer_type(VIEWER_TURNTABLE);
break;
2484 fwl_set_viewer_type(VIEWER_DIST);
break;
2485 case ACTION_SHIFT: fwl_setShift(p->pmenu.bitems[i].item->butStatus);
break;
2486 case ACTION_HOVER: fwl_setHover(p->pmenu.bitems[i].item->butStatus);
2488 case ACTION_PEDAL: fwl_setPedal(p->pmenu.bitems[i].item->butStatus);
break;
2489 case ACTION_VIEWALL: viewer_viewall();
break;
2490 case ACTION_LEVEL: viewer_level_to_bound();
break;
2491 case ACTION_HEADLIGHT: fwl_toggle_headlight();
break;
2492 case ACTION_COLLISION: toggle_collision();
break;
2493 case ACTION_PREV: fwl_Prev_ViewPoint();
break;
2494 case ACTION_NEXT: fwl_Next_ViewPoint();
break;
2497 if(!p->pmenu.bitems[i].item->butStatus)
2499 update_status(NULL);
2502 case ACTION_MESSAGES:
2504 update_status(NULL);
2505 showConsoleText(p->pmenu.bitems[i].item->butStatus);
2507 case ACTION_OPTIONS:
2509 update_status(NULL);
2517 #if defined(_MSC_VER) || defined(QNX)
2519 char *fname = frontend_pick_URL();
2522 fwl_replaceWorldNeeded(fname);
2535 #if defined(_MSC_VER) || defined(QNX)
2537 char *fname = frontend_pick_file();
2540 fwl_replaceWorldNeeded(fname);
2553 return ihit == -1 ? 0 : 1;
2555void updateButtonVertices()
2557 int i,j,k,kv,mv,ihalf;
2566 if(p->pmenu.top) p->pmenu.yoffset = (p->vport.H - p->buttonSize - p->pmenu.yoffset);
2568 ihalf = (p->pmenu.nbitems + 1)/p->buttonRows;
2569 for(i=0;i<p->pmenu.nbitems;i++)
2571 int button_xoff, button_yoff;
2573 button_yoff = button_xoff = 0;
2576 button_yoff = p->buttonSize;
2577 button_xoff = -(ihalf * p->buttonSize);
2582 xx = p->pmenu.bitems[i].vert[kv +0];
2583 yy = p->pmenu.bitems[i].vert[kv +1];
2584 xy = screen2normalizedScreen(xx + button_xoff,yy + p->pmenu.yoffset + button_yoff + p->side_bottom);
2586 p->pmenu.vert[mv+kv +0] = xy.x;
2587 p->pmenu.vert[mv+kv +1] = xy.y;
2604 updateButtonVertices();
2610 glScissor(p->vport.X,p->vport.Y + p->pmenu.yoffset+p->side_bottom,p->vport.W -itrim ,p->buttonSize*p->buttonRows);
2612 glEnable(GL_SCISSOR_TEST);
2614 glClearColor(colorClear[0],colorClear[1],colorClear[2],colorClear[3]);
2616 glClear(GL_COLOR_BUFFER_BIT);
2617 glDisable(GL_SCISSOR_TEST);
2620 glActiveTexture ( GL_TEXTURE0 );
2622 glBindTexture ( GL_TEXTURE_2D, p->pmenu.textureID );
2624 ctrl = fwl_getCtrl();
2625 for(i=0;i<p->pmenu.nbitems;i++)
2628 bool highlightIt = p->pmenu.bitems[i].item->butStatus;
2629 do_ctrl = ctrl && i < 8;
2636 glUniform4f(p->color4fLoc,colorButtonCTRL[0],colorButtonCTRL[1],colorButtonCTRL[2],colorButtonCTRL[3]);
2638 glUniform4f(p->color4fLoc,colorButtonHighlight[0],colorButtonHighlight[1],colorButtonHighlight[2],colorButtonHighlight[3]);
2639 glVertexAttribPointer ( p->positionLoc, 3, GL_FLOAT,
2640 GL_FALSE, 0, &(p->pmenu.vert[i*3*4]) );
2642 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2643 GL_FALSE, 0, p->pmenu.items[p->pmenu.nitems-1].tex );
2644 glEnableVertexAttribArray ( p->positionLoc );
2645 glEnableVertexAttribArray ( p->texCoordLoc );
2646 glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, p->pmenu.ind );
2650 glVertexAttribPointer ( p->positionLoc, 3, GL_FLOAT,
2651 GL_FALSE, 0, &(p->pmenu.vert[i*3*4]) );
2655 if(p->pmenu.bitems[i].item->buttonset){
2657 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2658 GL_FALSE, 0, p->pmenu.bitems[i].item->buttonset->items[p->pmenu.bitems[i].item->buttonset->index]->tex );
2660 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2661 GL_FALSE, 0, p->pmenu.bitems[i].item->tex );
2664 glUniform4f(p->color4fLoc,colorButtonIcon[0],colorButtonIcon[1],colorButtonIcon[2],colorButtonIcon[3]);
2665 glEnableVertexAttribArray ( p->positionLoc );
2666 glEnableVertexAttribArray ( p->texCoordLoc );
2667 glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, p->pmenu.ind );
2690void updateViewportSize();
2691void fwl_getWindowSize(
int *width,
int *height);
2692void statusbarHud_DrawCursor(GLint textureID,
int x,
int y){
2693GLfloat cursorVert[] = {
2700GLfloat cursorTex[] = {
2707 GLushort ind[] = {0,1,2,3,4,5};
2711 int i,j,screenWidth,screenHeight;
2712 GLfloat cursorVert2[18];
2718 finishedWithGlobalShader();
2719 glDepthMask(GL_FALSE);
2720 glDisable(GL_DEPTH_TEST);
2721 if(p->programObject == 0) init_ProgramObject();
2722 glUseProgram ( p->programObject );
2725 fwl_getWindowSize(&screenWidth,&screenHeight);
2726 xy = mouse2screen(x,y);
2728 FW_GL_VIEWPORT(0,0,screenWidth,screenHeight);
2730 fxy.x = ((GLfloat)xy.x/(GLfloat)screenWidth * 2.0f);
2731 fxy.y = ((GLfloat)xy.y/(GLfloat)screenHeight * 2.0f);
2739 cursorVert2[i*3 + j] = cursorVert[i*3 +j];
2740 cursorVert2[i*3 +0] += fxy.x;
2741 cursorVert2[i*3 +1] += fxy.y;
2750 glVertexAttribPointer (p->positionLoc, 3, GL_FLOAT,
2751 GL_FALSE, 0, cursorVert2 );
2753 glVertexAttribPointer ( p->texCoordLoc, 2, GL_FLOAT,
2754 GL_FALSE, 0, cursorTex );
2755 glUniform4f(p->color4fLoc,0.7f,0.7f,0.9f,1.0f);
2756 glEnableVertexAttribArray (p->positionLoc );
2757 glEnableVertexAttribArray ( p->texCoordLoc);
2760 glActiveTexture ( GL_TEXTURE0 );
2761 glBindTexture ( GL_TEXTURE_2D, textureID );
2764 glUniform1i ( p->textureLoc, 0 );
2765 glDrawElements ( GL_TRIANGLES, 3*2, GL_UNSIGNED_SHORT, ind );
2771 glEnable(GL_DEPTH_TEST);
2772 glDepthMask(GL_TRUE);
2773 restoreGlobalShader();
2776void updateViewCursorStyle(
int cstyle);
2777void fwl_set_frontend_using_cursor(
int on);
2780 int item = getMenuItemByAction(action);
2783 return p->pmenu.items[item].butStatus;
2795 y = p->vport.H - mouseY;
2797 y = mouseY - p->pmenu.yoffset;
2798 if( y >= 0 && y <= p->buttonSize * p->buttonRows) isOver = 1;
2806 if(mouseY < p->statusBarSize * p->statusBarRows) isOver = 1;
2838void updateViewportSize(){
2844 vportstack = (
Stack*)tg->Mainloop._vportstack;
2845 p->vport = stack_top(
ivec4,vportstack);
2847void updateSBHRows(){
2852 if(p->vport.W < ((p->buttonSize * p->pmenu.nbitems) + 10)){
2854 p->statusBarRows = 1;
2857 p->statusBarRows = 1;
2860int handleStatusbarHud1(
int mev,
int butnum,
int mouseX,
int mouseY,
int windex)
2871 if ((mev == ButtonPress) || (mev == ButtonRelease) )
2877 if(overMenubar(p,mouseY))
2879 if (mev == ButtonRelease){
2880 ihit = handleButtonRelease(mouseX,mouseYY);
2884 p->menubar_pinned = 1 - p->menubar_pinned;
2885 fwl_get_sbh_pin(&p->statusbar_pinned, &p->menubar_pinned);
2886 p->menubar_pinned = 1 - p->menubar_pinned;
2887 fwl_set_sbh_pin(p->statusbar_pinned, p->menubar_pinned);
2888 if(!p->menubar_pinned)
2891 if(!p->statusbar_pinned && !p->showStatus)
2895 if (mev == ButtonPress){
2896 if (showAction(p, ACTION_HELP)) {
2898 ib_over = handleButtonOver(mouseX, mouseYY);
2900 update_status((
char *)p->pmenu.bitems[ib_over].item->help);
2902 update_status(NULL);
2906 }
else if(overStatusbar(p,mouseY)){
2908 if(mev == ButtonRelease){
2909 if(p->wantButtons && !p->showButtons) toggleMenu(1);
2910 if(p->wantStatusbar && !p->statusbar_pinned ) p->showStatus = 1 - p->showStatus;
2915 if (!ihit && showAction(p, ACTION_OPTIONS))
2917 if (mev == ButtonPress)
2918 ihit = handleOptionPress(mouseX,mouseYY);
2923 if (mev == MotionNotify)
2928#elif defined(_MSC_VER)
2931 static int lastover;
2932 if (p->vport.H - mouseYY < 16)
2935 toggleMenu(1 - p->showButtons);
2943 if (p->showButtons == 1){
2947 ihit = handleButtonOver(mouseX,mouseYY);
2957 if(overMenubar(p,mouseY) || overStatusbar(p,mouseY))
2959 p->showButtons = p->wantButtons;
2961 if(overMenubar(p,mouseY)){
2963 if(showAction(p, ACTION_HELP)){
2965 ib_over = handleButtonOver(mouseX,mouseYY);
2967 update_status((
char *)p->pmenu.bitems[ib_over].item->help);
2969 update_status(NULL);
2978 p->showButtons = p->menubar_pinned;
2982 if (showAction(p, ACTION_OPTIONS))
3004int getCursorStyle();
3005int statusbar_handle_mouse1(
int mev,
int butnum,
int mouseX,
int yup,
int windex)
3007 int vpx, vpy, iret, ihandled;
3010 updateViewportSize();
3014 vpy = yup - p->vport.Y;
3015 vpx = mouseX - p->vport.X;
3016 ihandled = handleStatusbarHud1(mev, butnum, vpx, vpy, windex);
3019 fwl_set_frontend_using_cursor(FALSE);
3021 fwl_set_frontend_using_cursor(TRUE);
3026int statusbar_handle_mouse(
int mev,
int butnum,
int mouseX,
int mouseY)
3028 return statusbar_handle_mouse1(mev,butnum,mouseX,mouseY,0);
3031char *getMessageBar();
3032char *fwl_getKeyChord();
3033void fwl_setClipPlane(
int height);
3034int fwl_get_sbh_wantMenubar();
3035int fwl_get_sbh_wantStatusbar();
3036void drawStatusBarSide()
3039void update_pinned(){
3043 fwl_get_sbh_pin(&p->statusbar_pinned,&p->menubar_pinned);
3044 p->wantButtons = fwl_get_sbh_wantMenubar();
3045 p->wantStatusbar = fwl_get_sbh_wantStatusbar();
3047void update_density(){
3048 float density_factor;
3053 density_factor = fwl_getDensityFactor();
3054 ifactor = (int)(density_factor + .5f);
3055 ifactor = max(1,ifactor);
3056 p->bmScaleRegular = ifactor;
3057 p->bmScale = ifactor;
3058 p->bmScaleForOptions = ifactor;
3060 p->statusBarSize = p->bmScaleRegular * 16;
3061 p->buttonSize = (int)(density_factor * 32);
3063int statusbar_getClipPlane(){
3065 int statusbar_height, menubar_height;
3074 statusbar_height = (p->statusbar_pinned && p->wantStatusbar)? p->statusBarSize * p->statusBarRows : 0;
3075 menubar_height = (p->menubar_pinned && p->wantButtons) ? p->buttonSize * p->buttonRows : 0;
3076 vrml_clipplane = statusbar_height + menubar_height;
3077 return vrml_clipplane;
3109 int i,nsides, menu_over_status;
3110 GLfloat side_bottom_f;
3121 if(!p->fontInitialized) initFont();
3122 if(p->programObject == 0) init_ProgramObject();
3125 updateViewportSize();
3128 updateButtonStatus();
3129 updateConsoleStatus();
3131 glDepthMask(GL_FALSE);
3132 glDisable(GL_DEPTH_TEST);
3134 glUseProgram ( p->programObject );
3135 glViewport(p->vport.X, p->vport.Y, p->vport.W, p->vport.H);
3137 p->show_menu = p->wantButtons && (p->menubar_pinned || p->showButtons);
3138 menu_over_status = !p->menubar_pinned && p->showButtons;
3139 p->show_status = p->wantStatusbar && ((p->showStatus || p->statusbar_pinned) && !menu_over_status);
3140 p->show_status = p->show_status || showAction(p, ACTION_HELP);
3145 p->pmenu.yoffset = p->show_status ? p->statusBarSize * p->statusBarRows : 0;
3148 p->clipPlane = (p->show_menu ? p->buttonSize * p->buttonRows : 0) + p->show_status ? p->statusBarSize * p->statusBarRows : 0;
3157 if (Viewer()->updown) nsides = 2;
3158 for (i = 0; i < nsides; i++)
3162 side_bottom_f = -1.0f;
3163 if (Viewer()->updown){
3165 p->side_top = i*(p->vport.H / 2);
3166 p->side_bottom = (1 -i) *(p->vport.H /2);
3167 if(i == 0) side_bottom_f = 0.0f;
3176 int sblen, sslen,itrim;
3186 glScissor(p->vport.X, p->vport.Y + p->side_bottom, p->vport.W -itrim, p->statusBarSize * p->statusBarRows);
3187 glEnable(GL_SCISSOR_TEST);
3189 glClearColor(colorClear[0],colorClear[1],colorClear[2],colorClear[3]);
3190 glClear(GL_COLOR_BUFFER_BIT);
3191 glDisable(GL_SCISSOR_TEST);
3195 glUniform4f(p->color4fLoc,colorStatusbarText[0],colorStatusbarText[1],colorStatusbarText[2],colorStatusbarText[3]);
3196 xy = screen2normalizedScreenScale((GLfloat)p->bmWH.x, (GLfloat)p->bmWH.y);
3199 sblen = (int)(2.0f/xy.x);
3207 printString2(-1.0f, side_bottom_f, pp);
3211 int len, istart,istart1,ilen,lenk,lenkk;
3212 char *strfps, *strdist, *strstatus, *strAkeys;
3215 strAkeys = fwl_getKeyChord();
3216 lenkk = lenk = strlen(strAkeys);
3218 strstatus = getMenuStatus();
3219 len = strlen(strstatus);
3223 if(max(istart1,35) + len + 9 < sblen) {
3225 istart = max(istart1,35);
3226 }
else if(istart1 + len + 9 < sblen){
3229 }
else if(istart1 + len + lenkk < sblen){
3232 }
else if(p->buttonRows == 2){
3235 ilen = sblen - istart;
3239 ilen = sblen - istart - lenkk;
3244 printString3(-1.0f + xy.x*istart, side_bottom_f, strstatus,ilen);
3248 printString3(1.0f - xy.x*(lenk + 4), side_bottom_f, strAkeys,lenk);
3251 strfps = getFpsBar();
3252 printString2(1.0f - xy.x*(4), side_bottom_f, strfps);
3253 strdist = getDistBar();
3254 printString2(1.0f - xy.x*(22), side_bottom_f, strdist);
3260 glUniform4f(p->color4fLoc,colorMessageText[0],colorMessageText[1],colorMessageText[2],colorMessageText[3]);
3262 if (showAction(p, ACTION_HELP))
3263 printKeyboardHelp(p);
3264 if (showAction(p, ACTION_MESSAGES))
3266 if (showAction(p, ACTION_OPTIONS))
3274 glDisableVertexAttribArray( p->texCoordLoc );
3279 glEnable(GL_DEPTH_TEST);
3284int statusbar_getClipPlane(){
3287int statusbar_handle_mouse1(
int mev,
int butnum,
int mouseX,
int yup,
int windex){