00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <math.h>
00022 #include <string.h>
00023 #include "glwin.h"
00024
00025
00026
00027 #if defined(VMDOPENGL)
00028 #define USEOPENGL
00029 #endif
00030
00031 #if defined(USEOPENGL)
00032
00033
00034
00035
00036
00037 #define GL_GLEXT_PROTOTYPES 1
00038 #define GLX_GLXEXT_PROTOTYPES 1
00039
00040 #if (defined(WIN32) || defined(_WIN64)) && defined(_MSC_VER)
00041
00042
00043
00044 #ifndef _WIN32_WINNT
00045 #define _WIN32_WINNT 0x0400
00046 #endif
00047 #include <windows.h>
00048 #include <winuser.h>
00049 #include <GL/gl.h>
00050
00051 #if defined(VMDSPACEWARE) && (defined(WIN32) || defined(_WIN64))
00052 #define OS_WIN32 1
00053 #include "spwmacro.h"
00054 #include "si.h"
00055 #endif
00056 #else
00057
00058
00059
00060 #include <X11/Xlib.h>
00061 #include <X11/keysym.h>
00062 #include <X11/Xatom.h>
00063
00064 #if defined(USEEGL)
00065
00066 #include <EGL/egl.h>
00067 #else
00068
00069 #include <GL/glx.h>
00070 #endif
00071
00072
00073 #include <GL/gl.h>
00074 #endif
00075
00076
00077
00078
00079 #if defined(USEGLEXT)
00080
00081
00082
00083
00084
00085 #if (defined(__linux) || defined(_MSC_VER))
00086 #include <GL/glext.h>
00087 #endif
00088
00089
00090 #if 0 && defined(__APPLE__)
00091 #include <OpenGL/glext.h>
00092 #endif
00093
00094
00095 #ifndef APIENTRY
00096 #define APIENTRY
00097 #endif
00098 #ifndef GLAPI
00099 #define GLAPI extern
00100 #endif
00101
00102 #endif
00103
00104
00105
00106
00107
00108
00109 typedef struct {
00110 #if (defined(WIN32) || defined(_WIN64)) && defined(_MSC_VER)
00111 #if defined(USESPACEWARE)
00112
00113 SiHdl sball;
00114 SiSpwEvent spwevent;
00115 SiGetEventData spwedata;
00116 #else
00117 int foo;
00118 #endif
00119 #else
00120
00121 Display *dpy;
00122 Window drv_win;
00123 Window app_win;
00124 Atom ev_motion;
00125 Atom ev_button_press;
00126 Atom ev_button_release;
00127 Atom ev_command;
00128 #endif
00129 } spaceballhandle;
00130
00131
00132
00133 typedef struct {
00134 int event;
00135 int rx;
00136 int ry;
00137 int rz;
00138 int tx;
00139 int ty;
00140 int tz;
00141 int buttons;
00142 int period;
00143 } spaceballevent;
00144
00145
00146 #if !(defined(WIN32) || defined(_WIN64))
00147
00148 typedef struct {
00149 int isvalid;
00150 GLhandleARB ProgramObject;
00151 GLhandleARB VertexShaderObject;
00152 GLhandleARB FragmentShaderObject;
00153 int lastshader;
00154 } glsl_shader;
00155 #endif
00156
00157
00158 typedef struct {
00159 int oglmajor;
00160 int oglminor;
00161 int oglrelease;
00163 int hasglshaderobjectsarb;
00164 int hasglvertexshaderarb;
00165 int hasglfragmentshaderarb;
00166 int hasglgeometryshader4arb;
00167 int hasglsampleshadingarb;
00168 int hasglshadinglangarb;
00169 int hasglfborendertarget;
00170 int hasgetvideosyncsgi;
00171
00172
00173 #if defined(GL_ARB_shader_objects)
00174
00175 GLhandleARB (APIENTRY *p_glCreateShaderObjectARB)(GLenum shaderType);
00176 GLhandleARB (APIENTRY *p_glCreateProgramObjectARB)(void);
00177 void (APIENTRY *p_glUseProgramObjectARB)(GLhandleARB programObj);
00178 void (APIENTRY *p_glDetachObjectARB)(GLhandleARB containerObj, GLhandleARB attachedObj);
00179 void (APIENTRY *p_glGetInfoLogARB)(GLhandleARB obj,GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
00180 void (APIENTRY *p_glGetObjectParameterivARB)(GLhandleARB obj, GLenum pname, GLint *params);
00181 void (APIENTRY *p_glLinkProgramARB)(GLhandleARB programObj);
00182 void (APIENTRY *p_glDeleteObjectARB)(GLhandleARB obj);
00183 void (APIENTRY *p_glAttachObjectARB)(GLhandleARB containerObj, GLhandleARB obj);
00184 void (APIENTRY *p_glCompileShaderARB)(GLhandleARB shaderObj);
00185 void (APIENTRY *p_glShaderSourceARB)(GLhandleARB shaderObj, GLsizei count, const GLcharARB **strings, const GLint *length);
00186 GLint (APIENTRY *p_glGetUniformLocationARB)(GLhandleARB programObject, const GLcharARB *name);
00187 void (APIENTRY *p_glUniform1iARB)(GLint location, GLint v0);
00188 void (APIENTRY *p_glUniform1fvARB)(GLint location, GLsizei count, GLfloat *value);
00189 void (APIENTRY *p_glUniform2fvARB)(GLint location, GLsizei count, GLfloat *value);
00190 void (APIENTRY *p_glUniform3fvARB)(GLint location, GLsizei count, GLfloat *value);
00191 void (APIENTRY *p_glUniform4fvARB)(GLint location, GLsizei count, GLfloat *value);
00192
00193
00194 void (APIENTRY *p_glGenFramebuffers)(GLsizei n, GLuint * framebuffers);
00195 void (APIENTRY *p_glBindFramebuffer)(GLenum target, GLuint framebuffer);
00196 void (APIENTRY *p_glGenRenderbuffers)(GLsizei n, GLuint * renderbuffers);
00197 void (APIENTRY *p_glBindRenderbuffer)(GLenum target, GLuint renderbuffer);
00198 void (APIENTRY *p_glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
00199 void (APIENTRY *p_glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
00200 void (APIENTRY *p_glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
00201 GLenum (APIENTRY *p_glCheckFramebufferStatus)(GLenum target);
00202 void (APIENTRY *p_glDeleteRenderbuffers)(GLsizei n, const GLuint * renderbuffers);
00203 void (APIENTRY *p_glDeleteFramebuffers)(GLsizei n, const GLuint * framebuffers);
00204 void (APIENTRY *p_glDrawBuffers)(GLsizei n, const GLenum *bufs);
00205 #endif
00206
00207
00208 int (APIENTRY *p_glXGetVideoSyncSGI)(GLuint *count);
00209 } glwin_ext_fctns;
00210
00211
00212 #if defined(GL_ARB_shader_objects)
00213
00214 #define GLCREATESHADEROBJECTARB ext->p_glCreateShaderObjectARB
00215 #define GLCREATEPROGRAMOBJECTARB ext->p_glCreateProgramObjectARB
00216 #define GLUSEPROGRAMOBJECTARB ext->p_glUseProgramObjectARB
00217 #define GLDETACHOBJECTARB ext->p_glDetachObjectARB
00218 #define GLGETINFOLOGARB ext->p_glGetInfoLogARB
00219 #define GLGETOBJECTPARAMETERIVARB ext->p_glGetObjectParameterivARB
00220 #define GLLINKPROGRAMARB ext->p_glLinkProgramARB
00221 #define GLDELETEOBJECTARB ext->p_glDeleteObjectARB
00222 #define GLATTACHOBJECTARB ext->p_glAttachObjectARB
00223 #define GLCOMPILESHADERARB ext->p_glCompileShaderARB
00224 #define GLSHADERSOURCEARB ext->p_glShaderSourceARB
00225 #define GLGETUNIFORMLOCATIONARB ext->p_glGetUniformLocationARB
00226 #define GLUNIFORM1IARB ext->p_glUniform1iARB
00227 #define GLUNIFORM1FVARB ext->p_glUniform1fvARB
00228 #define GLUNIFORM2FVARB ext->p_glUniform2fvARB
00229 #define GLUNIFORM3FVARB ext->p_glUniform3fvARB
00230 #define GLUNIFORM4FVARB ext->p_glUniform4fvARB
00231
00232
00233 #define GLGENFRAMEBUFFERS ext->p_glGenFramebuffers
00234 #define GLBINDFRAMEBUFFER ext->p_glBindFramebuffer
00235 #define GLGENRENDERBUFFERS ext->p_glGenRenderbuffers
00236 #define GLBINDRENDERBUFFER ext->p_glBindRenderbuffer
00237 #define GLRENDERBUFFERSTORAGE ext->p_glRenderbufferStorage
00238 #define GLFRAMEBUFFERTEXTURE2D ext->p_glFramebufferTexture2D
00239 #define GLFRAMEBUFFERRENDERBUFFER ext->p_glFramebufferRenderbuffer
00240 #define GLCHECKFRAMEBUFFERSTATUS ext->p_glCheckFramebufferStatus
00241 #define GLDELETERENDERBUFFERS ext->p_glDeleteRenderbuffers
00242 #define GLDELETEFRAMEBUFFERS ext->p_glDeleteFramebuffers
00243 #define GLDRAWBUFFERS ext->p_glDrawBuffers
00244
00245
00246 #define GLXGETVIDEOSYNCSGI ext->p_glXGetVideoSyncSGI
00247 #endif
00248
00249
00250
00251 typedef struct {
00252 #if (defined(WIN32) || defined(_WIN64)) && defined(_MSC_VER)
00253 HWND hWnd;
00254 HDC hDC;
00255 HGLRC hRC;
00256 long scrwidth;
00257 long scrheight;
00258 long MouseFlags;
00259 #else
00260 int scrnum;
00261 Display *dpy;
00262 Window root;
00263 Window win;
00264 Atom wmDeleteWindow;
00265 #if defined(USEEGL)
00266 EGLDisplay egldpy;
00267 EGLConfig eglconf;
00268 EGLSurface eglsurf;
00269 EGLContext eglctx;
00270 #else
00271 GLXContext ctx;
00272 #endif
00273 #endif
00274
00275 int havestencil;
00276 int instereo;
00278 int width;
00279 int height;
00280 int xpos;
00281 int ypos;
00282 int mousex;
00283 int mousey;
00284 int evdev;
00285 int evval;
00286 char evkey;
00288 int havefocus;
00289 spaceballhandle *sball;
00290 spaceballevent sballevent;
00292 glwin_ext_fctns *ext;
00293 } oglhandle;
00294
00295
00296 #if defined(USEOPENGL) && !defined(USEEGL) && !(defined(WIN32) || defined(_WIN64)) && !defined(_MSC_VER)
00297 static int glx_query_extension(Display *dpy, const char *extname) {
00298 char *ext;
00299 char *endext;
00300 if (!extname)
00301 return 0;
00302
00303
00304 ext = (char *) glXQueryExtensionsString(dpy, 0);
00305 if (ext != NULL) {
00306 endext = ext + strlen(ext);
00307 while (ext < endext) {
00308 size_t n = strcspn(ext, " ");
00309 if ((strlen(extname) == n) && (strncmp(extname, ext, n) == 0)) {
00310 return 1;
00311 break;
00312 }
00313 ext += (n + 1);
00314 }
00315 }
00316
00317 return 0;
00318 }
00319 #endif
00320
00321
00322
00323 static void quat_rot_matrix(float *m, const float *q) {
00324 m[ 0] = 1.0f - 2.0f * (q[1] * q[1] + q[2] * q[2]);
00325 m[ 1] = 2.0f * (q[0] * q[1] - q[2] * q[3]);
00326 m[ 2] = 2.0f * (q[2] * q[0] + q[1] * q[3]);
00327 m[ 3] = 0.0f;
00328
00329 m[ 4] = 2.0f * (q[0] * q[1] + q[2] * q[3]);
00330 m[ 5] = 1.0f - 2.0f * (q[2] * q[2] + q[0] * q[0]);
00331 m[ 6] = 2.0f * (q[1] * q[2] - q[0] * q[3]);
00332 m[ 7] = 0.0f;
00333
00334 m[ 8] = 2.0f * (q[2] * q[0] - q[1] * q[3]);
00335 m[ 9] = 2.0f * (q[1] * q[2] + q[0] * q[3]);
00336 m[10] = 1.0f - 2.0f * (q[1] * q[1] + q[0] * q[0]);
00337 m[11] = 0.0f;
00338
00339 m[12] = 0.0f;
00340 m[13] = 0.0f;
00341 m[14] = 0.0f;
00342 m[15] = 1.0f;
00343 }
00344
00345
00346
00347 typedef void (APIENTRY *glwin_fctnptr)(void);
00348
00349
00350 void * glwin_get_procaddress(const char * procname) {
00351 void *fctn = NULL;
00352 if (!procname)
00353 return NULL;
00354
00355 #if defined(_MSC_VER)
00356
00357
00358
00359
00360 fctn = (glwin_fctnptr) wglGetProcAddress((LPCSTR) procname);
00361 #else
00362
00363 #if !defined(_MSC_VER) && !defined(__APPLE__)
00364
00365
00366
00367 fctn = glXGetProcAddressARB((const GLubyte *) procname);
00368 #if 0
00369 printf("GL fctn '%s' %s\n", procname, (fctn) ? "available" : "NULL");
00370 #endif
00371 #endif
00372
00373
00374 #if defined(GLX_ARB_get_proc_address)
00375
00376
00377
00378
00379 if (fctn == NULL) {
00380 fctn = glXGetProcAddressARB((const GLubyte *) procname);
00381 #if 0
00382 printf("GLARB fctn '%s' %s\n", procname, (fctn) ? "available" : "NULL");
00383 #endif
00384 }
00385 #endif
00386 #endif
00387
00388 #if 0
00389 printf("GL fctn '%s' %s\n", procname, (fctn) ? "available" : "NULL");
00390 #endif
00391
00392 return fctn;
00393 }
00394
00395
00396
00397 void glwin_init_exts(void * voidhandle) {
00398 oglhandle * handle = (oglhandle *) voidhandle;
00399 if (handle == NULL)
00400 return;
00401 glwin_ext_fctns *ext = handle->ext;
00402
00403
00404
00405 memset(ext, 0, sizeof(glwin_ext_fctns));
00406
00407 #if defined(GL_ARB_shading_language_100)
00408
00409 if (glwin_query_extension("GL_ARB_shading_language_100")) {
00410 ext->hasglshadinglangarb = 1;
00411 }
00412 #endif
00413
00414 #if defined(GL_ARB_shader_objects)
00415 if (glwin_query_extension("GL_ARB_shader_objects")) {
00416 ext->p_glCreateShaderObjectARB = (GLhandleARB (APIENTRY *)(GLenum)) glwin_get_procaddress("glCreateShaderObjectARB");
00417 ext->p_glCreateProgramObjectARB = (GLhandleARB (APIENTRY *)(void)) glwin_get_procaddress("glCreateProgramObjectARB");
00418 ext->p_glUseProgramObjectARB = (void (APIENTRY *)(GLhandleARB)) glwin_get_procaddress("glUseProgramObjectARB");
00419 ext->p_glDetachObjectARB = (void (APIENTRY *)(GLhandleARB, GLhandleARB)) glwin_get_procaddress("glDetachObjectARB");
00420 ext->p_glGetInfoLogARB = (void (APIENTRY *)(GLhandleARB, GLsizei, GLsizei *, GLcharARB *)) glwin_get_procaddress("glGetInfoLogARB");
00421 ext->p_glGetObjectParameterivARB = (void (APIENTRY *)(GLhandleARB, GLenum, GLint *)) glwin_get_procaddress("glGetObjectParameterivARB");
00422 ext->p_glLinkProgramARB = (void (APIENTRY *)(GLhandleARB)) glwin_get_procaddress("glLinkProgramARB");
00423 ext->p_glDeleteObjectARB = (void (APIENTRY *)(GLhandleARB)) glwin_get_procaddress("glDeleteObjectARB");
00424 ext->p_glAttachObjectARB = (void (APIENTRY *)(GLhandleARB, GLhandleARB)) glwin_get_procaddress("glAttachObjectARB");
00425 ext->p_glCompileShaderARB = (void (APIENTRY *)(GLhandleARB)) glwin_get_procaddress("glCompileShaderARB");
00426 ext->p_glShaderSourceARB = (void (APIENTRY *)(GLhandleARB, GLsizei, const GLcharARB **, const GLint *)) glwin_get_procaddress("glShaderSourceARB");
00427 ext->p_glGetUniformLocationARB = (GLint (APIENTRY *)(GLhandleARB programObject, const GLcharARB *name)) glwin_get_procaddress("glGetUniformLocationARB");
00428 ext->p_glUniform1iARB = (void (APIENTRY *)(GLint location, GLint v0)) glwin_get_procaddress("glUniform1iARB");
00429 ext->p_glUniform1fvARB = (void (APIENTRY *)(GLint location, GLsizei count, GLfloat *value)) glwin_get_procaddress("glUniform1fvARB");
00430 ext->p_glUniform2fvARB = (void (APIENTRY *)(GLint location, GLsizei count, GLfloat *value)) glwin_get_procaddress("glUniform2fvARB");
00431 ext->p_glUniform3fvARB = (void (APIENTRY *)(GLint location, GLsizei count, GLfloat *value)) glwin_get_procaddress("glUniform3fvARB");
00432 ext->p_glUniform4fvARB = (void (APIENTRY *)(GLint location, GLsizei count, GLfloat *value)) glwin_get_procaddress("glUniform4fvARB");
00433
00434 if (ext->p_glCreateShaderObjectARB != NULL && ext->p_glCreateProgramObjectARB != NULL &&
00435 ext->p_glUseProgramObjectARB != NULL && ext->p_glDetachObjectARB != NULL &&
00436 ext->p_glGetInfoLogARB != NULL && ext->p_glGetObjectParameterivARB != NULL &&
00437 ext->p_glLinkProgramARB != NULL && ext->p_glDeleteObjectARB != NULL &&
00438 ext->p_glAttachObjectARB != NULL && ext->p_glCompileShaderARB != NULL &&
00439 ext->p_glShaderSourceARB != NULL && ext->p_glGetUniformLocationARB != NULL &&
00440 ext->p_glUniform1iARB != NULL && ext->p_glUniform1fvARB != NULL &&
00441 ext->p_glUniform2fvARB != NULL && ext->p_glUniform3fvARB != NULL &&
00442 ext->p_glUniform4fvARB != NULL) {
00443 ext->hasglshaderobjectsarb = 1;
00444 }
00445 }
00446 #endif
00447
00448 #if defined(GL_ARB_vertex_shader)
00449 if (glwin_query_extension("GL_ARB_vertex_shader")) {
00450 ext->hasglvertexshaderarb = 1;
00451 }
00452 #endif
00453
00454 #if defined(GL_ARB_fragment_shader)
00455 if (glwin_query_extension("GL_ARB_fragment_shader")) {
00456 ext->hasglfragmentshaderarb = 1;
00457 }
00458 #endif
00459
00460 #if defined(GL_ARB_geometry_shader4)
00461 if (glwin_query_extension("GL_ARB_geometry_shader4")) {
00462 ext->hasglgeometryshader4arb = 1;
00463 }
00464 #endif
00465
00466 if (glwin_query_extension("GL_ARB_sample_shading")) {
00467 ext->hasglsampleshadingarb = 1;
00468 }
00469
00470 #if defined(GL_ARB_framebuffer_object)
00471
00472 ext->p_glGenFramebuffers = (void (APIENTRY *)(GLsizei n, GLuint * framebuffers)) glwin_get_procaddress("glGenFramebuffers");
00473 ext->p_glBindFramebuffer = (void (APIENTRY *)(GLenum target, GLuint framebuffer)) glwin_get_procaddress("glBindFramebuffer");
00474 ext->p_glGenRenderbuffers = (void (APIENTRY *)(GLsizei n, GLuint * renderbuffers)) glwin_get_procaddress("glGenRenderbuffers");
00475 ext->p_glBindRenderbuffer = (void (APIENTRY *)(GLenum target, GLuint renderbuffer)) glwin_get_procaddress("glBindRenderbuffer");
00476 ext->p_glRenderbufferStorage = (void (APIENTRY *)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)) glwin_get_procaddress("glRenderbufferStorage");
00477 ext->p_glFramebufferTexture2D = (void (APIENTRY *)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)) glwin_get_procaddress("glFramebufferTexture2D");
00478 ext->p_glFramebufferRenderbuffer = (void (APIENTRY *)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)) glwin_get_procaddress("glFramebufferRenderbuffer");
00479 ext->p_glCheckFramebufferStatus = (GLenum (APIENTRY *)(GLenum target)) glwin_get_procaddress("glCheckFramebufferStatus");
00480 ext->p_glDeleteRenderbuffers = (void (APIENTRY *)(GLsizei n, const GLuint * renderbuffers)) glwin_get_procaddress("glDeleteRenderbuffers");
00481 ext->p_glDeleteFramebuffers = (void (APIENTRY *)(GLsizei n, const GLuint * framebuffers)) glwin_get_procaddress("glDeleteFramebuffers");
00482 ext->p_glDrawBuffers = (void (APIENTRY *)(GLsizei n, const GLenum *bufs)) glwin_get_procaddress("glDrawBuffers");
00483
00484 if (ext->p_glGenFramebuffers != NULL &&
00485 ext->p_glBindFramebuffer != NULL &&
00486 ext->p_glGenRenderbuffers != NULL &&
00487 ext->p_glBindRenderbuffer != NULL &&
00488 ext->p_glRenderbufferStorage != NULL &&
00489 ext->p_glFramebufferTexture2D != NULL &&
00490 ext->p_glFramebufferRenderbuffer != NULL &&
00491 ext->p_glCheckFramebufferStatus != NULL &&
00492 ext->p_glDeleteRenderbuffers != NULL &&
00493 ext->p_glDeleteFramebuffers != NULL &&
00494 ext->p_glDrawBuffers != NULL) {
00495 ext->hasglfborendertarget = 1;
00496 }
00497 #endif
00498
00499 #if !(defined(WIN32) || defined(_WIN64))
00500 if (glx_query_extension(handle->dpy, "GLX_SGI_video_sync")) {
00501 ext->p_glXGetVideoSyncSGI = (int (APIENTRY *)(GLuint *count)) glwin_get_procaddress("glXGetVideoSyncSGI");
00502
00503 if (ext->p_glXGetVideoSyncSGI != NULL)
00504 ext->hasgetvideosyncsgi = 1;
00505 }
00506 #endif
00507
00508 }
00509
00510
00511 #if !(defined(WIN32) || defined(_WIN64)) && !defined(_MSC_VER)
00512
00513
00514
00515
00516
00517
00518
00519 #define SBALL_COMMAND_NONE 0
00520 #define SBALL_COMMAND_APP_WINDOW 27695
00521 #define SBALL_COMMAND_APP_SENSITIVITY 27696
00522
00523
00524 static spaceballhandle * spaceball_attach(Display *dpy, Window win) {
00525
00526 spaceballhandle *handle = (spaceballhandle *) calloc(1, sizeof(spaceballhandle));
00527
00528
00529 handle->ev_motion = XInternAtom(dpy, "MotionEvent", True);
00530 handle->ev_button_press = XInternAtom(dpy, "ButtonPressEvent", True);
00531 handle->ev_button_release = XInternAtom(dpy, "ButtonReleaseEvent", True);
00532 handle->ev_command = XInternAtom(dpy, "CommandEvent", True);
00533
00534 if (!handle->ev_motion || !handle->ev_button_press ||
00535 !handle->ev_button_release || !handle->ev_command) {
00536 free(handle);
00537 return NULL;
00538 }
00539
00540
00541 Window root = RootWindow(dpy, DefaultScreen(dpy));
00542
00543
00544 Atom ActualType;
00545 int ActualFormat;
00546 unsigned long NItems, BytesReturn;
00547 unsigned char *PropReturn = NULL;
00548 XGetWindowProperty(dpy, root, handle->ev_command, 0, 1, 0,
00549 AnyPropertyType, &ActualType, &ActualFormat, &NItems,
00550 &BytesReturn, &PropReturn );
00551 if (PropReturn == NULL) {
00552 free(handle);
00553 return NULL;
00554 }
00555 handle->drv_win = *(Window *) PropReturn;
00556 XFree(PropReturn);
00557
00558 XTextProperty sball_drv_winname;
00559 if (XGetWMName(dpy, handle->drv_win, &sball_drv_winname) != 0) {
00560 if (!strcmp("Magellan Window", (char *) sball_drv_winname.value)) {
00561
00562 XEvent msg;
00563 msg.type = ClientMessage;
00564 msg.xclient.format = 16;
00565 msg.xclient.send_event = 0;
00566 msg.xclient.display = dpy;
00567 msg.xclient.window = handle->drv_win;
00568 msg.xclient.message_type = handle->ev_command;
00569
00570 msg.xclient.data.s[0] = (short) (((win)>>16)&0x0000FFFF);
00571 msg.xclient.data.s[1] = (short) (((win)) &0x0000FFFF);
00572 msg.xclient.data.s[2] = SBALL_COMMAND_APP_WINDOW;
00573
00574 int rc = XSendEvent(dpy, handle->drv_win, 0, 0x0000, &msg);
00575 XFlush(dpy);
00576 if (rc == 0) {
00577 free(handle);
00578 return NULL;
00579 }
00580 }
00581
00582 XFree(sball_drv_winname.value);
00583 }
00584
00585 return handle;
00586 }
00587
00588
00589 static void spaceball_close(spaceballhandle *handle) {
00590 free(handle);
00591 }
00592
00593
00594 static int spaceball_decode_event(spaceballhandle *handle, const XEvent *xev, spaceballevent *sballevent) {
00595 unsigned int evtype;
00596
00597 if (handle == NULL || xev == NULL || sballevent == NULL)
00598 return 0;
00599
00600 if (xev->type != ClientMessage)
00601 return 0;
00602
00603 evtype = xev->xclient.message_type;
00604 if (evtype == handle->ev_motion) {
00605
00606
00607 sballevent->tx += xev->xclient.data.s[2];
00608 sballevent->ty += xev->xclient.data.s[3];
00609 sballevent->tz += xev->xclient.data.s[4];
00610 sballevent->rx += xev->xclient.data.s[5];
00611 sballevent->ry += xev->xclient.data.s[6];
00612 sballevent->rz += xev->xclient.data.s[7];
00613 sballevent->period += xev->xclient.data.s[8];
00614 sballevent->event = 1;
00615 return 1;
00616 } else if (evtype == handle->ev_button_press) {
00617 sballevent->buttons |= (1 << xev->xclient.data.s[2]);
00618 sballevent->event = 1;
00619 return 1;
00620 } else if (evtype == handle->ev_button_release) {
00621 sballevent->buttons &= ~(1 << xev->xclient.data.s[2]);
00622 sballevent->event = 1;
00623 return 1;
00624 }
00625
00626 return 0;
00627 }
00628
00629
00630 static void spaceball_init_event(spaceballevent *sballevent) {
00631 memset(sballevent, 0, sizeof(spaceballevent));
00632 }
00633
00634
00635 static void spaceball_clear_event(spaceballevent *sballevent) {
00636 sballevent->tx = 0;
00637 sballevent->ty = 0;
00638 sballevent->tz = 0;
00639 sballevent->rx = 0;
00640 sballevent->ry = 0;
00641 sballevent->rz = 0;
00642 sballevent->period = 0;
00643 sballevent->event = 0;
00644 }
00645
00646
00647 static oglhandle *glwin_alloc_init(void) {
00648 oglhandle * handle = (oglhandle *) calloc(1, sizeof(oglhandle));
00649 if (handle == NULL)
00650 return NULL;
00651
00652 #if defined(VMDOPENGL)
00653
00654
00655 if (getenv("VMDGDISPLAY") != NULL) {
00656 handle->dpy = XOpenDisplay(getenv("VMDGDISPLAY"));
00657 } else {
00658 handle->dpy = XOpenDisplay(getenv("DISPLAY"));
00659 }
00660 #else
00661 handle->dpy = XOpenDisplay(getenv("DISPLAY"));
00662 #endif
00663 if (handle->dpy == NULL) {
00664 free(handle);
00665 return NULL;
00666 }
00667
00668 handle->scrnum = DefaultScreen(handle->dpy);
00669 handle->root = RootWindow(handle->dpy, handle->scrnum);
00670 handle->havestencil = 0;
00671 handle->instereo = 0;
00672 handle->evdev = GLWIN_EV_NONE;
00673 handle->havefocus = 0;
00674
00675 handle->ext = (glwin_ext_fctns *) calloc(1, sizeof(glwin_ext_fctns));
00676
00677 return handle;
00678 }
00679
00680
00681
00682
00683
00684 void * glwin_create(const char * wintitle, int width, int height) {
00685 #if defined(USEEGL)
00686
00687 oglhandle * handle;
00688 XSetWindowAttributes attr;
00689 unsigned long mask;
00690 int num_visuals;
00691 XVisualInfo vistemplate;
00692 XVisualInfo *vis=NULL;
00693 XSizeHints sizeHints;
00694 GLint stencilbits;
00695 EGLint eglmaj, eglmin;
00696 EGLint num_config=0;
00697
00698 #if defined(USEOPENGLES2)
00699 #define GLWIN_RENDERABLE_TYPE EGL_OPENGL_ES2_BIT
00700 #else
00701 #define GLWIN_RENDERABLE_TYPE EGL_OPENGL_BIT
00702 #endif
00703
00704 EGLint eglnormalattrib[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8,
00705 EGL_BLUE_SIZE, 8,
00706 EGL_DEPTH_SIZE, 16,
00707 EGL_STENCIL_SIZE, 1,
00708
00709 EGL_RENDERABLE_TYPE, GLWIN_RENDERABLE_TYPE,
00710
00711 EGL_NONE };
00712 EGLint eglfailsafeattrib[] = { EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1,
00713 EGL_BLUE_SIZE, 1,
00714
00715
00716 EGL_RENDERABLE_TYPE, GLWIN_RENDERABLE_TYPE,
00717
00718 EGL_NONE };
00719
00720 handle = glwin_alloc_init();
00721 handle->width = width;
00722 handle->height = height;
00723
00724
00725 #if 1
00726 handle->egldpy = eglGetDisplay(handle->dpy);
00727 #else
00728 handle->egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
00729 #endif
00730 if (handle->egldpy == EGL_NO_DISPLAY) {
00731 printf("glwin_create(): Failed to connect to EGL display\n");
00732 free(handle);
00733 return NULL;
00734 }
00735
00736 if (eglInitialize(handle->egldpy, &eglmaj, &eglmin) == EGL_FALSE) {
00737 printf("glwin_create(): Failed to initialize EGL display connection\n");
00738 free(handle);
00739 return NULL;
00740 #if 1
00741 } else {
00742 printf("EGL init dpy version: %d.%d\n", eglmaj, eglmin);
00743 #endif
00744 }
00745
00746
00747 handle->havestencil = 1;
00748 handle->instereo = 0;
00749 if (eglChooseConfig(handle->egldpy, eglnormalattrib, &handle->eglconf, 1, &num_config) == EGL_FALSE) {
00750 printf("eglChooseConfig(1) %d configs\n", num_config);
00751 if (eglChooseConfig(handle->egldpy, eglfailsafeattrib, &handle->eglconf, 1, &num_config) == EGL_FALSE) {
00752 printf("Error: eglChooseConfig() failed\n");
00753 free(handle);
00754 return NULL;
00755 }
00756 handle->havestencil = 0;
00757 }
00758 printf("eglChooseConfig() %d configs\n", num_config);
00759
00760
00761 EGLint vid;
00762 if (eglGetConfigAttrib(handle->egldpy, handle->eglconf, EGL_NATIVE_VISUAL_ID, &vid) == EGL_FALSE) {
00763 printf("Error: eglGetConfigAttrib() failed\n");
00764 return NULL;
00765 }
00766
00767 vistemplate.visualid = vid;
00768 vis = XGetVisualInfo(handle->dpy, VisualIDMask, &vistemplate, &num_visuals);
00769 if (vis == NULL) {
00770 printf("Error: failed to obtain EGL-compatible X visual...\n");
00771 free(handle);
00772 return NULL;
00773 }
00774
00775
00776 #if defined(USEOPENGLES2)
00777
00778 if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
00779 printf("Error: failed to bind OpenGL ES API\n");
00780 free(handle);
00781 return NULL;
00782 }
00783 #else
00784
00785 if (eglBindAPI(EGL_OPENGL_API) == EGL_FALSE) {
00786 printf("Error: failed to bind full OpenGL API\n");
00787 free(handle);
00788 return NULL;
00789 }
00790 #endif
00791
00792
00793
00794 attr.background_pixel = 0;
00795 attr.border_pixel = 0;
00796 attr.colormap = XCreateColormap(handle->dpy, handle->root,
00797 vis->visual, AllocNone);
00798
00799 attr.event_mask = StructureNotifyMask | ExposureMask;
00800 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
00801
00802 handle->win = XCreateWindow(handle->dpy, handle->root, 0, 0, width, height,
00803 0, vis->depth, InputOutput,
00804 vis->visual, mask, &attr );
00805
00806 #if 0
00807
00808 Atom bypasscomp = X11_XInternAtom(handle->dpy, "_NET_WM_BYPASS_COMPOSITOR", False);
00809 const long bypasscomp_on = 1;
00810 X11_XChangeProperty(handle->dpy, handle->win, bypasscomp, XA_CARDINAL, 32,
00811 PropModeReplace, (unsigned char *) bypasscomp_on, 1);
00812 #endif
00813
00814 handle->eglctx = eglCreateContext(handle->dpy, handle->eglconf, EGL_NO_CONTEXT, NULL);
00815
00816 handle->eglsurf = eglCreateWindowSurface(handle->egldpy, handle->eglconf, handle->win, NULL);
00817 eglMakeCurrent(handle->dpy, handle->eglsurf, handle->eglsurf, handle->eglctx);
00818
00819
00820 glwin_init_exts(handle);
00821
00822 EGLint Context_RendererType=0;
00823 eglQueryContext(handle->egldpy, handle->eglctx, EGL_CONTEXT_CLIENT_TYPE, &Context_RendererType);
00824
00825 const char *glstring="uninitialized";
00826 char buf[1024];
00827 switch (Context_RendererType) {
00828 case EGL_OPENGL_API: glstring = "OpenGL"; break;
00829 case EGL_OPENGL_ES_API: glstring = "OpenGL ES"; break;
00830 case EGL_OPENVG_API: glstring = "OpenVG???"; break;
00831 default:
00832 sprintf(buf, "Unknown API: %x", Context_RendererType);
00833 glstring=buf;
00834 break;
00835 }
00836 printf("EGL_CONTEXT_CLIENT_TYPE: %s\n", glstring);
00837
00838
00839 XStoreName(handle->dpy, handle->win, wintitle);
00840
00841 XSelectInput(handle->dpy, handle->win,
00842 KeyPressMask | ButtonPressMask | ButtonReleaseMask |
00843 PointerMotionMask | StructureNotifyMask | ExposureMask |
00844 EnterWindowMask | LeaveWindowMask | FocusChangeMask);
00845
00846
00847 memset((void *) &(sizeHints), 0, sizeof(sizeHints));
00848 sizeHints.flags |= USSize;
00849 sizeHints.flags |= USPosition;
00850 sizeHints.width = width;
00851 sizeHints.height = height;
00852 sizeHints.x = 0;
00853 sizeHints.y = 0;
00854 XSetWMNormalHints(handle->dpy, handle->win, &sizeHints);
00855
00856
00857
00858 handle->wmDeleteWindow = XInternAtom(handle->dpy, "WM_DELETE_WINDOW", False);
00859 XSetWMProtocols(handle->dpy, handle->win, &handle->wmDeleteWindow, 1);
00860
00861 XMapRaised(handle->dpy, handle->win);
00862
00863
00864 #if 0
00865
00866 handle->sball = spaceball_attach(handle->dpy, handle->win);
00867 #else
00868
00869 handle->sball = spaceball_attach(handle->dpy, InputFocus);
00870 #endif
00871
00872 spaceball_init_event(&handle->sballevent);
00873 spaceball_clear_event(&handle->sballevent);
00874
00875 glwin_handle_events(handle, GLWIN_EV_POLL_BLOCK);
00876
00877 #if 0
00878
00879 glGetIntegerv(GL_STENCIL_BITS, &stencilbits);
00880 if (stencilbits > 0) {
00881 handle->havestencil = 1;
00882 }
00883 #endif
00884
00885 glClearColor(1.0, 0.0, 0.0, 1.0);
00886 glClear(GL_COLOR_BUFFER_BIT);
00887 glwin_swap_buffers(handle);
00888 glClear(GL_COLOR_BUFFER_BIT);
00889 glwin_swap_buffers(handle);
00890
00891
00892 XFlush(handle->dpy);
00893
00894 return handle;
00895 #else
00896
00897 oglhandle * handle;
00898 XSetWindowAttributes attr;
00899 unsigned long mask;
00900 XVisualInfo *vis=NULL;
00901 XSizeHints sizeHints;
00902 GLint stencilbits;
00903
00904 int glxstereoattrib[] = { GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8,
00905 GLX_BLUE_SIZE, 8, GLX_DEPTH_SIZE, 16,
00906 GLX_STENCIL_SIZE, 1,
00907 GLX_STEREO, GLX_DOUBLEBUFFER, None };
00908 int glxnormalattrib[] = { GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8,
00909 GLX_BLUE_SIZE, 8, GLX_DEPTH_SIZE, 16,
00910 GLX_STENCIL_SIZE, 1,
00911 GLX_DOUBLEBUFFER, None };
00912 int glxfailsafeattrib[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
00913 GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 16,
00914 GLX_DOUBLEBUFFER, None };
00915
00916 handle = glwin_alloc_init();
00917 handle->width = width;
00918 handle->height = height;
00919
00920
00921 handle->havestencil = 1;
00922 handle->instereo = 1;
00923 vis=glXChooseVisual(handle->dpy, handle->scrnum, glxstereoattrib);
00924 if (vis == NULL) {
00925 handle->havestencil = 1;
00926 handle->instereo = 0;
00927
00928 vis=glXChooseVisual(handle->dpy, handle->scrnum, glxnormalattrib);
00929 if (vis == NULL) {
00930 handle->havestencil = 0;
00931 handle->instereo = 0;
00932
00933 vis=glXChooseVisual(handle->dpy, handle->scrnum, glxfailsafeattrib);
00934 if (vis == NULL) {
00935 free(handle);
00936 return NULL;
00937 }
00938 }
00939 }
00940
00941
00942 attr.background_pixel = 0;
00943 attr.border_pixel = 0;
00944 attr.colormap = XCreateColormap(handle->dpy, handle->root,
00945 vis->visual, AllocNone);
00946
00947 attr.event_mask = StructureNotifyMask | ExposureMask;
00948 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
00949
00950 handle->win = XCreateWindow(handle->dpy, handle->root, 0, 0, width, height,
00951 0, vis->depth, InputOutput,
00952 vis->visual, mask, &attr );
00953
00954 #if 0
00955
00956 Atom bypasscomp = X11_XInternAtom(handle->dpy, "_NET_WM_BYPASS_COMPOSITOR", False);
00957 const long bypasscomp_on = 1;
00958 X11_XChangeProperty(handle->dpy, handle->win, bypasscomp, XA_CARDINAL, 32,
00959 PropModeReplace, (unsigned char *) bypasscomp_on, 1);
00960 #endif
00961
00962 handle->ctx = glXCreateContext( handle->dpy, vis, NULL, True );
00963
00964 glXMakeCurrent( handle->dpy, handle->win, handle->ctx );
00965
00966
00967 glwin_init_exts(handle);
00968
00969 XStoreName(handle->dpy, handle->win, wintitle);
00970
00971 XSelectInput(handle->dpy, handle->win,
00972 KeyPressMask | ButtonPressMask | ButtonReleaseMask |
00973 PointerMotionMask | StructureNotifyMask | ExposureMask |
00974 EnterWindowMask | LeaveWindowMask | FocusChangeMask);
00975
00976
00977 memset((void *) &(sizeHints), 0, sizeof(sizeHints));
00978 sizeHints.flags |= USSize;
00979 sizeHints.flags |= USPosition;
00980 sizeHints.width = width;
00981 sizeHints.height = height;
00982 sizeHints.x = 0;
00983 sizeHints.y = 0;
00984 XSetWMNormalHints(handle->dpy, handle->win, &sizeHints);
00985
00986
00987
00988 handle->wmDeleteWindow = XInternAtom(handle->dpy, "WM_DELETE_WINDOW", False);
00989 XSetWMProtocols(handle->dpy, handle->win, &handle->wmDeleteWindow, 1);
00990
00991 XMapRaised(handle->dpy, handle->win);
00992
00993
00994 #if 0
00995
00996 handle->sball = spaceball_attach(handle->dpy, handle->win);
00997 #else
00998
00999 handle->sball = spaceball_attach(handle->dpy, InputFocus);
01000 #endif
01001
01002 spaceball_init_event(&handle->sballevent);
01003 spaceball_clear_event(&handle->sballevent);
01004
01005 glwin_handle_events(handle, GLWIN_EV_POLL_BLOCK);
01006
01007
01008 glGetIntegerv(GL_STENCIL_BITS, &stencilbits);
01009 if (stencilbits > 0) {
01010 handle->havestencil = 1;
01011 }
01012
01013 glClearColor(0.0, 0.0, 0.0, 1.0);
01014 glClear(GL_COLOR_BUFFER_BIT);
01015 glwin_swap_buffers(handle);
01016 glClear(GL_COLOR_BUFFER_BIT);
01017 glwin_swap_buffers(handle);
01018
01019 XFlush(handle->dpy);
01020
01021 return handle;
01022 #endif
01023 }
01024
01025
01026 void glwin_destroy(void * voidhandle) {
01027 oglhandle * handle = (oglhandle *) voidhandle;
01028 if (handle == NULL)
01029 return;
01030
01031
01032 if (handle->sball != NULL) {
01033 spaceball_close(handle->sball);
01034 handle->sball = NULL;
01035 }
01036
01037
01038 if (handle->ext != NULL) {
01039 free(handle->ext);
01040 }
01041
01042
01043 XUnmapWindow(handle->dpy, handle->win);
01044
01045 #if defined(USEEGL)
01046
01047 eglMakeCurrent(handle->egldpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
01048 eglDestroyContext(handle->egldpy, handle->eglctx);
01049 eglDestroySurface(handle->egldpy, handle->eglsurf);
01050 eglTerminate(handle->egldpy);
01051 #else
01052
01053 glXMakeCurrent(handle->dpy, None, NULL);
01054 #endif
01055
01056 XDestroyWindow(handle->dpy, handle->win);
01057 XCloseDisplay(handle->dpy);
01058 }
01059
01060
01061 void glwin_swap_buffers(void * voidhandle) {
01062 oglhandle * handle = (oglhandle *) voidhandle;
01063
01064 if (handle != NULL)
01065 #if defined(USEEGL)
01066
01067 eglSwapBuffers(handle->egldpy, handle->eglsurf);
01068 #else
01069
01070 glXSwapBuffers(handle->dpy, handle->win);
01071 #endif
01072 }
01073
01074
01075 int glwin_handle_events(void * voidhandle, int evblockmode) {
01076 oglhandle * handle = (oglhandle *) voidhandle;
01077 int rc=0;
01078 char keybuf[10];
01079 int keybuflen = 9;
01080 KeySym keysym;
01081 XComposeStatus comp;
01082
01083 if (handle == NULL)
01084 return 0;
01085
01086
01087
01088 spaceball_clear_event(&handle->sballevent);
01089
01090 #if 0
01091 if (handle) {
01092
01093 XWindowAttributes xwa;
01094 XGetWindowAttributes(handle->dpy, handle->win, &xwa);
01095 handle->width = xwa.width;
01096 handle->height = xwa.height;
01097 }
01098 #endif
01099
01100
01101
01102 while (!rc && (evblockmode || XPending(handle->dpy))) {
01103 int k;
01104 unsigned int button;
01105 XEvent event;
01106
01107 evblockmode = GLWIN_EV_POLL_NONBLOCK;
01108 XNextEvent(handle->dpy, &event);
01109 handle->evdev = GLWIN_EV_NONE;
01110 handle->evval = 0;
01111 handle->evkey = '\0';
01112
01113 switch(event.type) {
01114 case Expose:
01115 case ReparentNotify:
01116 case MapNotify:
01117 rc=1;
01118 break;
01119
01120 case ConfigureNotify:
01121 handle->width = event.xconfigure.width;
01122 handle->height = event.xconfigure.height;
01123 handle->xpos = event.xconfigure.x;
01124 handle->ypos = event.xconfigure.y;
01125 rc=1;
01126 break;
01127
01128 case KeyPress:
01129 handle->mousex = event.xbutton.x;
01130 handle->mousey = event.xbutton.y;
01131 k = XLookupString(&(event.xkey), keybuf, keybuflen, &keysym, &comp);
01132 if (k > 0 && keybuf[0] != '\0') {
01133 handle->evdev = GLWIN_EV_KBD;
01134 handle->evkey = keybuf[0];
01135 rc=1;
01136 } else {
01137 handle->evdev = GLWIN_EV_NONE;
01138 handle->evkey = 0;
01139 switch (keysym) {
01140 case XK_Up: handle->evdev = GLWIN_EV_KBD_UP; break;
01141 case XK_Down: handle->evdev = GLWIN_EV_KBD_DOWN; break;
01142 case XK_Left: handle->evdev = GLWIN_EV_KBD_LEFT; break;
01143 case XK_Right: handle->evdev = GLWIN_EV_KBD_RIGHT; break;
01144 case XK_Page_Up: handle->evdev = GLWIN_EV_KBD_PAGE_UP; break;
01145 case XK_Page_Down: handle->evdev = GLWIN_EV_KBD_PAGE_UP; break;
01146 case XK_Home: handle->evdev = GLWIN_EV_KBD_HOME; break;
01147 case XK_End: handle->evdev = GLWIN_EV_KBD_END; break;
01148 case XK_Insert: handle->evdev = GLWIN_EV_KBD_INSERT; break;
01149 case XK_Delete: handle->evdev = GLWIN_EV_KBD_DELETE; break;
01150
01151 case XK_F1: handle->evdev = GLWIN_EV_KBD_F1; break;
01152 case XK_F2: handle->evdev = GLWIN_EV_KBD_F2; break;
01153 case XK_F3: handle->evdev = GLWIN_EV_KBD_F3; break;
01154 case XK_F4: handle->evdev = GLWIN_EV_KBD_F4; break;
01155 case XK_F5: handle->evdev = GLWIN_EV_KBD_F5; break;
01156 case XK_F6: handle->evdev = GLWIN_EV_KBD_F6; break;
01157 case XK_F7: handle->evdev = GLWIN_EV_KBD_F7; break;
01158 case XK_F8: handle->evdev = GLWIN_EV_KBD_F8; break;
01159 case XK_F9: handle->evdev = GLWIN_EV_KBD_F9; break;
01160 case XK_F10: handle->evdev = GLWIN_EV_KBD_F10; break;
01161 case XK_F11: handle->evdev = GLWIN_EV_KBD_F11; break;
01162 case XK_F12: handle->evdev = GLWIN_EV_KBD_F12; break;
01163
01164 case XK_Escape: handle->evdev = GLWIN_EV_KBD_F12; break;
01165 }
01166 if (handle->evdev != GLWIN_EV_NONE)
01167 rc=1;
01168 }
01169 break;
01170
01171 case MotionNotify:
01172 handle->evdev = GLWIN_EV_MOUSE_MOVE;
01173 handle->mousex = event.xmotion.x;
01174 handle->mousey = event.xmotion.y;
01175 rc=1;
01176 break;
01177
01178 case ButtonPress:
01179 case ButtonRelease:
01180 button = event.xbutton.button;
01181 handle->evval = (event.type == ButtonPress);
01182 handle->mousex = event.xbutton.x;
01183 handle->mousey = event.xbutton.y;
01184 switch (button) {
01185 case Button1:
01186 handle->evdev = GLWIN_EV_MOUSE_LEFT;
01187 rc=1;
01188 break;
01189 case Button2:
01190 handle->evdev = GLWIN_EV_MOUSE_MIDDLE;
01191 rc=1;
01192 break;
01193 case Button3:
01194 handle->evdev = GLWIN_EV_MOUSE_RIGHT;
01195 rc=1;
01196 break;
01197 case Button4:
01198 handle->evdev = GLWIN_EV_MOUSE_WHEELUP;
01199 rc=1;
01200 break;
01201 case Button5:
01202 handle->evdev = GLWIN_EV_MOUSE_WHEELDOWN;
01203 rc=1;
01204 break;
01205 }
01206 break;
01207
01208 case FocusIn:
01209 case EnterNotify:
01210 handle->havefocus=1;
01211 break;
01212
01213 case FocusOut:
01214 case LeaveNotify:
01215 handle->havefocus=0;
01216 break;
01217
01218 case ClientMessage:
01219
01220 if (event.xclient.data.l[0] == handle->wmDeleteWindow) {
01221 handle->evdev = GLWIN_EV_WINDOW_CLOSE;
01222 rc=1;
01223 } else {
01224 #if 1
01225
01226
01227 spaceball_decode_event(handle->sball, &event, &handle->sballevent);
01228 #else
01229
01230
01231 if (handle->havefocus) {
01232 spaceball_decode_event(handle->sball, &event, &handle->sballevent);
01233 }
01234 #endif
01235 }
01236 break;
01237
01238 }
01239 }
01240
01241 return rc;
01242 }
01243
01244
01245 int glwin_resize(void *voidhandle, int width, int height) {
01246 oglhandle * handle = (oglhandle *) voidhandle;
01247 if (handle == NULL)
01248 return -1;
01249
01250 XResizeWindow(handle->dpy, handle->win, width, height);
01251
01252 #if 0
01253 XFlush(handle->dpy);
01254 #endif
01255
01256 return 0;
01257 }
01258
01259
01260 int glwin_reposition(void *voidhandle, int xpos, int ypos) {
01261 oglhandle * handle = (oglhandle *) voidhandle;
01262 if (handle == NULL)
01263 return -1;
01264
01265 XMoveWindow(handle->dpy, handle->win, xpos, ypos);
01266
01267 return 0;
01268 }
01269
01270
01271 #if 0
01272 int glwin_switch_fullscreen_video_mode(void * voidhandle, mode...) {
01273 XF86VidModeSwitchToMode(display,defaultscreen,video_mode);
01274 XF86VidModeSetViewPort(display,DefaultScreen,0,0);
01275 XMoveResizeWindow(display,window,0,0,width,height);
01276 XMapRaised(display,window);
01277 XGrabPointer(display,window,True,0,GrabModeAsync,GrabModeAsync,window,0L,CurrentTime);
01278 XGrabKeyboard(display,window,False,GrabModeAsync,GrabModeAsync,CurrentTime);
01279 }
01280 #endif
01281
01282
01283 int glwin_fullscreen(void * voidhandle, int fson, int xinescreen) {
01284 struct {
01285 unsigned long flags;
01286 unsigned long functions;
01287 unsigned long decorations;
01288 long inputMode;
01289 unsigned long status;
01290 } wmhints;
01291 Atom wmproperty;
01292
01293 oglhandle * handle = (oglhandle *) voidhandle;
01294
01295 memset(&wmhints, 0, sizeof(wmhints));
01296 wmhints.flags = 2;
01297 if (fson) {
01298 wmhints.decorations = 0;
01299 } else {
01300 wmhints.decorations = 1;
01301 }
01302 wmproperty = XInternAtom(handle->dpy, "_MOTIF_WM_HINTS", True);
01303 XChangeProperty(handle->dpy, handle->win, wmproperty, wmproperty, 32,
01304 PropModeReplace, (unsigned char *) &wmhints, 5);
01305
01306 #if 0
01307 {
01308 XSetWindowAttributes xswa;
01309 xswa.override_redirect = False;
01310 XChangeWindowAttributes(handle->dpy, handle->win, CWOverrideRedirect, &xswa);
01311 }
01312 #endif
01313
01314 #if 1 && defined(__linux)
01315
01316
01317 Atom fsatom = XInternAtom(handle->dpy, "_NET_WM_STATE_FULLSCREEN", True);
01318 Atom stateatom = XInternAtom(handle->dpy, "_NET_WM_STATE", True);
01319 if (fsatom != None && stateatom != None) {
01320 #if 0
01321 XChangeProperty(handle->dpy, handle->win, stateatom,
01322 XA_ATOM, 32, PropModeReplace, (unsigned char*) &fsatom, 1);
01323 #endif
01324
01325 XEvent xev;
01326 memset(&xev, 0, sizeof(xev));
01327 xev.type = ClientMessage;
01328 xev.xclient.window = handle->win;
01329 xev.xclient.message_type = stateatom;
01330 xev.xclient.format = 32;
01331 if (fson)
01332 xev.xclient.data.l[0] = 1;
01333 else
01334 xev.xclient.data.l[0] = 0;
01335 xev.xclient.data.l[1] = fsatom;
01336 xev.xclient.data.l[2] = 0;
01337
01338 XSendEvent(handle->dpy, handle->root, False,
01339 SubstructureRedirectMask | SubstructureNotifyMask, &xev);
01340
01341 XFlush(handle->dpy);
01342 }
01343 #if 0
01344 else {
01345 printf("*** failed to obtain full screen X11 atom\n");
01346 }
01347 #endif
01348 #endif
01349
01350
01351
01352
01353 if (fson) {
01354 int dpyScreen = DefaultScreen(handle->dpy);
01355
01356 XSizeHints sizeHints;
01357 memset((void *) &(sizeHints), 0, sizeof(sizeHints));
01358 sizeHints.flags |= USSize;
01359 sizeHints.flags |= USPosition;
01360
01361 sizeHints.width = DisplayWidth(handle->dpy, dpyScreen);
01362 sizeHints.height = DisplayHeight(handle->dpy, dpyScreen);
01363 sizeHints.x = 0;
01364 sizeHints.y = 0;
01365
01366 #if defined(USEXINERAMA)
01367 if (xinescreen != -1) {
01368 int xinerr, xinevent, xinenumscreens;
01369 if (XineramaQueryExtension(handle->dpy, &xinevent, &xinerr) &&
01370 XineramaIsActive(handle->dpy)) {
01371 XineramaScreenInfo *screens =
01372 XineramaQueryScreens(handle->dpy, &xinenumscreens);
01373 if (xinescreen >= 0 && xinescreen < xinenumscreens) {
01374 sizeHints.width = screens[xinescreen].width;
01375 sizeHints.height = screens[xinescreen].height;
01376 sizeHints.x = screens[xinescreen].x_org;
01377 sizeHints.y = screens[xinescreen].y_org;
01378 #if 1 || defined(DEBUGOUTPUT)
01379 printf("*** OpenGL Stereo: Xinerama screen %d, +%d+%dx%dx%d\n",
01380 xinescreen, sizeHints.x, sizeHints.y,
01381 sizeHints.width, sizeHints.height);
01382 #endif
01383 } else {
01384 printf("*** OpenGL Stereo: no such Xinerama screen index %d\n",
01385 xinescreen);
01386 }
01387 XFree(screens);
01388 }
01389 }
01390 #endif
01391
01392 XMoveWindow(handle->dpy, handle->win, sizeHints.x, sizeHints.y);
01393 XResizeWindow(handle->dpy, handle->win, sizeHints.width, sizeHints.height);
01394 }
01395
01396 #if 0
01397 {
01398 XSetWindowAttributes xswa;
01399 xswa.override_redirect = True;
01400 XChangeWindowAttributes(handle->dpy, handle->win, CWOverrideRedirect, &xswa);
01401 }
01402 #endif
01403
01404 #if 0
01405 XSync(handle->dpy, 0);
01406 #endif
01407
01408 return 0;
01409 }
01410
01411
01412 #else
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422 #if defined(USESPACEWARE)
01423
01424 static spaceballhandle * spaceball_attach(HWND hWnd) {
01425 SiOpenData oData;
01426 enum SpwRetVal res;
01427
01428 switch (SiInitialize()) {
01429 case SPW_NO_ERROR:
01430 break;
01431
01432 case SPW_DLL_LOAD_ERROR:
01433 default:
01434 return NULL;
01435 }
01436
01437
01438 spaceballhandle *handle = (spaceballhandle *) calloc(1, sizeof(spaceballhandle));
01439
01440 SiOpenWinInit(&oData, hWnd);
01441 SiSetUiMode(handle->sball, SI_UI_ALL_CONTROLS);
01442
01443
01444
01445 handle->sball = SiOpen("OpenGL", SI_ANY_DEVICE, SI_NO_MASK, SI_EVENT, &oData);
01446 if ((handle->sball == NULL) || (handle->sball == SI_NO_HANDLE)) {
01447 SiTerminate();
01448 free(handle);
01449 return NULL;
01450 }
01451
01452 res = SiBeep(handle->sball, "CcCc");
01453 if ((handle->sball != NULL) && (handle->sball != SI_NO_HANDLE))
01454 return handle;
01455
01456 free(handle);
01457 return NULL;
01458 }
01459
01460
01461 static void spaceball_close(spaceballhandle *handle) {
01462 if (handle == NULL)
01463 return;
01464
01465 if (handle->sball != NULL) {
01466 enum SpwRetVal res;
01467 res = SiClose(handle->sball);
01468 if (res != SPW_NO_ERROR)
01469 printf("An error occured during Spaceball shutdown.\n");
01470 SiTerminate();
01471 }
01472
01473 free(handle);
01474 }
01475
01476
01477 static int spaceball_decode_event(spaceballhandle *handle, spaceballevent *sballevent, UINT msg, WPARAM wParam, LPARAM lParam) {
01478 if (handle == NULL)
01479 return 0;
01480
01481 if (handle->sball == NULL)
01482 return 0;
01483
01484
01485 SiGetEventWinInit(&handle->spwedata, msg, wParam, lParam);
01486
01487 if (SiGetEvent(handle->sball, 0, &handle->spwedata, &handle->spwevent) == SI_IS_EVENT) {
01488 return 1;
01489 }
01490
01491 return 0;
01492 }
01493
01494 #endif
01495
01496
01497
01498 static void spaceball_init_event(spaceballevent *sballevent) {
01499 memset(sballevent, 0, sizeof(spaceballevent));
01500 }
01501
01502 static void spaceball_clear_event(spaceballevent *sballevent) {
01503 sballevent->tx = 0;
01504 sballevent->ty = 0;
01505 sballevent->tz = 0;
01506 sballevent->rx = 0;
01507 sballevent->ry = 0;
01508 sballevent->rz = 0;
01509 sballevent->period = 0;
01510 sballevent->event = 0;
01511 }
01512
01513
01514
01515
01516
01517 LRESULT WINAPI myWindowProc( HWND, UINT, WPARAM, LPARAM );
01518
01519 static const char *szClassName = "OpenGLWindow";
01520 static WNDCLASS wc;
01521 static int wc_initialized = 0;
01522
01523 static int OpenWin32Connection(oglhandle * handle) {
01524 HINSTANCE hInstance = GetModuleHandle(NULL);
01525
01526 if (!wc_initialized) {
01527
01528 memset(&wc, 0, sizeof(WNDCLASS));
01529 wc.style = CS_OWNDC;
01530 wc.lpfnWndProc = (WNDPROC) myWindowProc;
01531 wc.hInstance = hInstance;
01532 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
01533 wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
01534 wc.hbrBackground = NULL;
01535 wc.lpszMenuName = NULL;
01536 wc.lpszClassName = szClassName;
01537
01538 if(!RegisterClass(&wc)) {
01539 printf("Cannot register window class.\n");
01540 return -1;
01541 }
01542
01543 wc_initialized = 1;
01544 }
01545
01546 handle->scrwidth = GetSystemMetrics(SM_CXSCREEN);
01547 handle->scrheight = GetSystemMetrics(SM_CYSCREEN);
01548
01549 return 0;
01550 }
01551
01552
01553 static HGLRC SetupOpenGL(oglhandle * handle) {
01554 int nMyPixelFormatID;
01555 HDC hDC;
01556 HGLRC hRC;
01557 PIXELFORMATDESCRIPTOR checkpfd;
01558 static PIXELFORMATDESCRIPTOR pfd = {
01559 sizeof (PIXELFORMATDESCRIPTOR),
01560 1,
01561 PFD_DRAW_TO_WINDOW
01562 | PFD_DOUBLEBUFFER
01563 | PFD_STEREO
01564 | PFD_SUPPORT_OPENGL,
01565 PFD_TYPE_RGBA,
01566 24,
01567 0, 0, 0,
01568 0, 0, 0,
01569 0, 0,
01570 0, 0, 0, 0, 0,
01571 16,
01572 1,
01573 0,
01574 PFD_MAIN_PLANE,
01575 0,
01576 0,
01577 0,
01578 0
01579 };
01580
01581 hDC = GetDC(handle->hWnd);
01582 nMyPixelFormatID = ChoosePixelFormat(hDC, &pfd);
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592 if (nMyPixelFormatID == 0) {
01593 printf("Error selecting OpenGL Pixel Format!!\n");
01594 return NULL;
01595 }
01596
01597
01598 DescribePixelFormat(hDC, nMyPixelFormatID,
01599 sizeof(PIXELFORMATDESCRIPTOR), &checkpfd);
01600 if (checkpfd.dwFlags & PFD_STEREO)
01601 handle->instereo = 1;
01602 else
01603 handle->instereo = 0;
01604
01605 SetPixelFormat(hDC, nMyPixelFormatID, &pfd);
01606
01607 hRC = wglCreateContext(hDC);
01608 ReleaseDC(handle->hWnd, hDC);
01609
01610 return hRC;
01611 }
01612
01613
01614 static int myCreateWindow(oglhandle * handle, const char * wintitle,
01615 int xpos, int ypos, int xs, int ys) {
01616
01617 handle->hWnd =
01618 CreateWindow(
01619 szClassName,
01620 wintitle,
01621 WS_OVERLAPPEDWINDOW
01622 | WS_CLIPCHILDREN
01623 | WS_CLIPSIBLINGS,
01624 xpos, ypos,
01625 xs, ys,
01626 NULL,
01627 NULL,
01628 GetModuleHandle(NULL),
01629 handle
01630 );
01631
01632 if (!handle->hWnd) {
01633 printf("Couldn't Open Window!!\n");
01634 return -1;
01635 }
01636
01637 handle->hDC = GetDC(handle->hWnd);
01638 wglMakeCurrent(handle->hDC, handle->hRC);
01639
01640
01641 ShowWindow( handle->hWnd, SW_SHOW);
01642 UpdateWindow( handle->hWnd );
01643
01644 return 0;
01645 }
01646
01647
01648 static void win32decodemouse(oglhandle *handle, LPARAM lParam) {
01649 int x, y;
01650 x = LOWORD(lParam);
01651 y = HIWORD(lParam);
01652
01653 if (x & 1 << 15) x -= (1 << 16);
01654 if (y & 1 << 15) y -= (1 << 16);
01655 handle->mousex = x;
01656 handle->mousey = y;
01657 }
01658
01659
01660 LRESULT WINAPI myWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
01661 PAINTSTRUCT ps;
01662 oglhandle *handle;
01663
01664
01665
01666 if (msg == WM_NCCREATE) {
01667 #if defined(_M_X64) || defined(_WIN64) || defined(_Wp64)
01668 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) (((CREATESTRUCT *) lParam)->lpCreateParams));
01669 #elif 1
01670 SetWindowLong(hwnd, GWL_USERDATA, (LONG) (((CREATESTRUCT *) lParam)->lpCreateParams));
01671 #else
01672 SetProp(hwnd, "OGLHANDLE", (((CREATESTRUCT *) lParam)->lpCreateParams));
01673 #endif
01674 }
01675
01676
01677
01678 #if defined(_M_X64) || defined(_WIN64) || defined(_Wp64)
01679 handle = (oglhandle *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
01680 #elif 1
01681 handle = (oglhandle *) GetWindowLong(hwnd, GWL_USERDATA);
01682 #else
01683 handle = (oglhandle *) GetProp(hwnd, "OGLHANDLE");
01684 #endif
01685 if (handle == NULL)
01686 return DefWindowProc(hwnd, msg, wParam, lParam);
01687
01688 switch (msg) {
01689 case WM_CREATE:
01690 handle->hWnd = hwnd;
01691 handle->hRC = SetupOpenGL(handle);
01692 return 0;
01693
01694 case WM_MOVE:
01695 wglMakeCurrent(handle->hDC, handle->hRC);
01696 handle->xpos = LOWORD(lParam);
01697 handle->ypos = HIWORD(lParam);
01698 return 0;
01699
01700 case WM_SIZE:
01701 wglMakeCurrent(handle->hDC, handle->hRC);
01702 handle->width = LOWORD(lParam);
01703 handle->height = HIWORD(lParam);
01704 return 0;
01705
01706 case WM_KEYDOWN:
01707 handle->evdev = GLWIN_EV_KBD;
01708
01709
01710 handle->evkey = MapVirtualKey((UINT) wParam, 2);
01711
01712 if (handle->evkey != 0) {
01713
01714
01715
01716
01717 int shiftstate = ((handle->MouseFlags & MK_SHIFT) != 0);
01718 handle->evkey = (shiftstate) ? toupper(handle->evkey) : tolower(handle->evkey);
01719 } else {
01720
01721
01722
01723 unsigned int keysym = (unsigned int) wParam;
01724
01725 switch (keysym) {
01726 case VK_UP: handle->evdev = GLWIN_EV_KBD_UP; break;
01727 case VK_DOWN: handle->evdev = GLWIN_EV_KBD_DOWN; break;
01728 case VK_LEFT: handle->evdev = GLWIN_EV_KBD_LEFT; break;
01729 case VK_RIGHT: handle->evdev = GLWIN_EV_KBD_RIGHT; break;
01730 case VK_PRIOR: handle->evdev = GLWIN_EV_KBD_PAGE_UP; break;
01731 case VK_NEXT: handle->evdev = GLWIN_EV_KBD_PAGE_UP; break;
01732 case VK_HOME: handle->evdev = GLWIN_EV_KBD_HOME; break;
01733 case VK_END: handle->evdev = GLWIN_EV_KBD_END; break;
01734 case VK_INSERT: handle->evdev = GLWIN_EV_KBD_INSERT; break;
01735 case VK_DELETE: handle->evdev = GLWIN_EV_KBD_DELETE; break;
01736
01737 case VK_F1: handle->evdev = GLWIN_EV_KBD_F1; break;
01738 case VK_F2: handle->evdev = GLWIN_EV_KBD_F2; break;
01739 case VK_F3: handle->evdev = GLWIN_EV_KBD_F3; break;
01740 case VK_F4: handle->evdev = GLWIN_EV_KBD_F4; break;
01741 case VK_F5: handle->evdev = GLWIN_EV_KBD_F5; break;
01742 case VK_F6: handle->evdev = GLWIN_EV_KBD_F6; break;
01743 case VK_F7: handle->evdev = GLWIN_EV_KBD_F7; break;
01744 case VK_F8: handle->evdev = GLWIN_EV_KBD_F8; break;
01745 case VK_F9: handle->evdev = GLWIN_EV_KBD_F9; break;
01746 case VK_F10: handle->evdev = GLWIN_EV_KBD_F10; break;
01747 case VK_F11: handle->evdev = GLWIN_EV_KBD_F11; break;
01748 case VK_F12: handle->evdev = GLWIN_EV_KBD_F12; break;
01749
01750 case VK_ESCAPE: handle->evdev = GLWIN_EV_KBD_ESC; break;
01751
01752 default:
01753 handle->evdev = GLWIN_EV_NONE;
01754 break;
01755 }
01756 }
01757 return 0;
01758
01759 case WM_MOUSEMOVE:
01760 win32decodemouse(handle, lParam);
01761 handle->evdev = GLWIN_EV_MOUSE_MOVE;
01762 handle->MouseFlags = (long) wParam;
01763 if (!(handle->MouseFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)))
01764 ReleaseCapture();
01765 return 0;
01766
01767 case WM_MOUSEWHEEL:
01768 {
01769 int wheeldelta = ((short) HIWORD(wParam));
01770 if (wheeldelta > (WHEEL_DELTA / 2)) {
01771 handle->evdev = GLWIN_EV_MOUSE_WHEELUP;
01772 } else if (wheeldelta < -(WHEEL_DELTA / 2)) {
01773 handle->evdev = GLWIN_EV_MOUSE_WHEELDOWN;
01774 }
01775 }
01776 return 0;
01777
01778 case WM_LBUTTONDOWN:
01779 SetCapture(hwnd);
01780 win32decodemouse(handle, lParam);
01781 handle->MouseFlags = (long) wParam;
01782 handle->evdev = GLWIN_EV_MOUSE_LEFT;
01783 handle->evval = 1;
01784 return 0;
01785
01786 case WM_LBUTTONUP:
01787 win32decodemouse(handle, lParam);
01788 handle->MouseFlags = (long) wParam;
01789 handle->evdev = GLWIN_EV_MOUSE_LEFT;
01790 handle->evval = 0;
01791 if (!(handle->MouseFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)))
01792 ReleaseCapture();
01793 return 0;
01794
01795 case WM_MBUTTONDOWN:
01796 SetCapture(hwnd);
01797 win32decodemouse(handle, lParam);
01798 handle->MouseFlags = (long) wParam;
01799 handle->evdev = GLWIN_EV_MOUSE_MIDDLE;
01800 handle->evval = 1;
01801 return 0;
01802
01803 case WM_MBUTTONUP:
01804 win32decodemouse(handle, lParam);
01805 handle->MouseFlags = (long) wParam;
01806 handle->evdev = GLWIN_EV_MOUSE_MIDDLE;
01807 handle->evval = 0;
01808 if (!(handle->MouseFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)))
01809 ReleaseCapture();
01810 return 0;
01811
01812 case WM_RBUTTONDOWN:
01813 SetCapture(hwnd);
01814 win32decodemouse(handle, lParam);
01815 handle->MouseFlags = (long) wParam;
01816 handle->evdev = GLWIN_EV_MOUSE_RIGHT;
01817 handle->evval = 1;
01818 return 0;
01819
01820 case WM_RBUTTONUP:
01821 win32decodemouse(handle, lParam);
01822 handle->MouseFlags = (long) wParam;
01823 handle->evdev = GLWIN_EV_MOUSE_RIGHT;
01824 handle->evval = 0;
01825 if (!(handle->MouseFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)))
01826 ReleaseCapture();
01827 return 0;
01828
01829 case WM_CLOSE:
01830 #if 1
01831 DestroyWindow(handle->hWnd);
01832 #else
01833 PostQuitMessage(0);
01834 #endif
01835 return 0;
01836
01837 case WM_PAINT:
01838 BeginPaint(hwnd, &ps);
01839 EndPaint(hwnd, &ps);
01840 return 0;
01841
01842 case WM_SIZING:
01843 glClear(GL_COLOR_BUFFER_BIT);
01844 SwapBuffers(handle->hDC);
01845 glDrawBuffer(GL_BACK);
01846 return 0;
01847
01848 case WM_SETCURSOR:
01849 if (LOWORD(lParam) == HTCLIENT) {
01850 SetCursor(LoadCursor(NULL, IDC_ARROW));
01851 return 0;
01852 }
01853 return DefWindowProc(hwnd, msg, wParam, lParam);
01854
01855 default:
01856 return DefWindowProc(hwnd, msg, wParam, lParam);
01857 }
01858
01859 return 0;
01860 }
01861
01862
01863 void * glwin_create(const char * wintitle, int width, int height) {
01864 oglhandle * handle;
01865 int rc;
01866 GLint stencilbits;
01867
01868 handle = (oglhandle *) calloc(1, sizeof(oglhandle));
01869 if (handle == NULL)
01870 return NULL;
01871
01872 handle->havestencil=0;
01873 handle->instereo=0;
01874
01875 handle->width = width;
01876 handle->height = height;
01877 handle->evdev = GLWIN_EV_NONE;
01878
01879 rc = OpenWin32Connection(handle);
01880 if (rc != 0) {
01881 printf("OpenWin32Connection() returned an error!\n");
01882 free(handle);
01883 return NULL;
01884 }
01885
01886 handle->width = width;
01887 handle->height = height;
01888
01889 rc = myCreateWindow(handle, wintitle, 0, 0, width, height);
01890 if (rc != 0) {
01891 printf("CreateWindow() returned an error!\n");
01892 free(handle);
01893 return NULL;
01894 }
01895
01896
01897 #if 0
01898 handle->sball = spaceball_attach(handle->win);
01899 #endif
01900
01901 spaceball_init_event(&handle->sballevent);
01902 spaceball_clear_event(&handle->sballevent);
01903
01904
01905 glGetIntegerv(GL_STENCIL_BITS, &stencilbits);
01906 if (stencilbits > 0) {
01907 handle->havestencil = 1;
01908 }
01909
01910 return handle;
01911 }
01912
01913
01914 void glwin_destroy(void * voidhandle) {
01915 oglhandle * handle = (oglhandle *) voidhandle;
01916
01917 wglDeleteContext(handle->hRC);
01918 #if 1
01919 DestroyWindow(handle->hWnd);
01920 #else
01921 PostQuitMessage( 0 );
01922 #endif
01923
01924
01925 }
01926
01927
01928 void glwin_swap_buffers(void * voidhandle) {
01929 oglhandle * handle = (oglhandle *) voidhandle;
01930 glFlush();
01931 SwapBuffers(handle->hDC);
01932 glDrawBuffer(GL_BACK);
01933 }
01934
01935
01936 int glwin_handle_events(void * voidhandle, int evblockmode) {
01937 oglhandle * handle = (oglhandle *) voidhandle;
01938 MSG msg;
01939 int rc=0;
01940 int pending=0;
01941
01942 handle->evdev = GLWIN_EV_NONE;
01943 handle->evval = 0;
01944 handle->evkey = '\0';
01945
01946
01947
01948 pending=PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
01949 while (!rc && (evblockmode || pending)) {
01950 if (pending) {
01951 TranslateMessage(&msg);
01952 DispatchMessage(&msg);
01953 pending=0;
01954 } else if (evblockmode == GLWIN_EV_POLL_BLOCK) {
01955 if (GetMessage(&msg, NULL, 0, 0)) {
01956 TranslateMessage(&msg);
01957 DispatchMessage(&msg);
01958 }
01959 } else {
01960 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
01961 TranslateMessage(&msg);
01962 DispatchMessage(&msg);
01963 }
01964 }
01965 if (handle->evdev != GLWIN_EV_NONE)
01966 rc=1;
01967 }
01968
01969 return rc;
01970 }
01971
01972
01973 int glwin_resize(void *voidhandle, int width, int height) {
01974 RECT rcClient, rcWindow;
01975 POINT ptDiff;
01976 oglhandle * handle = (oglhandle *) voidhandle;
01977 if (handle == NULL)
01978 return -1;
01979
01980 GetClientRect(handle->hWnd, &rcClient);
01981 GetWindowRect(handle->hWnd, &rcWindow);
01982 ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
01983 ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
01984 MoveWindow(handle->hWnd, rcWindow.left, rcWindow.top, width + ptDiff.x, height + ptDiff.y, TRUE);
01985
01986 return 0;
01987 }
01988
01989
01990 int glwin_reposition(void *voidhandle, int xpos, int ypos) {
01991 RECT rcClient, rcWindow;
01992 oglhandle * handle = (oglhandle *) voidhandle;
01993 if (handle == NULL)
01994 return -1;
01995
01996 GetClientRect(handle->hWnd, &rcClient);
01997 GetWindowRect(handle->hWnd, &rcWindow);
01998 MoveWindow(handle->hWnd, xpos, ypos, rcWindow.right-rcWindow.left, rcWindow.bottom-rcWindow.top, TRUE);
01999
02000 return 0;
02001 }
02002
02003
02004 int glwin_fullscreen(void * voidhandle, int fson, int xinescreen) {
02005 return -1;
02006 }
02007
02008 #endif
02009
02010
02011
02012
02013
02014 int glwin_query_extension(const char *extname) {
02015 char *ext;
02016 char *endext;
02017 if (!extname)
02018 return 0;
02019
02020
02021 ext = (char *) glGetString(GL_EXTENSIONS);
02022 if (ext != NULL) {
02023 endext = ext + strlen(ext);
02024 while (ext < endext) {
02025 size_t n = strcspn(ext, " ");
02026 if ((strlen(extname) == n) && (strncmp(extname, ext, n) == 0)) {
02027 return 1;
02028 break;
02029 }
02030 ext += (n + 1);
02031 }
02032 }
02033
02034 return 0;
02035 }
02036
02037
02038 int glwin_query_vsync(void *voidhandle, int *onoff) {
02039 oglhandle * handle = (oglhandle *) voidhandle;
02040 if (handle == NULL)
02041 return GLWIN_ERROR;
02042
02043 #if defined(GLX_EXT_swap_control)
02044 if (glx_query_extension(handle->dpy, "GLX_EXT_swap_control")) {
02045 int interval = 0;
02046 unsigned int tmp = -1;
02047 glXQueryDrawable(handle->dpy, glXGetCurrentDrawable(), GLX_SWAP_INTERVAL_EXT, &tmp);
02048 interval = tmp;
02049 if (interval > 0) {
02050 *onoff = 1;
02051 } else {
02052 *onoff = 0;
02053 }
02054 return GLWIN_SUCCESS;
02055 }
02056 #elif 0
02057 GLuint count = 0;
02058 glwin_ext_fctns *ext = handle->ext;
02059 if (ext->hasgetvideosyncsgi) {
02060
02061
02062 if (GLXGETVIDEOSYNCSGI(&count) == 0) {
02063 if (count > 0) {
02064 *onoff = 1;
02065 } else {
02066 *onoff = 0;
02067 }
02068 }
02069 return GLWIN_SUCCESS;
02070 }
02071 #endif
02072
02073 return GLWIN_NOT_IMPLEMENTED;
02074 }
02075
02076
02077 #if !(defined(WIN32) || defined(_WIN64))
02078
02079 typedef struct {
02080 int isvalid;
02081 GLenum drawbufs[16];
02082 GLuint fbo;
02083 GLuint tex;
02084 GLuint depth;
02085 } glwin_fbo_target;
02086
02087
02088 int glwin_fbo_target_bind(void *voidhandle, void *voidtarget) {
02089 oglhandle * handle = (oglhandle *) voidhandle;
02090 glwin_fbo_target * fb = (glwin_fbo_target *) voidtarget;
02091 if (handle == NULL || fb == NULL)
02092 return GLWIN_ERROR;
02093 glwin_ext_fctns *ext = handle->ext;
02094
02095 GLBINDFRAMEBUFFER(GL_FRAMEBUFFER, fb->fbo);
02096
02097 return GLWIN_SUCCESS;
02098 }
02099
02100
02101 int glwin_fbo_target_unbind(void *voidhandle, void *voidtarget) {
02102 oglhandle * handle = (oglhandle *) voidhandle;
02103 glwin_fbo_target * fb = (glwin_fbo_target *) voidtarget;
02104 if (handle == NULL || fb == NULL)
02105 return GLWIN_ERROR;
02106 glwin_ext_fctns *ext = handle->ext;
02107
02108 GLBINDFRAMEBUFFER(GL_FRAMEBUFFER, 0);
02109
02110 return GLWIN_SUCCESS;
02111 }
02112
02113
02114 int glwin_fbo_target_destroy(void *voidhandle, void *voidtarget) {
02115 oglhandle * handle = (oglhandle *) voidhandle;
02116 glwin_fbo_target * fb = (glwin_fbo_target *) voidtarget;
02117 if (handle == NULL || fb == NULL)
02118 return GLWIN_ERROR;
02119 glwin_ext_fctns *ext = handle->ext;
02120
02121 GLDELETERENDERBUFFERS(1, &fb->depth);
02122 GLDELETEFRAMEBUFFERS(1, &fb->fbo);
02123 glDeleteTextures(1, &fb->tex);
02124 free(fb);
02125
02126 return GLWIN_SUCCESS;
02127 }
02128
02129
02130 int glwin_fbo_target_resize(void *voidhandle, void *voidtarget, int wsx, int wsy) {
02131 oglhandle * handle = (oglhandle *) voidhandle;
02132 glwin_fbo_target * fb = (glwin_fbo_target *) voidtarget;
02133 if (handle == NULL || fb == NULL)
02134 return GLWIN_ERROR;
02135 glwin_ext_fctns *ext = handle->ext;
02136
02137 #if 0
02138 printf("\nglwin_fbo_target_resize(): W %d x %d\n", wsx, wsy);
02139 #endif
02140
02141 GLBINDFRAMEBUFFER(GL_FRAMEBUFFER, fb->fbo);
02142
02143 glBindTexture(GL_TEXTURE_2D, fb->tex);
02144 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, wsx, wsy, 0,
02145 GL_RGBA, GL_UNSIGNED_BYTE, 0);
02146 GLFRAMEBUFFERTEXTURE2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
02147 GL_TEXTURE_2D, fb->tex, 0);
02148 GLBINDRENDERBUFFER(GL_RENDERBUFFER, fb->depth);
02149 GLRENDERBUFFERSTORAGE(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, wsx, wsy);
02150 GLFRAMEBUFFERRENDERBUFFER(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
02151 GL_RENDERBUFFER, fb->depth);
02152 if (GLCHECKFRAMEBUFFERSTATUS(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
02153 return GLWIN_ERROR;
02154 }
02155
02156 fb->drawbufs[0] = GL_COLOR_ATTACHMENT0;
02157 GLDRAWBUFFERS(1, fb->drawbufs);
02158
02159 return GLWIN_SUCCESS;
02160 }
02161
02162
02163 void *glwin_fbo_target_create(void *voidhandle, int wsx, int wsy) {
02164 oglhandle * handle = (oglhandle *) voidhandle;
02165 if (handle == NULL)
02166 return NULL;
02167 glwin_ext_fctns *ext = handle->ext;
02168
02169 if (!ext->hasglfborendertarget)
02170 return NULL;
02171
02172 glwin_fbo_target *fb =
02173 (glwin_fbo_target *) calloc(1, sizeof(glwin_fbo_target));
02174
02175 if (fb != NULL) {
02176
02177 glGenTextures(1, &fb->tex);
02178 glBindTexture(GL_TEXTURE_2D, fb->tex);
02179
02180
02181 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
02182
02183
02184 #if 1
02185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
02186 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
02187 #else
02188 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
02189 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
02190 #endif
02191 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
02192 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
02193 #if 1
02194 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, wsx, wsy, 0,
02195 GL_RGBA, GL_UNSIGNED_BYTE, 0);
02196 #else
02197 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, wsx, wsy, 0,
02198 GL_RGBA, GL_UNSIGNED_BYTE, 0);
02199 #endif
02200 glBindTexture(GL_TEXTURE_2D, 0);
02201
02202
02203
02204 GLGENRENDERBUFFERS(1, &fb->depth);
02205 GLBINDRENDERBUFFER(GL_RENDERBUFFER, fb->depth);
02206 GLRENDERBUFFERSTORAGE(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, wsx, wsy);
02207 GLBINDRENDERBUFFER(GL_RENDERBUFFER, 0);
02208
02209
02210
02211 GLGENFRAMEBUFFERS(1, &fb->fbo);
02212 GLBINDFRAMEBUFFER(GL_FRAMEBUFFER, fb->fbo);
02213
02214
02215 GLFRAMEBUFFERTEXTURE2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
02216 GL_TEXTURE_2D, fb->tex, 0);
02217
02218
02219 GLFRAMEBUFFERRENDERBUFFER(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
02220 GL_RENDERBUFFER, fb->depth);
02221
02222 if (GLCHECKFRAMEBUFFERSTATUS(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
02223 return NULL;
02224 }
02225
02226
02227 fb->drawbufs[0] = GL_COLOR_ATTACHMENT0;
02228 GLDRAWBUFFERS(1, fb->drawbufs);
02229
02230
02231 GLBINDFRAMEBUFFER(GL_FRAMEBUFFER, 0);
02232 }
02233
02234 #if 0
02235 if (glwin_fbo_target_resize(voidhandle, fb, wsx, wsy) == GLWIN_ERROR) {
02236 glwin_fbo_target_destroy(voidhandle, fb);
02237 return NULL;
02238 }
02239 #endif
02240
02241 return fb;
02242 }
02243
02244
02245 int glwin_fbo_target_draw_normal(void *voidhandle, void *voidtarget) {
02246 oglhandle * handle = (oglhandle *) voidhandle;
02247 glwin_fbo_target * fb = (glwin_fbo_target *) voidtarget;
02248 if (handle == NULL || fb == NULL)
02249 return GLWIN_ERROR;
02250 glwin_ext_fctns *ext = handle->ext;
02251
02252 GLBINDFRAMEBUFFER(GL_FRAMEBUFFER, 0);
02253
02254 return GLWIN_SUCCESS;
02255 }
02256
02257
02258 int glwin_fbo_target_draw_fbo(void *voidhandle, void *voidtarget, int wsx, int wsy) {
02259 oglhandle * handle = (oglhandle *) voidhandle;
02260 glwin_fbo_target * fb = (glwin_fbo_target *) voidtarget;
02261 if (handle == NULL || fb == NULL)
02262 return GLWIN_ERROR;
02263
02264
02265 glwin_fbo_target_unbind(voidhandle, voidtarget);
02266
02267 glBindTexture(GL_TEXTURE_2D, fb->tex);
02268 glEnable(GL_TEXTURE_2D);
02269 glColor3f(0.0, 0.0, 1.0);
02270 glBegin(GL_QUADS);
02271 glTexCoord2f(0.0f, 0.0f);
02272 glVertex2f(0, 0);
02273 glTexCoord2f(0.0f, 1.0f);
02274 glVertex2f(0, wsy);
02275 glTexCoord2f(1.0f, 1.0f);
02276 glVertex2f(wsx, wsy);
02277 glTexCoord2f(1.0f, 0.0f);
02278 glVertex2f(wsx, 0);
02279 glEnd();
02280 glDisable(GL_TEXTURE_2D);
02281
02282 return GLWIN_SUCCESS;
02283 }
02284
02285
02286
02287
02288
02289
02290 #define HMD_DIVCNT 10
02291
02292 static void hmd_compute_warped_coords(int divcnt, int wsx, int wsy,
02293 float rscale, float wscale,
02294 float *xcrds, float *ycrds,
02295 const float *user_distort_coeff5) {
02296 float divs = (float) divcnt;
02297 float hwidth = wsx / 2.0f;
02298 float hwdiv = hwidth / divs;
02299 float hdiv = wsy / divs;
02300 float cx=hwidth / 2.0f;
02301 float cy=wsy / 2.0f;
02302 float x, y;
02303
02304
02305 const float dk2_warp_coeff[5] = { 1.000f, 0.000f, 0.220f, 0.000f, 0.240f };
02306 #if 0
02307 const float msr_warp_coeff[5] = { 1.000f, 0.290f, 0.195f, 0.045f, 0.360f };
02308 #endif
02309 const float *C = dk2_warp_coeff;
02310
02311
02312
02313
02314
02315 if (user_distort_coeff5)
02316 C = user_distort_coeff5;
02317
02318 int ix, iy;
02319 for (iy=0; iy<=divcnt; iy++) {
02320 for (ix=0; ix<=divcnt; ix++) {
02321 float drx, dry, r, r2, rnew;
02322 int addr = iy*(divcnt+1) + ix;
02323 x = ix * hwdiv;
02324 y = iy * hdiv;
02325
02326
02327 float rnorm = wsy * 1.0f;
02328 drx = (x - cx) / rnorm;
02329 dry = (y - cy) / rnorm;
02330 r2 = drx*drx + dry*dry;
02331 r = sqrt(r2);
02332
02333 rnew = C[0] + r*C[1] + r2*C[2] + r*r2*C[3] + r2*r2*C[4];
02334
02335 rnew = 1.0f/rnew;
02336 rnorm *= 1.0f * rscale;
02337 x = wscale * rnorm * rnew * drx + cx;
02338 y = rnorm * rnew * dry + cy;
02339
02340 xcrds[addr] = x;
02341 ycrds[addr] = y;
02342 }
02343 }
02344 }
02345
02346
02347
02348 static void hmd_draw_eye_lines(int divcnt, int xoff, int width, int height,
02349 float *xcrds, float *ycrds) {
02350 float x, y;
02351 int ix, iy;
02352
02353 glDisable(GL_TEXTURE_2D);
02354 glColor3f(1.0f, 1.0f, 1.0f);
02355
02356 for (iy=0; iy<=divcnt; iy++) {
02357 for (ix=0; ix<divcnt; ix++) {
02358 int addr = iy*(divcnt+1) + ix;
02359 y = ycrds[addr];
02360 x = xcrds[addr] + xoff;
02361 float xn = xcrds[addr+1] + xoff;
02362 float yn = ycrds[addr+1];
02363 glBegin(GL_LINES);
02364 glVertex2f(x, y);
02365 glVertex2f(xn, yn);
02366 glEnd();
02367 }
02368 }
02369 for (ix=0; ix<=divcnt; ix++) {
02370 for (iy=0; iy<divcnt; iy++) {
02371 int addr = iy*(divcnt+1) + ix;
02372 x = xcrds[addr] + xoff;
02373 y = ycrds[addr];
02374 float xn = xcrds[addr + divcnt+1] + xoff;
02375 float yn = ycrds[addr + divcnt+1];
02376 glBegin(GL_LINES);
02377 glVertex2f(x, y);
02378 glVertex2f(xn, yn);
02379 glEnd();
02380 }
02381 }
02382 }
02383
02384
02385
02386 static void hmd_draw_eye_texquads(int divcnt, int xoff, int width, int height,
02387 float *xcrds, float *ycrds) {
02388 float divs = (float) divcnt;
02389 float xtxdiv = 0.5f / divs;
02390 float ytxdiv = 1.0f / divs;
02391 float tx, ty;
02392 int ix, iy;
02393 float txoff = xoff / ((float) width);
02394
02395 glBegin(GL_QUADS);
02396 for (iy=0,ty=1.0f; iy<divcnt; iy++,ty-=ytxdiv) {
02397 float tyn = ty-ytxdiv;
02398 for (ix=0,tx=0.0f; ix<divcnt; ix++,tx+=xtxdiv) {
02399 float txn = tx+xtxdiv;
02400 int addr = iy*(divcnt+1) + ix;
02401 float xx0y0 = xcrds[addr] + xoff;
02402 float yx0y0 = ycrds[addr];
02403 float xx1y0 = xcrds[addr + 1] + xoff;
02404 float yx1y0 = ycrds[addr + 1];
02405 float xx0y1 = xcrds[addr + divcnt+1] + xoff;
02406 float yx0y1 = ycrds[addr + divcnt+1];
02407 float xx1y1 = xcrds[addr + 1 + divcnt+1] + xoff;
02408 float yx1y1 = ycrds[addr + 1 + divcnt+1];
02409
02410 glTexCoord2f(tx+txoff, ty);
02411 glVertex2f(xx0y0, yx0y0);
02412 glTexCoord2f(tx+txoff, tyn);
02413 glVertex2f(xx0y1, yx0y1);
02414 glTexCoord2f(txn+txoff, tyn);
02415 glVertex2f(xx1y1, yx1y1);
02416 glTexCoord2f(txn+txoff, ty);
02417 glVertex2f(xx1y0, yx1y0);
02418 }
02419 }
02420 glEnd();
02421 }
02422
02423
02424
02425
02426
02427
02428
02429 typedef struct {
02430 void *hmd_fbo;
02431 int divcnt;
02432 int wsx;
02433 int wsy;
02434 int wrot;
02435 int ixs;
02436 int iys;
02437 float *xcrds;
02438 float *ycrds;
02439
02440
02441 float *Rxcrds;
02442 float *Rycrds;
02443 float *Gxcrds;
02444 float *Gycrds;
02445 float *Bxcrds;
02446 float *Bycrds;
02447 } glwin_warp_hmd;
02448
02449
02450 void glwin_spheremap_update_hmd_warp(void *vwin, void *voidwarp,
02451 int wsx, int wsy,
02452 int warpdivs, int ixs, int iys,
02453 const float *barrel_coeff, int force) {
02454 glwin_warp_hmd * warp = (glwin_warp_hmd *) voidwarp;
02455
02456 if (force || warp->divcnt!=warpdivs || warp->wsx!=wsx || warp->wsy!=wsy) {
02457 const float Oculus_DK2_coeff[4] = { 1.0f, 0.22f, 0.24f, 0.0f };
02458
02459 if (!barrel_coeff)
02460 barrel_coeff = Oculus_DK2_coeff;
02461
02462 #if 0
02463 printf("glwin_spheremap_update_hmd_warp(): W %d x %d, I %d x %d\n",
02464 wsx, wsy, ixs, iys);
02465 printf("warp: %.3f, %.3f, %.3f, %.3f\n",
02466 barrel_coeff[0], barrel_coeff[1], barrel_coeff[2], barrel_coeff[3]);
02467 #endif
02468
02469
02470
02471 if (glwin_fbo_target_resize(vwin, warp->hmd_fbo, wsx, wsy) == GLWIN_ERROR) {
02472 printf("\nglwin_spheremap_update_hmd_warp(): "
02473 "an error occured resizing the FBO!\n");
02474 }
02475
02476
02477
02478
02479 if (warp->xcrds != NULL)
02480 free(warp->xcrds);
02481 if (warp->ycrds != NULL)
02482 free(warp->ycrds);
02483
02484 if (warp->Rxcrds != NULL)
02485 free(warp->Rxcrds);
02486 if (warp->Rycrds != NULL)
02487 free(warp->Rycrds);
02488 if (warp->Gxcrds != NULL)
02489 free(warp->Gxcrds);
02490 if (warp->Gycrds != NULL)
02491 free(warp->Gycrds);
02492 if (warp->Bxcrds != NULL)
02493 free(warp->Bxcrds);
02494 if (warp->Bycrds != NULL)
02495 free(warp->Bycrds);
02496
02497 warp->wsx = wsx;
02498 warp->wsy = wsy;
02499 warp->divcnt = warpdivs;
02500 warp->xcrds = (float *) calloc(1, warpdivs*warpdivs*sizeof(float));
02501 warp->ycrds = (float *) calloc(1, warpdivs*warpdivs*sizeof(float));
02502 warp->Rxcrds = (float *) calloc(1, warpdivs*warpdivs*sizeof(float));
02503 warp->Rycrds = (float *) calloc(1, warpdivs*warpdivs*sizeof(float));
02504 warp->Gxcrds = (float *) calloc(1, warpdivs*warpdivs*sizeof(float));
02505 warp->Gycrds = (float *) calloc(1, warpdivs*warpdivs*sizeof(float));
02506 warp->Bxcrds = (float *) calloc(1, warpdivs*warpdivs*sizeof(float));
02507 warp->Bycrds = (float *) calloc(1, warpdivs*warpdivs*sizeof(float));
02508
02509
02510 hmd_compute_warped_coords(warpdivs-1, wsx, wsy, 1.0f, 1.0f,
02511 warp->xcrds, warp->ycrds, barrel_coeff);
02512
02513
02514 const float Rscale = 1.015f;
02515 const float Gscale = 1.000f;
02516 const float Bscale = 0.980f;
02517
02518 hmd_compute_warped_coords(warpdivs-1, wsx,wsy, Rscale, 1.0f,
02519 warp->Rxcrds, warp->Rycrds, barrel_coeff);
02520 hmd_compute_warped_coords(warpdivs-1, wsx,wsy, Gscale, 1.0f,
02521 warp->Gxcrds, warp->Gycrds, barrel_coeff);
02522 hmd_compute_warped_coords(warpdivs-1, wsx,wsy, Bscale, 1.0f,
02523 warp->Bxcrds, warp->Bycrds, barrel_coeff);
02524 }
02525 }
02526
02527
02528 void glwin_spheremap_destroy_hmd_warp(void *vwin, void *voidwarp) {
02529 glwin_warp_hmd * warp = (glwin_warp_hmd *) voidwarp;
02530 glwin_fbo_target_destroy(vwin, warp->hmd_fbo);
02531
02532 if (warp->xcrds != NULL)
02533 free(warp->xcrds);
02534 if (warp->ycrds != NULL)
02535 free(warp->ycrds);
02536
02537 if (warp->Rxcrds != NULL)
02538 free(warp->Rxcrds);
02539 if (warp->Rycrds != NULL)
02540 free(warp->Rycrds);
02541 if (warp->Gxcrds != NULL)
02542 free(warp->Gxcrds);
02543 if (warp->Gycrds != NULL)
02544 free(warp->Gycrds);
02545 if (warp->Bxcrds != NULL)
02546 free(warp->Bxcrds);
02547 if (warp->Bycrds != NULL)
02548 free(warp->Bycrds);
02549 free(warp);
02550 }
02551
02552
02553 void * glwin_spheremap_create_hmd_warp(void *vwin, int wsx, int wsy, int wrot,
02554 int warpdivs, int ixs, int iys,
02555 const float *user_coeff) {
02556 glwin_warp_hmd *warp = (glwin_warp_hmd *) calloc(1, sizeof(glwin_warp_hmd));
02557 warp->hmd_fbo = glwin_fbo_target_create(vwin, wsx, wsy);
02558 warp->wrot = wrot;
02559 glwin_spheremap_update_hmd_warp(vwin, warp, wsx, wsy, warpdivs,
02560 ixs, iys, user_coeff, 1);
02561 return warp;
02562 }
02563
02564
02565 int glwin_spheremap_draw_hmd_warp(void *vwin, void *voidwarp,
02566 int drawimage, int drawlines, int chromcorr,
02567 int wsx, int wsy, int ixs, int iys,
02568 const float *hmdquat,
02569 float fov, float rad, int hmd_spres) {
02570 oglhandle * handle = (oglhandle *) vwin;
02571 glwin_warp_hmd * warp = (glwin_warp_hmd *) voidwarp;
02572 glwin_fbo_target * fb = (glwin_fbo_target *) warp->hmd_fbo;
02573 if (handle == NULL || warp == NULL)
02574 return GLWIN_ERROR;
02575
02576 glBindTexture(GL_TEXTURE_2D, 0);
02577 glEnable(GL_TEXTURE_2D);
02578
02579 glwin_fbo_target_bind(vwin, warp->hmd_fbo);
02580 glwin_spheremap_draw_tex(vwin, GLWIN_STEREO_OVERUNDER,
02581 ixs, iys, hmdquat, fov, rad, hmd_spres);
02582 glwin_fbo_target_unbind(vwin, warp->hmd_fbo);
02583
02584 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
02585 glClearColor(0.0, 0.0, 0.0, 1.0);
02586 glViewport(0, 0, wsx, wsy);
02587 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
02588
02589 glShadeModel(GL_SMOOTH);
02590 glMatrixMode(GL_PROJECTION);
02591 glLoadIdentity();
02592 glOrtho(0.0, wsx, wsy, 0.0, -1.0, 1.0);
02593 glMatrixMode(GL_MODELVIEW);
02594 glLoadIdentity();
02595
02596 float hw = wsx * 0.5f;
02597 int dm1 = warp->divcnt-1;
02598
02599
02600
02601
02602
02603 if (drawimage) {
02604 glBindTexture(GL_TEXTURE_2D, fb->tex);
02605 glEnable(GL_TEXTURE_2D);
02606
02607
02608 if (chromcorr) {
02609 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
02610 hmd_draw_eye_texquads(dm1, 0, wsx, wsy, warp->Rxcrds, warp->Rycrds);
02611 hmd_draw_eye_texquads(dm1, hw, wsx, wsy, warp->Rxcrds, warp->Rycrds);
02612 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
02613 hmd_draw_eye_texquads(dm1, 0, wsx, wsy, warp->Gxcrds, warp->Gycrds);
02614 hmd_draw_eye_texquads(dm1, hw, wsx, wsy, warp->Gxcrds, warp->Gycrds);
02615 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE);
02616 hmd_draw_eye_texquads(dm1, 0, wsx, wsy, warp->Bxcrds, warp->Bycrds);
02617 hmd_draw_eye_texquads(dm1, hw, wsx, wsy, warp->Bxcrds, warp->Bycrds);
02618 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
02619 } else {
02620 hmd_draw_eye_texquads(dm1, 0, wsx, wsy, warp->xcrds, warp->ycrds);
02621 hmd_draw_eye_texquads(dm1, hw, wsx, wsy, warp->xcrds, warp->ycrds);
02622 }
02623 }
02624 glDisable(GL_TEXTURE_2D);
02625
02626
02627
02628
02629 if (drawlines) {
02630
02631 if (chromcorr) {
02632 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
02633 hmd_draw_eye_lines(dm1, 0, wsx, wsy, warp->Rxcrds, warp->Rycrds);
02634 hmd_draw_eye_lines(dm1, hw, wsx, wsy, warp->Rxcrds, warp->Rycrds);
02635 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
02636 hmd_draw_eye_lines(dm1, 0, wsx, wsy, warp->Gxcrds, warp->Gycrds);
02637 hmd_draw_eye_lines(dm1, hw, wsx, wsy, warp->Gxcrds, warp->Gycrds);
02638 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE);
02639 hmd_draw_eye_lines(dm1, 0, wsx, wsy, warp->Bxcrds, warp->Bycrds);
02640 hmd_draw_eye_lines(dm1, hw, wsx, wsy, warp->Bxcrds, warp->Bycrds);
02641 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
02642 } else {
02643 hmd_draw_eye_lines(dm1, 0, wsx, wsy, warp->xcrds, warp->ycrds);
02644 hmd_draw_eye_lines(dm1, hw, wsx, wsy, warp->xcrds, warp->ycrds);
02645 }
02646 }
02647
02648 return GLWIN_SUCCESS;
02649 }
02650
02651
02652
02653
02654
02655
02656
02657
02658 static void glwin_print_glsl_infolog(void *voidhandle, GLhandleARB obj,
02659 const char *msg) {
02660 oglhandle *handle = (oglhandle *) voidhandle;
02661 if (handle == NULL)
02662 return;
02663 glwin_ext_fctns *ext = handle->ext;
02664
02665 GLint blen = 0;
02666 GLint slen = 0;
02667 GLcharARB *infoLog;
02668
02669 GLGETOBJECTPARAMETERIVARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB , &blen);
02670 if (blen > 1) {
02671 if ((infoLog = (GLcharARB *) calloc(1, blen)) == NULL) {
02672 printf("GLSL shader compiler could not allocate InfoLog buffer\n");
02673 return;
02674 }
02675
02676 GLGETINFOLOGARB(obj, blen, &slen, infoLog);
02677 printf(" %s\n", msg);
02678 printf(" %s\n", (char *) infoLog);
02679 free(infoLog);
02680 }
02681 }
02682
02683
02684 static int glwin_compile_shaders(void *voidhandle, glsl_shader *sh,
02685 const GLubyte *vertexShader,
02686 const GLubyte *fragmentShader,
02687 int verbose) {
02688 oglhandle *handle = (oglhandle *) voidhandle;
02689 glwin_ext_fctns *ext = handle->ext;
02690
02691 GLint vert_compiled = 0;
02692 GLint frag_compiled = 0;
02693 GLint shaders_linked = 0;
02694 GLint length;
02695
02696
02697 memset(sh, 0, sizeof(glsl_shader));
02698
02699
02700 if (vertexShader == NULL || fragmentShader == NULL) {
02701 return GLWIN_ERROR;
02702 }
02703
02704
02705 length = strlen((const char *) vertexShader);
02706 GLSHADERSOURCEARB(sh->VertexShaderObject, 1, (const char **) &vertexShader, &length);
02707
02708 length = strlen((const char *) fragmentShader);
02709 GLSHADERSOURCEARB(sh->FragmentShaderObject, 1, (const char **) &fragmentShader, &length);
02710
02711
02712
02713 GLCOMPILESHADERARB(sh->VertexShaderObject);
02714 GLGETOBJECTPARAMETERIVARB(sh->VertexShaderObject,
02715 GL_OBJECT_COMPILE_STATUS_ARB, &vert_compiled);
02716
02717 if (verbose)
02718 glwin_print_glsl_infolog(voidhandle, sh->VertexShaderObject, "OpenGL vertex shader compilation log: ");
02719
02720 GLCOMPILESHADERARB(sh->FragmentShaderObject);
02721 GLGETOBJECTPARAMETERIVARB(sh->FragmentShaderObject,
02722 GL_OBJECT_COMPILE_STATUS_ARB, &frag_compiled);
02723
02724 if (verbose)
02725 glwin_print_glsl_infolog(voidhandle, sh->FragmentShaderObject, "OpenGL fragment shader compilation log: ");
02726
02727 if (vert_compiled && frag_compiled) {
02728
02729 GLATTACHOBJECTARB(sh->ProgramObject, sh->VertexShaderObject);
02730 GLATTACHOBJECTARB(sh->ProgramObject, sh->FragmentShaderObject);
02731
02732
02733 GLLINKPROGRAMARB(sh->ProgramObject);
02734 GLGETOBJECTPARAMETERIVARB(sh->ProgramObject, GL_OBJECT_LINK_STATUS_ARB, &shaders_linked);
02735
02736 if (verbose)
02737 glwin_print_glsl_infolog(voidhandle, sh->ProgramObject, "OpenGL shader linkage log: " );
02738 }
02739
02740
02741
02742
02743
02744
02745
02746
02747 if (vert_compiled)
02748 GLDELETEOBJECTARB(sh->VertexShaderObject);
02749 if (frag_compiled)
02750 GLDELETEOBJECTARB(sh->FragmentShaderObject);
02751
02752 if (vert_compiled && frag_compiled && shaders_linked) {
02753 sh->isvalid = 1;
02754 return GLWIN_SUCCESS;
02755 } else {
02756 memset(sh, 0, sizeof(glsl_shader));
02757 return GLWIN_ERROR;
02758 }
02759 }
02760
02761
02762 int glwin_destroy_shaders(void *voidhandle, glsl_shader *sh) {
02763 oglhandle *handle = (oglhandle *) voidhandle;
02764 glwin_ext_fctns *ext = handle->ext;
02765
02766
02767 if (sh->isvalid) {
02768 GLDELETEOBJECTARB(sh->ProgramObject);
02769 memset(sh, 0, sizeof(glsl_shader));
02770
02771 return GLWIN_SUCCESS;
02772 }
02773
02774 return GLWIN_ERROR;
02775 }
02776
02777
02778
02779
02780
02781 const char *hmd_vert =
02782 "// requires GLSL version 1.10 \n"
02783 "#version 110 \n"
02784 " \n"
02785 " \n"
02786 " \n"
02787 "void main(void) { \n"
02788 " // transform vertex to Eye space for user clipping plane calculations \n"
02789 " vec4 ecpos = gl_ModelViewMatrix * gl_Vertex; \n"
02790 " gl_ClipVertex = ecpos; \n"
02791 " \n"
02792 " // transform, normalize, and output normal. \n"
02793 " oglnormal = normalize(gl_NormalMatrix * gl_Normal); \n"
02794 " \n"
02795 " // pass along vertex color for use fragment shading, \n"
02796 " // fragment shader will get an interpolated color. \n"
02797 " oglcolor = vec3(gl_Color); \n"
02798 " \n"
02799 " \n"
02800 #if 1
02801 " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n"
02802 #else
02803 " gl_Position = ftransform(); \n"
02804 #endif
02805 " \n"
02806 " \n"
02807 " \n"
02808 " \n"
02809 "} \n"
02810 " \n";
02811
02812
02813 const char *hmd_frag =
02814 " \n"
02815 " \n"
02816 " \n"
02817 " \n"
02818 "void main(void) { \n"
02819 " \n"
02820 #if 1
02821 " // Flip the surface normal if it is facing away from the viewer, \n"
02822 " // determined by polygon winding order provided by OpenGL. \n"
02823 " vec3 N = normalize(oglnormal); \n"
02824 " if (!gl_FrontFacing) { \n"
02825 " N = -N; \n"
02826 " } \n"
02827 #endif
02828 " \n"
02829 " \n"
02830 " \n"
02831 " \n"
02832 " \n"
02833 " \n"
02834 "} \n"
02835 " \n";
02836
02837
02838 int glwin_compile_hmd_shaders(void *voidhandle, glsl_shader *sh) {
02839 int rc = glwin_compile_shaders(voidhandle, sh,
02840 (GLubyte *) hmd_vert, (GLubyte *) hmd_frag, 1);
02841 return rc;
02842 }
02843
02844 #endif
02845
02846
02847 void glwin_draw_image(void * voidhandle, int ixs, int iys, unsigned char * img) {
02848 glRasterPos2i(0, 0);
02849 glDrawPixels(ixs, iys, GL_RGB, GL_UNSIGNED_BYTE, img);
02850 glwin_swap_buffers(voidhandle);
02851 }
02852
02853
02854 void glwin_draw_image_rgb3u(void *voidhandle, int stereomode, int ixs, int iys,
02855 const unsigned char *rgb3u) {
02856 int wxs=0, wys=0;
02857 glwin_get_winsize(voidhandle, &wxs, &wys);
02858 glViewport(0, 0, wxs, wys);
02859
02860 glDrawBuffer(GL_BACK);
02861 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
02862 glClearColor(0.0, 0.0, 0.0, 1.0);
02863 glClear(GL_COLOR_BUFFER_BIT);
02864
02865 glShadeModel(GL_FLAT);
02866 glMatrixMode(GL_PROJECTION);
02867 glLoadIdentity();
02868 glOrtho(0.0, wxs, 0.0, wys, -1.0, 1.0);
02869 glMatrixMode(GL_MODELVIEW);
02870 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
02871 glPixelZoom(1.0, 1.0);
02872
02873 if (stereomode == GLWIN_STEREO_OVERUNDER) {
02874
02875 const unsigned char *leftimg = rgb3u;
02876 const unsigned char *rightimg = leftimg + ((ixs * (iys/2)) * 4);
02877
02878 glDrawBuffer(GL_BACK_LEFT);
02879 glRasterPos2i(0, 0);
02880 #if 0
02881 glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
02882 #endif
02883 glDrawPixels(ixs, iys/2, GL_RGBA, GL_UNSIGNED_BYTE, leftimg);
02884
02885 glDrawBuffer(GL_BACK_RIGHT);
02886 glRasterPos2i(0, 0);
02887 #if 0
02888 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
02889 #endif
02890 glDrawPixels(ixs, iys/2, GL_RGBA, GL_UNSIGNED_BYTE, rightimg);
02891 } else {
02892 glRasterPos2i(0, 0);
02893 glDrawPixels(ixs, iys, GL_RGBA, GL_UNSIGNED_BYTE, rgb3u);
02894 }
02895
02896 glwin_swap_buffers(voidhandle);
02897 }
02898
02899
02900 void glwin_draw_image_tex_rgb3u(void *voidhandle,
02901 int stereomode, int ixs, int iys,
02902 const unsigned char *rgb3u) {
02903 int wxs=0, wys=0;
02904 glwin_get_winsize(voidhandle, &wxs, &wys);
02905 glViewport(0, 0, wxs, wys);
02906
02907 glDrawBuffer(GL_BACK);
02908 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
02909 glClearColor(0.0, 0.0, 0.0, 1.0);
02910 glClear(GL_COLOR_BUFFER_BIT);
02911
02912 glShadeModel(GL_FLAT);
02913 glMatrixMode(GL_PROJECTION);
02914 glLoadIdentity();
02915 glOrtho(0.0, wxs, 0.0, wys, -1.0, 1.0);
02916 glMatrixMode(GL_MODELVIEW);
02917
02918 GLuint texName = 0;
02919 GLfloat texborder[4] = {0.0, 0.0, 0.0, 1.0};
02920 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
02921 glBindTexture(GL_TEXTURE_2D, texName);
02922
02923
02924 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, texborder);
02925 #if defined(GL_CLAMP_TO_BORDER)
02926 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
02927 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
02928 #else
02929 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
02930 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
02931 #endif
02932
02933 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
02934 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
02935 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
02936
02937 glLoadIdentity();
02938 glColor3f(1.0, 1.0, 1.0);
02939
02940 if (stereomode == GLWIN_STEREO_OVERUNDER) {
02941 const unsigned char *leftimg = rgb3u;
02942 const unsigned char *rightimg = leftimg + ((ixs * (iys/2)) * 4);
02943
02944 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ixs, iys, 0,
02945 GL_RGBA, GL_UNSIGNED_BYTE, leftimg);
02946 glEnable(GL_TEXTURE_2D);
02947
02948 glDrawBuffer(GL_BACK_LEFT);
02949 #if 0
02950 glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
02951 #endif
02952 glBegin(GL_QUADS);
02953 glTexCoord2f(0.0f, 0.0f);
02954 glVertex2f(0.0f, 0.0f);
02955 glTexCoord2f(0.0f, 0.5f);
02956 glVertex2f(0.0f, wys);
02957 glTexCoord2f(1.0f, 0.5f);
02958 glVertex2f(wxs, wys);
02959 glTexCoord2f(1.0f, 0.0f);
02960 glVertex2f(wxs, 0.0f);
02961 glEnd();
02962
02963 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ixs, iys, 0,
02964 GL_RGBA, GL_UNSIGNED_BYTE, rightimg);
02965 glEnable(GL_TEXTURE_2D);
02966
02967 glDrawBuffer(GL_BACK_RIGHT);
02968 #if 0
02969 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
02970 #endif
02971 glBegin(GL_QUADS);
02972 glTexCoord2f(0.0f, 0.5f);
02973 glVertex2f(0.0f, 0.0f);
02974 glTexCoord2f(0.0f, 1.0f);
02975 glVertex2f(0.0f, wys);
02976 glTexCoord2f(1.0f, 1.0f);
02977 glVertex2f(wxs, wys);
02978 glTexCoord2f(1.0f, 0.5f);
02979 glVertex2f(wxs, 0.0f);
02980 glEnd();
02981 } else {
02982 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ixs, iys, 0,
02983 GL_RGBA, GL_UNSIGNED_BYTE, rgb3u);
02984 glEnable(GL_TEXTURE_2D);
02985
02986 glBegin(GL_QUADS);
02987 glTexCoord2f(0.0f, 0.0f);
02988 glVertex2f(0.0f, 0.0f);
02989 glTexCoord2f(0.0f, 1.0f);
02990 glVertex2f(0.0f, wys);
02991 glTexCoord2f(1.0f, 1.0f);
02992 glVertex2f(wxs, wys);
02993 glTexCoord2f(1.0f, 0.0f);
02994 glVertex2f(wxs, 0.0f);
02995 glEnd();
02996 }
02997
02998 glDisable(GL_TEXTURE_2D);
02999
03000 glwin_swap_buffers(voidhandle);
03001 }
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013 #define SPHEREMAXRES 64
03014 void glwin_draw_sphere_tex(float rad, int res, float txlatstart, float txlatend) {
03015 int i, j;
03016 float zLo, zHi, res_1;
03017
03018 float sinLong[SPHEREMAXRES];
03019 float cosLong[SPHEREMAXRES];
03020 float sinLatVert[SPHEREMAXRES];
03021 float cosLatVert[SPHEREMAXRES];
03022 float sinLatNorm[SPHEREMAXRES];
03023 float cosLatNorm[SPHEREMAXRES];
03024 float texLat[SPHEREMAXRES];
03025 float texLong[SPHEREMAXRES];
03026
03027
03028 float txlatsz = txlatend - txlatstart;
03029
03030 if (res < 2)
03031 res = 2;
03032
03033 if (res >= SPHEREMAXRES)
03034 res = SPHEREMAXRES-1;
03035
03036 res_1 = 1.0f / res;
03037
03038
03039 float ang_twopi_res = 6.28318530718f * res_1;
03040 for (i=0; i<res; i++) {
03041 float angle = i * ang_twopi_res;
03042 sinLong[i] = sinf(angle);
03043 cosLong[i] = cosf(angle);
03044 texLong[i] = (res-i) * res_1;
03045 }
03046
03047 sinLong[res] = 0.0f;
03048 cosLong[res] = 1.0f;
03049 texLong[res] = 0.0f;
03050
03051
03052 float ang_pi_res = 3.14159265359f * res_1;
03053 for (i=0; i<=res; i++) {
03054 float angle = i * ang_pi_res;
03055 sinLatNorm[i] = sinf(angle);
03056 cosLatNorm[i] = cosf(angle);
03057 sinLatVert[i] = rad * sinLatNorm[i];
03058 cosLatVert[i] = rad * cosLatNorm[i];
03059 texLat[i] = txlatstart + (i * res_1 * txlatsz);
03060 }
03061
03062 sinLatVert[0] = 0;
03063 sinLatVert[res] = 0;
03064
03065 for (j=0; j<res; j++) {
03066 zLo = cosLatVert[j];
03067 zHi = cosLatVert[j+1];
03068
03069 float stv1 = sinLatVert[j];
03070 float stv2 = sinLatVert[j+1];
03071
03072 float stn1 = sinLatNorm[j];
03073 float ctn1 = cosLatNorm[j];
03074 float stn2 = sinLatNorm[j+1];
03075 float ctn2 = cosLatNorm[j+1];
03076
03077 glBegin(GL_QUAD_STRIP);
03078 for (i=0; i<=res; i++) {
03079 glNormal3f(sinLong[i] * stn2, cosLong[i] * stn2, ctn2);
03080 glTexCoord2f(texLong[i], texLat[j+1]);
03081 glVertex3f(stv2 * sinLong[i], stv2 * cosLong[i], zHi);
03082
03083 glNormal3f(sinLong[i] * stn1, cosLong[i] * stn1, ctn1);
03084 glTexCoord2f(texLong[i], texLat[j]);
03085 glVertex3f(stv1 * sinLong[i], stv1 * cosLong[i], zLo);
03086 }
03087 glEnd();
03088 }
03089 }
03090
03091
03092 void glwin_spheremap_draw_prepare(void *voidhandle) {
03093 glShadeModel(GL_FLAT);
03094 glDepthFunc(GL_LEQUAL);
03095 glEnable(GL_DEPTH_TEST);
03096 glClearDepth(1.0);
03097
03098 glDrawBuffer(GL_BACK);
03099 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
03100 glClearColor(0.0, 0.0, 0.0, 1.0);
03101 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
03102
03103 GLuint texName = 0;
03104 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
03105 glBindTexture(GL_TEXTURE_2D, texName);
03106
03107 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
03108 #if !(defined(WIN32) || defined(_WIN64))
03109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
03110 #else
03111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
03112 #endif
03113
03114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
03115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
03116
03117 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
03118 }
03119
03120
03121 void glwin_spheremap_upload_tex_rgb3u(void *voidhandle, int ixs, int iys,
03122 const unsigned char *rgb3u) {
03123 glDisable(GL_TEXTURE_2D);
03124 GLuint texName = 0;
03125 glBindTexture(GL_TEXTURE_2D, texName);
03126 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ixs, iys, 0,
03127 GL_RGBA, GL_UNSIGNED_BYTE, rgb3u);
03128 glEnable(GL_TEXTURE_2D);
03129 }
03130
03131
03132 void glwin_spheremap_draw_tex(void *voidhandle, int stereomode,
03133 int ixs, int iys, const float *hmdquat,
03134 float fov, float rad, int res) {
03135 int wxs=0, wys=0;
03136 float n, f, a, t, b, r, l;
03137
03138 glwin_get_winsize(voidhandle, &wxs, &wys);
03139 glViewport(0, 0, wxs, wys);
03140
03141 glDrawBuffer(GL_BACK);
03142 glClearColor(0.0, 0.0, 0.0, 1.0);
03143 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
03144
03145 glMatrixMode(GL_PROJECTION);
03146 glLoadIdentity();
03147
03148 n = 1.0f;
03149 f = 15.0f;
03150 a = wxs / ((float) wys);
03151 t = n * tanf(fov * 3.14159265359f / (180.0f*2.0f));
03152 b = -t;
03153 r = a * t;
03154 l = -r;
03155 glFrustum(l, r, b, t, n, f);
03156
03157 glMatrixMode(GL_MODELVIEW);
03158 glLoadIdentity();
03159
03160 if (hmdquat != NULL) {
03161 float hmdmat[16];
03162 quat_rot_matrix(hmdmat, hmdquat);
03163 glMultMatrixf(hmdmat);
03164 }
03165
03166 glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
03167 glColor3f(1.0, 1.0, 1.0);
03168
03169
03170
03171
03172 if (stereomode == GLWIN_STEREO_OVERUNDER) {
03173
03174 glViewport(wxs/2, 0, wxs/2, wys);
03175 glwin_draw_sphere_tex(rad, res, 0.0f, 0.5f);
03176
03177
03178 glViewport(0, 0, wxs/2, wys);
03179 glwin_draw_sphere_tex(rad, res, 0.5f, 1.0f);
03180 } else {
03181 glwin_draw_sphere_tex(rad, res, 0.0f, 1.0f);
03182 }
03183 }
03184
03185
03186 int glwin_get_wininfo(void * voidhandle, int *instereo, int *havestencil) {
03187 oglhandle * handle = (oglhandle *) voidhandle;
03188 if (handle == NULL)
03189 return -1;
03190
03191 if (instereo != NULL)
03192 *instereo = handle->instereo;
03193
03194 if (havestencil != NULL)
03195 *havestencil = handle->havestencil;
03196
03197 return 0;
03198 }
03199
03200
03201 int glwin_get_winsize(void * voidhandle, int *xsize, int *ysize) {
03202 oglhandle * handle = (oglhandle *) voidhandle;
03203 if (handle == NULL)
03204 return -1;
03205
03206 #if 0
03207 if (handle) {
03208
03209 XWindowAttributes xwa;
03210 XGetWindowAttributes(handle->dpy, handle->win, &xwa);
03211 handle->width = xwa.width;
03212 handle->height = xwa.height;
03213 }
03214 #endif
03215
03216 if (xsize != NULL)
03217 *xsize = handle->width;
03218
03219 if (ysize != NULL)
03220 *ysize = handle->height;
03221
03222 return 0;
03223 }
03224
03225
03226 int glwin_get_winpos(void * voidhandle, int *xpos, int *ypos) {
03227 oglhandle * handle = (oglhandle *) voidhandle;
03228 if (handle == NULL)
03229 return -1;
03230
03231 if (xpos != NULL)
03232 *xpos = handle->xpos;
03233
03234 if (ypos != NULL)
03235 *ypos = handle->ypos;
03236
03237 return 0;
03238 }
03239
03240
03241 int glwin_get_mousepointer(void *voidhandle, int *x, int *y) {
03242 oglhandle * handle = (oglhandle *) voidhandle;
03243 if (handle == NULL)
03244 return -1;
03245
03246 if (x != NULL)
03247 *x = handle->mousex;
03248
03249 if (y != NULL)
03250 *y = handle->mousey;
03251
03252 return 0;
03253 }
03254
03255
03256 int glwin_get_lastevent(void * voidhandle, int *evdev, int *evval, char *evkey) {
03257 oglhandle * handle = (oglhandle *) voidhandle;
03258 if (handle == NULL)
03259 return -1;
03260
03261 if (evdev != NULL)
03262 *evdev = handle->evdev;
03263
03264 if (evval != NULL)
03265 *evval = handle->evval;
03266
03267 if (evkey != NULL)
03268 *evkey = handle->evkey;
03269
03270 return 0;
03271 }
03272
03273
03274 int glwin_spaceball_available(void *voidhandle) {
03275 oglhandle * handle = (oglhandle *) voidhandle;
03276
03277
03278 if (handle->sball != NULL)
03279 return 1;
03280
03281 return 0;
03282 }
03283
03284
03285 int glwin_get_spaceball(void *voidhandle, int *rx, int *ry, int *rz, int *tx, int *ty, int *tz, int *buttons) {
03286 oglhandle * handle = (oglhandle *) voidhandle;
03287 if (handle == NULL)
03288 return 0;
03289
03290 if ((handle->sball != NULL) && (handle->sballevent.event == 1)) {
03291 *rx = handle->sballevent.rx;
03292 *ry = handle->sballevent.ry;
03293 *rz = handle->sballevent.rz;
03294 *tx = handle->sballevent.tx;
03295 *ty = handle->sballevent.ty;
03296 *tz = handle->sballevent.tz;
03297 *buttons = handle->sballevent.buttons;
03298 return 1;
03299 }
03300
03301 return 0;
03302 }
03303
03304
03305 #else
03306
03307
03308
03309
03310
03311 void * glwin_create(const char * wintitle, int width, int height) {
03312 return NULL;
03313 }
03314
03315 void glwin_destroy(void * voidhandle) {
03316 return;
03317 }
03318
03319 void glwin_swap_buffers(void * voidhandle) {
03320 return;
03321 }
03322
03323 int glwin_handle_events(void * voidhandle, int evblockmode) {
03324 return 0;
03325 }
03326
03327 int glwin_get_wininfo(void * voidhandle, int *instereo, int *havestencil) {
03328 return -1;
03329 }
03330
03331 int glwin_get_winsize(void * voidhandle, int *xsize, int *ysize) {
03332 return -1;
03333 }
03334
03335 int glwin_get_winpos(void * voidhandle, int *xpos, int *ypos) {
03336 return -1;
03337 }
03338
03339 int glwin_get_mousepointer(void *voidhandle, int *x, int *y) {
03340 return -1;
03341 }
03342
03343 int glwin_get_lastevent(void * voidhandle, int *evdev, int *evval, char *evkey) {
03344 return -1;
03345 }
03346
03347 int glwin_query_extension(const char *extname) {
03348 return 0;
03349 }
03350
03351 int glwin_query_vsync(void *voidhandle, int *onoff) {
03352 return GLWIN_NOT_IMPLEMENTED;
03353 }
03354
03355 void glwin_draw_image(void * voidhandle, int xsize, int ysize, unsigned char * img) {
03356 return;
03357 }
03358
03359 void glwin_draw_image_rgb3u(void *voidhandle, int stereomode, int ixs, int iys,
03360 const unsigned char *rgb3u) {
03361 return;
03362 }
03363
03364 void glwin_draw_image_tex_rgb3u(void *voidhandle,
03365 int stereomode, int ixs, int iys,
03366 const unsigned char *rgb3u) {
03367 return;
03368 }
03369
03370 void glwin_spheremap_draw_prepare(void *voidhandle) {
03371 return;
03372 }
03373
03374 void glwin_spheremap_upload_tex_rgb3u(void *voidhandle, int ixs, int iys,
03375 const unsigned char *rgb3u) {
03376 return;
03377 }
03378
03379 void glwin_draw_sphere_tex(float rad, int res, float txlatstart, float txlatend) {
03380 return;
03381 }
03382
03383 void glwin_spheremap_draw(void *voidhandle, int stereomode, int ixs, int iys,
03384 const float *hmdquat, float fov, float rad, int res) {
03385 return;
03386 }
03387
03388 int glwin_resize(void *voidhandle, int width, int height) {
03389 return -1;
03390 }
03391
03392 int glwin_reposition(void *voidhandle, int xpos, int ypos) {
03393 return -1;
03394 }
03395
03396 int glwin_fullscreen(void * voidhandle, int fson, int xinescreen) {
03397 return -1;
03398 }
03399
03400 int glwin_spaceball_available(void *voidhandle) {
03401 return 0;
03402 }
03403
03404 int glwin_get_spaceball(void *voidhandle, int *rx, int *ry, int *rz, int *tx, int *ty, int *tz, int *buttons) {
03405 return 0;
03406 }
03407
03408 #endif
03409