Max 5 API Reference
00001 #include "jit.gl.h" 00002 #include "jit.gl.procs.h" 00003 #include "jit.gl.support.h" 00004 #include "jit.gl.pixelformat.h" 00005 00006 /****************************************************************************/ 00007 00008 // global context 00009 static t_jit_gl_context g_jit_gl_context = NULL; 00010 void jit_gl_sys_init(void); 00011 00012 /****************************************************************************/ 00013 00014 // sys utilites for win jit_gl_create_context 00015 #ifdef WIN_VERSION 00016 PROC SpecialWglGetProcAddress(HWND hwnd, char *str); 00017 HWND jit_gl_create_window(HWND hwnd, t_box *rect); 00018 void copyDIBtoMatrix(t_jit_gl_context ctx); 00019 #endif 00020 00021 // sys utilites for mac jit_gl_create_context 00022 #ifdef MAC_VERSION 00023 static GDHandle GetDeviceAtPoint(Point loc); 00024 static GDHandle GetDeviceAtRect(long top, long left, long bottom, long right); 00025 long check_dest_matrix(void *m, t_jit_matrix_info *p_info, void **p_baseaddr); 00026 #endif 00027 00028 static long jit_gl_context_check_matrix(void *m, t_jit_matrix_info *p_info, void **p_baseaddr); 00029 00030 /****************************************************************************/ 00031 00032 #ifdef MAC_VERSION 00033 t_jit_gl_context jit_gl_create_context(void *target, t_jit_gl_context_info *info) 00034 { 00035 GLboolean ok = FALSE; 00036 long i = 0; 00037 long err = 0; 00038 long targettype = JIT_GL_TARGET_WINDOW; 00039 GLint id = 0; 00040 GLint maxtexunits = 1; 00041 long doublebuf = 1; 00042 long depthbuf = 1; 00043 long depthsize = 16; 00044 long accelerated = 1; 00045 long fsaa = 0; 00046 long pixelsize = 32; 00047 long rowbytes = 0; 00048 long quality = 0; 00049 char *baseaddr = NULL; 00050 GrafPtr cgrafSave = NULL; 00051 AGLDrawable win = NULL; 00052 AGLDevice dev = NULL; 00053 AGLDevice *pdev = NULL; 00054 long ndev = 0; 00055 t_jit_matrix_info minfo; 00056 t_box *maxobj = NULL; 00057 long newpixelformat = FALSE; 00058 Rect r; 00059 #ifdef JIT_LITTLE_ENDIAN 00060 t_jit_object *tmpmatrix; 00061 #endif 00062 00063 t_jit_gl_context jctx = NULL; 00064 t_jit_gl_native_pixelformat pixelformat = NULL; 00065 t_jit_gl_native_context ctx = NULL; 00066 t_jit_gl_pixelformat *pf = NULL; 00067 00068 GLint *attributes = NULL; 00069 GLuint acount = 0; 00070 GLuint pfcount = 0; 00071 00072 method meth=NULL; //for pwindow Max4 v. Max5 00073 00074 aglConfigure(AGL_RETAIN_RENDERERS, GL_TRUE); 00075 00076 // init the pixelformat description 00077 pf = jit_gl_pixelformat_new(); 00078 if(!pf) 00079 { 00080 error("jit.gl.context: unable to create new pixelformat: out of memory!"); 00081 return NULL; 00082 } 00083 00084 if (info && !info->pixelformat) 00085 { 00086 pf->doublebuffer = info->flags & JIT_GL_CTX_DOUBLEBUF; 00087 pf->accelerated = info->flags & JIT_GL_CTX_ACCELERATED; 00088 pf->samples = info->flags & JIT_GL_CTX_FSAA ? 4 : 0; 00089 pf->sample_buffers = pf->samples ? 1 : 0; 00090 pf->depth_size = info->flags & JIT_GL_CTX_DEPTHBUF ? 16 : 0; 00091 pf->quality = info->flags & JIT_GL_CTX_HINT_QUALITY ? 1 : 0; 00092 pf->stereo = info->flags & JIT_GL_CTX_STEREO ? 1 : 0; 00093 00094 targettype = info->targettype; 00095 info->renderer_id = 0; 00096 } 00097 else if(info) 00098 { 00099 jit_gl_pixelformat_free(pf); 00100 pf = info->pixelformat; 00101 targettype = info->targettype; 00102 info->renderer_id = 0; 00103 } 00104 00105 00106 if (!target) 00107 { 00108 post ("jit.gl.context: NULL target"); 00109 jit_gl_pixelformat_free(pf); 00110 pf = NULL; 00111 return NULL; 00112 } 00113 00114 switch (targettype) 00115 { 00116 case JIT_GL_TARGET_MATRIX: 00117 { 00118 if (!jit_object_method(target, _jit_sym_class_jit_matrix)) 00119 { 00120 post ("jit.gl.context: invalid matrix for offscreen context"); 00121 return NULL; 00122 } 00123 00124 if (!check_dest_matrix(target, &minfo, (void **)&baseaddr)) 00125 return NULL; 00126 00127 #ifdef JIT_LITTLE_ENDIAN 00128 // need a temporary swapping matrix 00129 tmpmatrix = jit_object_new(_jit_sym_jit_matrix,&minfo); 00130 if (!check_dest_matrix(tmpmatrix, &minfo, (void **)&baseaddr)) 00131 return NULL; 00132 #endif 00133 00134 pf->pixel_size = 32; 00135 pf->pixel_type = JIT_GL_PF_PIXELTYPE_RGBA; 00136 pf->accelerated = FALSE; 00137 pf->doublebuffer = FALSE; 00138 pf->target = JIT_GL_PF_TARGET_DRAW_TO_BITMAP; 00139 rowbytes = minfo.dimstride[1]; 00140 break; 00141 } 00142 case JIT_GL_TARGET_PWINDOW: 00143 { 00144 // needs more work, but this is the basic idea 00145 jit_object_method(target, gensym("get_max_obj"), &maxobj); 00146 00147 if (!maxobj) 00148 { 00149 post ("jit.gl.context: no max object for jit.pwindow!"); 00150 return NULL; 00151 } 00152 00153 if (meth=zgetfn(maxobj,gensym("nativeparentwind"))) { 00154 double jr[4]; 00155 win = (AGLDrawable) meth(maxobj); 00156 // some JUCE equivalent of LocalToGlobal called by a special method of pwindow 00157 object_attr_getdouble_array(maxobj, gensym("global_rect"), 4, jr); 00158 r.left = (short)round(jr[0]); 00159 r.top = (short)round(jr[1]); 00160 r.right = (short)round(jr[2]); 00161 r.bottom = (short)round(jr[3]); 00162 } else { 00163 error("jit.pwindow invalid jpatcher object"); 00164 return NULL; 00165 } 00166 00167 00168 dev = GetDeviceAtRect(r.top, r.left, r.bottom, r.right); 00169 00170 if (!dev) 00171 { 00172 post ("jit.gl.context: no device for new gl context!"); 00173 return NULL; 00174 } 00175 00176 pf->pixel_type = JIT_GL_PF_PIXELTYPE_RGBA; 00177 pf->target = JIT_GL_PF_TARGET_DRAW_TO_WINDOW; 00178 00179 GetPort(&cgrafSave); 00180 SetPortWindowPort((WindowPtr)win); 00181 break; 00182 } 00183 case JIT_GL_TARGET_WINDOW: 00184 default: 00185 { 00186 meth=zgetfn(target, gensym("nativeparentwind")); 00187 if(meth) { 00188 long r[4]; 00189 win = (AGLDrawable) meth(target); 00190 // some JUCE equivalent of LocalToGlobal called by a special method of pwindow 00191 object_attr_getlong_array(target, gensym("rect"), 4, r); 00192 dev = GetDeviceAtRect(r[0], r[1], r[2], r[3]); 00193 } 00194 else { 00195 error("jit.window invalid jpatcher object"); 00196 return NULL; 00197 } 00198 00199 if (!dev) 00200 { 00201 post ("jit.gl.context: no device for new gl context!"); 00202 return NULL; 00203 } 00204 00205 // set the pixel format attributes 00206 pf->pixel_type = JIT_GL_PF_PIXELTYPE_RGBA; 00207 pf->target = JIT_GL_PF_TARGET_DRAW_TO_WINDOW; 00208 00209 GetPort(&cgrafSave); 00210 SetPortWindowPort((WindowPtr)win); 00211 } 00212 } 00213 00214 // verify agl has been loaded 00215 if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) aglChoosePixelFormat) // check for existence of OpenGL 00216 { 00217 post ("jit.gl.context: OpenGL not installed"); 00218 return NULL; 00219 } 00220 00221 // keep attempting to get a native pixelformat until one is found 00222 pixelformat = NULL; 00223 pdev = pf->accelerated ? &dev : NULL; 00224 00225 // create the attributes 00226 err = jit_gl_pixelformat_create_attributes(pf, &attributes, &acount); 00227 if(err || !attributes || !acount) 00228 { 00229 jit_gl_report_error("jit.gl.context: error creating pixel format"); 00230 error("jit.gl.context: unable to get a valid pixel format!"); 00231 err = JIT_ERR_GENERIC; 00232 goto out; 00233 } 00234 00235 // try to create the pixel format 00236 pixelformat = jit_gl_pixelformat_create_native(pf, pdev); 00237 00238 // continue trying, falling back to a supported format 00239 while(!pixelformat) 00240 { 00241 if(pf->samples > 0) 00242 { 00243 pf->samples -= 2; 00244 } 00245 else if(pf->pixel_float && pf->pixel_float_target) 00246 { 00247 // set sizes to be float compatible 00248 if(pf->red_size && pf->red_size != 32 && pf->red_size != 16) 00249 pf->red_size = 32; 00250 if(pf->green_size && pf->green_size != 32 && pf->green_size != 16) 00251 pf->green_size = 32; 00252 if(pf->blue_size && pf->blue_size != 32 && pf->blue_size != 16) 00253 pf->blue_size = 32; 00254 if(pf->alpha_size && pf->alpha_size != 32 && pf->alpha_size != 16) 00255 pf->alpha_size = 32; 00256 00257 pf->pixel_size = pf->red_size; 00258 pf->pixel_size += pf->green_size; 00259 pf->pixel_size += pf->blue_size; 00260 pf->pixel_size += pf->alpha_size; 00261 00262 // try each target in this order: ATI, NV, ARB 00263 if(pf->pixel_float_target == JIT_GL_PF_PIXEL_FLOAT_ARB) 00264 { 00265 pf->pixel_float_target = JIT_GL_PF_PIXEL_FLOAT_APPLE; 00266 } 00267 else 00268 { 00269 // disable 00270 pf->pixel_float_target = 0; 00271 pf->pixel_float = 0; 00272 00273 // set sizes to be integer compatible 00274 if(pf->red_size) 00275 pf->red_size = 8; 00276 if(pf->green_size) 00277 pf->green_size = 8; 00278 if(pf->blue_size) 00279 pf->blue_size = 8; 00280 if(pf->alpha_size) 00281 pf->alpha_size = 8; 00282 00283 pf->pixel_size = pf->red_size; 00284 pf->pixel_size += pf->green_size; 00285 pf->pixel_size += pf->blue_size; 00286 pf->pixel_size += pf->alpha_size; 00287 } 00288 } 00289 else if(pf->accelerated) 00290 { 00291 pf->accelerated = FALSE; 00292 pdev = NULL; 00293 } 00294 else 00295 { 00296 break; 00297 } 00298 00299 if(attributes && acount) 00300 jit_freebytes(attributes, acount * sizeof(GLint)); 00301 attributes = NULL; acount = 0; 00302 00303 // recreate the attributes 00304 err = jit_gl_pixelformat_create_attributes(pf, &attributes, &acount); 00305 if(err || !attributes || !acount) 00306 { 00307 jit_gl_report_error("jit.gl.context: error creating pixel format"); 00308 error("jit.gl.context: unable to get a valid pixel format!"); 00309 err = JIT_ERR_GENERIC; 00310 goto out; 00311 } 00312 00313 // try again 00314 pixelformat = jit_gl_pixelformat_create_native(pf, pdev); 00315 } 00316 00317 // verify pixelformat was created 00318 if(!pixelformat) 00319 { 00320 err = JIT_ERR_INVALID_PTR; 00321 goto out; 00322 } 00323 00324 // output warning for sw renderer 00325 if(!pf->accelerated) 00326 { 00327 post("jit.gl.context: using software renderer."); 00328 } 00329 00330 // get renderer id 00331 if (!aglDescribePixelFormat(pixelformat, AGL_RENDERER_ID, &id)) 00332 { 00333 jit_gl_report_error("jit.gl.context: error registering pixel format"); 00334 err = JIT_ERR_GENERIC; 00335 goto out; 00336 } 00337 00338 // create the native context 00339 if(info->share) 00340 ctx = aglCreateContext(pixelformat, info->share->context); //could support sharing here 00341 else 00342 ctx = aglCreateContext(pixelformat, NULL); //could support sharing here 00343 00344 if (ctx == NULL) 00345 { 00346 jit_gl_report_error("jit.gl.context: error creating context"); 00347 err = JIT_ERR_GENERIC; 00348 goto out; 00349 } 00350 00351 // attach the window to the context 00352 switch(targettype) 00353 { 00354 case JIT_GL_TARGET_WINDOW: 00355 { 00356 GLboolean success; 00357 success = aglSetDrawable(ctx, GetWindowPort((CWindowPtr)win)); 00358 00359 if (!success) 00360 { 00361 err = jit_gl_report_error("jit.gl.context: error setting drawable for context"); 00362 if (err == AGL_BAD_ALLOC) 00363 { 00364 post ("jit.gl.context: not enough memory for window."); 00365 post ("try reducing your monitor resolution or depth, or"); 00366 post ("setting depthbuffer or doublebuffer to 0."); 00367 } 00368 err = JIT_ERR_GENERIC; 00369 goto out; 00370 } 00371 break; 00372 } 00373 00374 case JIT_GL_TARGET_PWINDOW: 00375 { 00376 GLboolean success; 00377 00378 if(meth) { 00379 success = aglSetDrawable(ctx, win); 00380 } 00381 else { 00382 success = aglSetDrawable(ctx, GetWindowPort((CWindowPtr)win)); 00383 } 00384 00385 if (!success) 00386 { 00387 err = jit_gl_report_error("jit.gl.context: error setting drawable for context"); 00388 if (err == AGL_BAD_ALLOC) 00389 { 00390 post ("jit.gl.context: not enough memory for window."); 00391 post ("try reducing your monitor resolution or depth, or"); 00392 post ("setting depthbuffer or doublebuffer to 0."); 00393 } 00394 err = JIT_ERR_GENERIC; 00395 goto out; 00396 } 00397 break; 00398 } 00399 case JIT_GL_TARGET_MATRIX: 00400 { 00401 if (!aglSetOffScreen(ctx, minfo.dim[0], minfo.dim[1], rowbytes, baseaddr)) 00402 { 00403 jit_gl_report_error("jit.gl.context: error setting offscreen drawable for context"); 00404 err = JIT_ERR_GENERIC; 00405 goto out; 00406 } 00407 break; 00408 } 00409 default: 00410 { 00411 break; 00412 } 00413 } 00414 00415 // make the context the current context 00416 if (!aglSetCurrentContext(ctx)) 00417 { 00418 jit_gl_report_error("jit.gl.context: error making context current"); 00419 err = JIT_ERR_GENERIC; 00420 goto out; 00421 } 00422 00423 // update the context 00424 if (!aglUpdateContext(ctx)) 00425 { 00426 jit_gl_report_error("jit.gl.context: error updating current context"); 00427 err = JIT_ERR_GENERIC; 00428 goto out; 00429 } 00430 00431 // enable multisampling 00432 if (pf->samples) 00433 { 00434 glEnable(GL_MULTISAMPLE_ARB); 00435 //glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); 00436 } 00437 else 00438 { 00439 glDisable(GL_MULTISAMPLE_ARB); 00440 } 00441 jit_gl_report_error("jit_gl_create_context: multisamples"); 00442 00443 //more setup for default behavior which is not always true 00444 { 00445 // read/drawbuffer 00446 if (pf->doublebuffer) { 00447 glDrawBuffer(GL_BACK); 00448 glReadBuffer(GL_BACK); 00449 } else { 00450 glDrawBuffer(GL_FRONT); 00451 glReadBuffer(GL_FRONT); 00452 } 00453 jit_gl_report_error("jit_gl_create_context: read/draw buffer"); 00454 00455 } 00456 00457 out: 00458 00459 if (err) 00460 { 00461 if (ctx) 00462 { 00463 jit_gl_destroy_native_context(ctx); 00464 ctx = NULL; 00465 } 00466 00467 if (pixelformat) 00468 { 00469 jit_gl_pixelformat_destroy_native(pixelformat); 00470 pixelformat = NULL; 00471 } 00472 jctx = NULL; 00473 } 00474 else 00475 { 00476 // allocate jit_gl_context 00477 if (jctx = (t_jit_gl_context)jit_newptr(sizeof(t_jit_gl_context_struct))) 00478 { 00479 char pixfmt[256]; 00480 pixfmt[0] = 0; 00481 00482 jctx->context = ctx; 00483 jctx->drawable = win; //what do we do here for the offscreen? 00484 jctx->pixelformat = pixelformat; 00485 jctx->target = target; 00486 jctx->targettype = targettype; 00487 jctx->flags = 0; 00488 jctx->auxdata = NULL; 00489 jctx->extensions = jit_gl_get_extensions(); 00490 jctx->procs = (t_jit_gl_extprocs *)jit_newptr(sizeof(t_jit_gl_extprocs)); 00491 jit_gl_init_extension_procs(jctx->procs); 00492 jctx->support = jit_gl_support_new(); 00493 jit_gl_support_init(jctx->support, jctx->extensions); 00494 g_jit_gl_context = jctx; 00495 00496 #ifdef JIT_LITTLE_ENDIAN 00497 // need a temporary swapping matrix 00498 if (targettype==JIT_GL_TARGET_MATRIX) { 00499 jctx->target = tmpmatrix; 00500 jctx->auxdata = target; 00501 } 00502 #endif 00503 00504 // post format spec to console 00505 /* 00506 sprintf(pixfmt, "R:%d%sG:%d%sB:%d%sA:%d%sD:%d FSAA:%dx%d", 00507 jctx->support->color_red_bits, jctx->support->color_float_pixels ? "f" : " ", 00508 jctx->support->color_green_bits, jctx->support->color_float_pixels ? "f" : " ", 00509 jctx->support->color_blue_bits, jctx->support->color_float_pixels ? "f" : " ", 00510 jctx->support->color_alpha_bits, jctx->support->color_float_pixels ? "f" : " ", 00511 jctx->support->depth_bits, jctx->support->multisample_samples, jctx->support->multisample_buffers); 00512 00513 switch (targettype) 00514 { 00515 case JIT_GL_TARGET_PWINDOW: 00516 post("jit.pwindow: using pixelformat %s", pixfmt); 00517 break; 00518 00519 case JIT_GL_TARGET_MATRIX: 00520 post("jit.matrix: using pixelformat %s", pixfmt); 00521 break; 00522 00523 case JIT_GL_TARGET_WINDOW: 00524 post("jit.window: using pixelformat %s", pixfmt); 00525 break; 00526 } 00527 00528 */ 00529 } 00530 } 00531 00532 if (targettype != JIT_GL_TARGET_MATRIX && targettype != JIT_GL_TARGET_TEXTURE) 00533 MacSetPort (cgrafSave); 00534 00535 if (info) 00536 { 00537 info->renderer_id = id; 00538 00539 // currently we are not passing in any pixel formats to be freed 00540 //if(info->pixelformat) 00541 // jit_gl_pixelformat_free(info->pixelformat); 00542 info->pixelformat = NULL; 00543 info->pixelformat = pf; 00544 } 00545 else 00546 { 00547 jit_gl_pixelformat_free(pf); 00548 pf = NULL; 00549 } 00550 00551 return jctx; 00552 } 00553 00554 #endif //MAC_VERSION 00555 #ifdef WIN_VERSION 00556 t_jit_gl_context jit_gl_create_context(void *target, t_jit_gl_context_info *info) 00557 { 00558 GLint maxtexunits = 1; 00559 GLboolean ok = FALSE; 00560 long i = 0; 00561 long targettype = JIT_GL_TARGET_WINDOW; 00562 long doublebuf = 1; 00563 long depthbuf = 1; 00564 long depthsize = 16; 00565 long accelerated = 1; 00566 long pixelsize = 32; 00567 long fmt = 0; 00568 HDC pdev = NULL; 00569 HDC hdc = NULL; 00570 HGLRC ctx = NULL; 00571 HWND hwnd = NULL; 00572 PIXELFORMATDESCRIPTOR pfd; 00573 BITMAPINFO binfo; 00574 GLubyte *bits = NULL; 00575 HBITMAP bitmap = NULL; 00576 t_jit_matrix_info minfo; 00577 t_box *maxobj = NULL; 00578 t_jit_err err = JIT_ERR_NONE; 00579 long valid = 0; 00580 int renderToWindow = 0; 00581 00582 GLint *attributes = NULL; 00583 GLuint acount = 0; 00584 GLuint pfcount = 0; 00585 00586 method meth=NULL; //for pwindow Max4 v. Max5 00587 00588 PFNWGLCHOOSEPIXELFORMATARBPROC pfwglChoosePixelFormatARB = NULL; 00589 00590 t_jit_gl_context jctx = NULL; 00591 t_jit_gl_pixelformat *pf = NULL; 00592 t_jit_gl_native_pixelformat pixelformat = NULL; 00593 00594 // init the pixelformat description 00595 pf = jit_gl_pixelformat_new(); 00596 if(!pf) 00597 { 00598 error("jit.gl: unable to create new pixelformat: out of memory!"); 00599 return NULL; 00600 } 00601 00602 if (info && !info->pixelformat) 00603 { 00604 pf->doublebuffer = info->flags & JIT_GL_CTX_DOUBLEBUF; 00605 pf->accelerated = info->flags & JIT_GL_CTX_ACCELERATED; 00606 pf->samples = info->flags & JIT_GL_CTX_FSAA ? 4 : 0; 00607 pf->sample_buffers = pf->samples ? 1 : 0; 00608 pf->depth_size = info->flags & JIT_GL_CTX_DEPTHBUF ? 16 : 0; 00609 pf->quality = info->flags & JIT_GL_CTX_HINT_QUALITY ? 1 : 0; 00610 pf->stereo = info->flags & JIT_GL_CTX_STEREO ? 1 : 0; 00611 00612 targettype = info->targettype; 00613 info->renderer_id = 0; 00614 } 00615 else 00616 { 00617 jit_gl_pixelformat_free(pf); 00618 pf = info->pixelformat; 00619 targettype = info->targettype; 00620 info->renderer_id = 0; 00621 } 00622 00623 jit_gl_sys_init(); 00624 00625 switch (targettype) 00626 { 00627 case JIT_GL_TARGET_MATRIX: 00628 { 00629 if (!jit_object_method(target, _jit_sym_class_jit_matrix)) 00630 { 00631 post ("jit.gl.context: invalid matrix for offscreen context"); 00632 return NULL; 00633 } 00634 00635 jit_object_method(target, _jit_sym_getinfo, &minfo); 00636 hdc = CreateCompatibleDC(NULL); 00637 00638 if (!hdc) 00639 { 00640 post ("jit.gl.context: no device for new gl context!"); 00641 return NULL; 00642 } 00643 00644 // create and bind the bitmap 00645 memset(&binfo, 0, sizeof(BITMAPINFOHEADER)); 00646 binfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 00647 binfo.bmiHeader.biWidth = minfo.dim[0]; 00648 binfo.bmiHeader.biHeight = minfo.dim[1]; 00649 binfo.bmiHeader.biPlanes = 1; 00650 binfo.bmiHeader.biBitCount = 32; 00651 binfo.bmiHeader.biCompression = BI_RGB; 00652 bitmap = CreateDIBSection(hdc, &binfo, DIB_RGB_COLORS, &bits, NULL, 0); 00653 00654 if (!bitmap) 00655 { 00656 post ("jit.gl.context: couldn't create bitmap for new gl context!"); 00657 return NULL; 00658 } 00659 00660 SelectObject(hdc, bitmap); 00661 00662 pf->pixel_size = 32; 00663 pf->pixel_type = JIT_GL_PF_PIXELTYPE_RGBA; 00664 pf->accelerated = FALSE; 00665 pf->doublebuffer = FALSE; 00666 pf->target = JIT_GL_PF_TARGET_DRAW_TO_BITMAP; 00667 break; 00668 } 00669 case JIT_GL_TARGET_TEXTURE: 00670 { 00671 // pf->accelerated = TRUE; 00672 pf->pixel_type = JIT_GL_PF_PIXELTYPE_RGBA; 00673 pf->target = JIT_GL_PF_TARGET_DRAW_TO_PBUFFER; 00674 pf->flags |= JIT_GL_PF_FLAG_BIND_TO_TEXTURE; 00675 break; 00676 } 00677 case JIT_GL_TARGET_PWINDOW: 00678 { 00679 renderToWindow = 1; 00680 // the target is not the max object, so we need to get the max obj 00681 jit_object_method(target, gensym("get_max_obj"), &maxobj); 00682 00683 if (!maxobj) 00684 { 00685 post ("jit.gl.context: no max object for jit.pwindow!"); 00686 return NULL; 00687 } 00688 00689 if (meth=zgetfn((t_object *)maxobj,gensym("nativeparentwind"))) { 00690 hwnd = (HWND) meth(maxobj); 00691 } 00692 else { 00693 error("jit.pwindow invalid jpatcher object"); 00694 return NULL; 00695 } 00696 00697 if (!hwnd) 00698 { 00699 post ("jit.gl.context: no window for new gl context!"); 00700 return NULL; 00701 } 00702 00703 hwnd = jit_gl_create_window(hwnd, maxobj); 00704 /* 00705 hwnd = CreateWindow(JIT_GL_WINDCLASSNAME, JIT_GL_WINDCLASSNAME, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 00706 maxobj->b_rect.left, maxobj->b_rect.top, 00707 maxobj->b_rect.right - maxobj->b_rect.left, 00708 maxobj->b_rect.bottom - maxobj->b_rect.top, 00709 hwnd, NULL, _jit_gl_hinst, 0); 00710 */ 00711 if (!hwnd) 00712 { 00713 post ("jit.gl.context: could not create window for new gl context!"); 00714 return NULL; 00715 } 00716 00717 ShowWindow(hwnd, SW_SHOWNORMAL); 00718 hdc = GetDC(hwnd); 00719 00720 if (!hdc) 00721 { 00722 post ("jit.gl.context: no device for new gl context!"); 00723 return NULL; 00724 } 00725 00726 pf->pixel_type = JIT_GL_PF_PIXELTYPE_RGBA; 00727 pf->target = JIT_GL_PF_TARGET_DRAW_TO_WINDOW; 00728 break; 00729 } 00730 case JIT_GL_TARGET_WINDOW: 00731 default: 00732 { 00733 renderToWindow = 1; 00734 meth=zgetfn(target, gensym("nativeparentwind")); 00735 if(meth) { 00736 hwnd = (HWND)meth(target); 00737 } 00738 else { 00739 error("jit.window invalid jpatcher object"); 00740 return NULL; 00741 } 00742 00743 if (!hwnd) 00744 { 00745 post ("jit.gl.context: no window for new gl context!"); 00746 return NULL; 00747 } 00748 00749 hdc = GetDC(hwnd); 00750 /* //debug 00751 { 00752 char tmp[256]; 00753 DWORD style = GetClassLong(hwnd, GCL_STYLE); 00754 tmp[0]=0; 00755 GetClassName(hwnd,tmp,255); 00756 post("window class: %s, style: %x, CS_OWNDC: %d",tmp, style, style&CS_OWNDC); 00757 post("window style: %x, exstyle: %x",GetWindowLong(hwnd, GWL_STYLE), GetWindowLong(hwnd, GWL_EXSTYLE)); 00758 } 00759 */ 00760 00761 if (!hdc) 00762 { 00763 post ("jit.gl.context: no device for new gl context!"); 00764 return NULL; 00765 } 00766 00767 pf->pixel_type = JIT_GL_PF_PIXELTYPE_RGBA; 00768 pf->target = JIT_GL_PF_TARGET_DRAW_TO_WINDOW; 00769 00770 } 00771 } 00772 00773 if (hwnd) 00774 pfwglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)SpecialWglGetProcAddress(hwnd, "wglChoosePixelFormatARB"); 00775 00776 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); 00777 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); 00778 pfd.nVersion = 1; 00779 00780 pfd.dwFlags = PFD_SUPPORT_OPENGL | 00781 (renderToWindow ? PFD_DRAW_TO_WINDOW : PFD_DRAW_TO_BITMAP) | 00782 (pf->doublebuffer ? PFD_DOUBLEBUFFER : 0) | 00783 (pf->accelerated ? 0 : PFD_GENERIC_FORMAT); 00784 00785 pfd.iPixelType = PFD_TYPE_RGBA; 00786 00787 if(pf->pixel_size <= 0) 00788 pf->pixel_size = 32; 00789 00790 pfd.cColorBits = pf->pixel_size; 00791 pfd.cRedBits = 0; 00792 pfd.cRedShift = 0; 00793 pfd.cGreenBits = 0; 00794 pfd.cGreenShift = 0; 00795 pfd.cBlueBits = 0; 00796 pfd.cBlueShift = 0; 00797 pfd.cAlphaBits = 0; 00798 pfd.cAlphaShift = 0; 00799 pfd.cAccumBits = 0; 00800 pfd.cAccumRedBits = 0; 00801 pfd.cAccumGreenBits = 0; 00802 pfd.cAccumBlueBits = 0; 00803 pfd.cAccumAlphaBits = 0; 00804 pfd.cDepthBits = pf->depth_size; 00805 pfd.cStencilBits = 0; 00806 pfd.cAuxBuffers = 0; 00807 pfd.iLayerType = PFD_MAIN_PLANE; 00808 pfd.bReserved = 0; 00809 pfd.dwLayerMask = 0; 00810 pfd.dwVisibleMask = 0; 00811 pfd.dwDamageMask = 0; 00812 00813 if (targettype == JIT_GL_TARGET_MATRIX || (pfwglChoosePixelFormatARB == NULL)) 00814 { 00815 // Choose an rgb pixel format for given device. we have to specify which device, 00816 // or we would get stuck with the software renderer on multi-card systems. 00817 fmt = ChoosePixelFormat(hdc, &pfd); 00818 pf->samples = 0; 00819 00820 // couldn't get a hardware renderer, try getting a software renderer. 00821 if (!fmt) 00822 { 00823 pfd.dwFlags = PFD_SUPPORT_OPENGL | 00824 (renderToWindow ? PFD_DRAW_TO_WINDOW : PFD_DRAW_TO_BITMAP) | 00825 (pf->doublebuffer ? PFD_DOUBLEBUFFER : 0) | 00826 PFD_GENERIC_FORMAT; 00827 00828 fmt = ChoosePixelFormat(hdc, &pfd); 00829 if (fmt) 00830 { 00831 // post("jit.gl.context: using software renderer."); 00832 } 00833 else 00834 { 00835 err = JIT_ERR_GENERIC; 00836 goto out; 00837 } 00838 } 00839 } 00840 else 00841 { 00842 GLfloat fattrib[] = {0,0}; 00843 pdev = pf->accelerated ? hdc : NULL; 00844 00845 // create the attribute array for the current pixel format 00846 err = jit_gl_pixelformat_create_attributes(pf, &attributes, &acount); 00847 if(err || !attributes || !acount) 00848 { 00849 jit_gl_report_error("jit.gl.context: error creating pixel format"); 00850 error("jit.gl.context: unable to get a valid pixel format!"); 00851 err = JIT_ERR_GENERIC; 00852 goto out; 00853 } 00854 00855 // attempt to get the pixelformat 00856 pixelformat = jit_getbytes(sizeof(GLint)); 00857 valid = pfwglChoosePixelFormatARB(hdc, attributes, fattrib, 1, pixelformat, &pfcount); 00858 00859 // continue trying, falling back to a supported format 00860 while(!valid || !pixelformat || pfcount < 1) 00861 { 00862 if(pf->samples > 0) 00863 { 00864 pf->samples -= 2; 00865 } 00866 else if(pf->pixel_float && pf->pixel_float_target) 00867 { 00868 // set sizes to be float compatible 00869 if(pf->red_size && pf->red_size != 32 && pf->red_size != 16) 00870 pf->red_size = 32; 00871 if(pf->green_size && pf->green_size != 32 && pf->green_size != 16) 00872 pf->green_size = 32; 00873 if(pf->blue_size && pf->blue_size != 32 && pf->blue_size != 16) 00874 pf->blue_size = 32; 00875 if(pf->alpha_size && pf->alpha_size != 32 && pf->alpha_size != 16) 00876 pf->alpha_size = 32; 00877 00878 pf->pixel_size = pf->red_size; 00879 pf->pixel_size += pf->green_size; 00880 pf->pixel_size += pf->blue_size; 00881 pf->pixel_size += pf->alpha_size; 00882 00883 // try each target in this order: ARB, ATI, NV 00884 if(pf->pixel_float_target == JIT_GL_PF_PIXEL_FLOAT_ARB) 00885 { 00886 pf->pixel_float_target = JIT_GL_PF_PIXEL_FLOAT_ATI; 00887 } 00888 else if(pf->pixel_float_target == JIT_GL_PF_PIXEL_FLOAT_ATI) 00889 { 00890 pf->pixel_float_target = JIT_GL_PF_PIXEL_FLOAT_NV; 00891 } 00892 else 00893 { 00894 // disable 00895 pf->pixel_float_target = 0; 00896 pf->pixel_float = 0; 00897 post("jit.gl.context: error choosing float pixels: switching to fixed point."); 00898 00899 // set sizes to be integer compatible 00900 if(pf->red_size) 00901 pf->red_size = 8; 00902 if(pf->green_size) 00903 pf->green_size = 8; 00904 if(pf->blue_size) 00905 pf->blue_size = 8; 00906 if(pf->alpha_size) 00907 pf->alpha_size = 8; 00908 00909 pf->pixel_size = pf->red_size; 00910 pf->pixel_size += pf->green_size; 00911 pf->pixel_size += pf->blue_size; 00912 pf->pixel_size += pf->alpha_size; 00913 00914 } 00915 } 00916 else if(pf->accelerated) 00917 { 00918 pf->accelerated = FALSE; 00919 pdev = NULL; 00920 } 00921 else 00922 { 00923 break; 00924 } 00925 00926 if(attributes && acount) 00927 jit_freebytes(attributes, acount * sizeof(GLint)); 00928 attributes = NULL; acount = 0; 00929 00930 // recreate the attributes 00931 err = jit_gl_pixelformat_create_attributes(pf, &attributes, &acount); 00932 if(err || !attributes || !acount) 00933 { 00934 jit_gl_report_error("jit.gl.context: error creating pixel format"); 00935 error("jit.gl.context: unable to get a valid pixel format!"); 00936 err = JIT_ERR_GENERIC; 00937 goto out; 00938 } 00939 00940 // try again 00941 valid = pfwglChoosePixelFormatARB(hdc, attributes, fattrib, 1, pixelformat, &pfcount); 00942 } 00943 00944 // verify pixelformat was created 00945 if(!pixelformat) 00946 { 00947 ok = FALSE; 00948 err = JIT_ERR_GENERIC; 00949 goto out; 00950 } 00951 00952 // output warning for sw renderer 00953 if(!pf->accelerated) 00954 { 00955 post("jit.gl.context: using software renderer."); 00956 } 00957 00958 fmt = *pixelformat; 00959 } 00960 00961 00962 00963 00964 // cannot call set pixel format more than once for a given window 00965 if ((i = GetPixelFormat(hdc)) != fmt) 00966 { 00967 if (i) 00968 { 00969 post("warning: pixel format has already been set to %d, cannot set to %d", i, fmt); 00970 } 00971 else 00972 { 00973 ok = SetPixelFormat(hdc, fmt, &pfd); 00974 00975 /*{ 00976 int iPixelFormat; 00977 00978 iPixelFormat = GetPixelFormat (hdc); 00979 DescribePixelFormat (hdc, iPixelFormat, sizeof 00980 (PIXELFORMATDESCRIPTOR), &pfd); 00981 00982 // stereo mode not accepted 00983 if (((pfd.dwFlags & PFD_STEREO) == 0) && pf->stereo) { 00984 post("jit.gl.context: Stereo failed, make sure quad-buffered stereo is enabled"); 00985 } 00986 }*/ 00987 00988 if (!ok) 00989 { 00990 post("jit.gl.context: SetPixelFormat failed - %d", GetLastError()); 00991 err = JIT_ERR_GENERIC; 00992 goto out; 00993 } 00994 } 00995 } 00996 00997 // Create GL context 00998 ctx = wglCreateContext(hdc); 00999 if (ctx == NULL) 01000 { 01001 post("jit.gl.context: wglCreateContext failed - %d", GetLastError()); 01002 post("Please make sure that your monitor is set to 32 bit resolution."); 01003 err = JIT_ERR_GENERIC; 01004 goto out; 01005 } 01006 01007 //if sharing, share context resources 01008 if(info->share) { 01009 wglShareLists(ctx, info->share->context); 01010 } 01011 01012 // Make the context the current context 01013 SelectClipRgn(hdc, NULL); 01014 01015 ok = wglMakeCurrent(hdc, ctx); 01016 if (!ok) 01017 { 01018 post("jit.gl.context: wglMakeCurrent failed - %d", GetLastError()); 01019 err = JIT_ERR_GENERIC; 01020 goto out; 01021 } 01022 01023 if (pf->samples) 01024 { 01025 glEnable(GL_MULTISAMPLE_ARB); 01026 // glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); 01027 } 01028 else 01029 { 01030 if (jit_gl_is_min_version(1,3,0)) 01031 glDisable(GL_MULTISAMPLE_ARB); 01032 } 01033 jit_gl_report_error("jit_gl_create_context: multisamples"); 01034 01035 //more setup for default behavior which is not always true 01036 { 01037 // read/drawbuffer 01038 if (pf->doublebuffer) { 01039 glDrawBuffer(GL_BACK); 01040 glReadBuffer(GL_BACK); 01041 } else { 01042 glDrawBuffer(GL_FRONT); 01043 glReadBuffer(GL_FRONT); 01044 } 01045 jit_gl_report_error("jit_gl_create_context: read/draw buffer"); 01046 01047 } 01048 01049 01050 out: 01051 01052 if (!ok || err) 01053 { 01054 if(pf) 01055 { 01056 jit_gl_pixelformat_free(pf); 01057 pf = NULL; 01058 } 01059 01060 if(pixelformat) 01061 { 01062 jit_gl_pixelformat_destroy_native(pixelformat); 01063 pixelformat = NULL; 01064 } 01065 01066 if(attributes && acount) 01067 jit_freebytes(attributes, acount * sizeof(GLint)); 01068 attributes = NULL; acount = 0; 01069 01070 if (ctx) 01071 { 01072 wglDeleteContext(ctx); 01073 ctx = NULL; 01074 } 01075 01076 if (hdc) 01077 { 01078 ReleaseDC(hwnd, hdc); 01079 } 01080 01081 switch (targettype) 01082 { 01083 case JIT_GL_TARGET_PWINDOW: 01084 { 01085 if (hwnd) 01086 DestroyWindow(hwnd); 01087 01088 break; 01089 } 01090 case JIT_GL_TARGET_MATRIX: 01091 { 01092 if (bitmap) 01093 DeleteObject(bitmap); 01094 01095 break; 01096 } 01097 } 01098 jctx = NULL; 01099 } 01100 else 01101 { 01102 //wglShareLists(ctx,share); //could support sharing here 01103 //allocate jit_gl_context 01104 01105 if(attributes && acount) 01106 jit_freebytes(attributes, acount * sizeof(GLint)); 01107 attributes = NULL; acount = 0; 01108 01109 if (jctx = (t_jit_gl_context) jit_newptr(sizeof(t_jit_gl_context_struct))) 01110 { 01111 char pixfmt[256]; 01112 pixfmt[0] = 0; 01113 01114 jctx->context = ctx; 01115 jctx->drawable = hdc; //what do we do here for the offscreen? 01116 jctx->pixelformat = jit_getbytes(sizeof(GLint)); 01117 *jctx->pixelformat = fmt; 01118 jctx->target = target; 01119 jctx->targettype = targettype; 01120 jctx->flags = 0; 01121 jctx->extensions = jit_gl_get_extensions(); 01122 jctx->procs = (t_jit_gl_extprocs *)jit_newptr(sizeof(t_jit_gl_extprocs)); 01123 jit_gl_init_extension_procs(jctx->procs); 01124 jctx->support = jit_gl_support_new(); 01125 jit_gl_support_init(jctx->support, jctx->extensions); 01126 01127 // post format spec to console 01128 /* 01129 sprintf(pixfmt, "R:%d%sG:%d%sB:%d%sA:%d%sD:%d FSAA:%dx%d", 01130 jctx->support->color_red_bits, jctx->support->color_float_pixels ? "f" : " ", 01131 jctx->support->color_green_bits, jctx->support->color_float_pixels ? "f" : " ", 01132 jctx->support->color_blue_bits, jctx->support->color_float_pixels ? "f" : " ", 01133 jctx->support->color_alpha_bits, jctx->support->color_float_pixels ? "f" : " ", 01134 jctx->support->depth_bits, jctx->support->multisample_samples, jctx->support->multisample_buffers); 01135 */ 01136 switch (targettype) 01137 { 01138 case JIT_GL_TARGET_PWINDOW: 01139 jctx->auxdata = hwnd; 01140 //post("jit.pwindow: using pixelformat %s", pixfmt); 01141 break; 01142 01143 case JIT_GL_TARGET_MATRIX: 01144 //post("jit.matrix: using pixelformat %s", pixfmt); 01145 jctx->auxdata = bitmap; 01146 break; 01147 01148 case JIT_GL_TARGET_WINDOW: 01149 //post("jit.window: using pixelformat %s", pixfmt); 01150 01151 default: 01152 jctx->auxdata = NULL; 01153 } 01154 01155 g_jit_gl_context = jctx; 01156 } 01157 } 01158 01159 return jctx; 01160 } 01161 01162 #endif //WIN_VERSION 01163 01164 /****************************************************************************/ 01165 01166 GLboolean jit_gl_destroy_context(t_jit_gl_context ctx) 01167 { 01168 GLboolean rv = TRUE; 01169 01170 if (ctx && ctx->context) 01171 { 01172 #ifdef MAC_VERSION 01173 // should detach drawable in case? 01174 jit_gl_pixelformat_destroy_native(ctx->pixelformat); 01175 ctx->pixelformat = NULL; 01176 jit_gl_destroy_native_context(ctx->context); 01177 ctx->context = NULL; 01178 #ifdef JIT_LITTLE_ENDIAN 01179 // need a temporary swapping matrix 01180 if (ctx->targettype==JIT_GL_TARGET_MATRIX) { 01181 jit_object_free(ctx->target); 01182 ctx->target = NULL; 01183 } 01184 #endif 01185 #endif 01186 #ifdef WIN_VERSION 01187 01188 jit_gl_destroy_native_context(ctx->context); 01189 ctx->context = NULL; 01190 01191 switch (ctx->targettype) 01192 { 01193 01194 case JIT_GL_TARGET_PWINDOW: 01195 ReleaseDC((HWND)ctx->auxdata, ctx->drawable); 01196 01197 if (ctx->auxdata) 01198 DestroyWindow((HWND)ctx->auxdata); 01199 01200 break; 01201 01202 case JIT_GL_TARGET_WINDOW: 01203 ReleaseDC( (HWND)object_method(ctx->target, gensym("nativeparentwind")) , ctx->drawable); 01204 01205 break; 01206 01207 case JIT_GL_TARGET_MATRIX: 01208 if (ctx->auxdata) 01209 { 01210 DeleteObject((HANDLE)ctx->auxdata); 01211 ctx->auxdata = NULL; 01212 } 01213 01214 DeleteDC(ctx->drawable); 01215 break; 01216 } 01217 01218 #endif 01219 jit_disposeptr((char *)ctx->procs); 01220 if(ctx->pixelformat) 01221 jit_freebytes(ctx->pixelformat, sizeof(GLint)); 01222 01223 // zero memory just in case 01224 ctx->context = NULL; 01225 ctx->drawable = NULL; 01226 ctx->pixelformat = NULL; 01227 ctx->target = NULL; 01228 ctx->extensions = NULL; 01229 if (ctx->support) 01230 jit_gl_support_free(ctx->support); 01231 01232 ctx->support = NULL; 01233 } 01234 01235 if (ctx) 01236 jit_disposeptr((char *)ctx); 01237 01238 return rv; 01239 } 01240 01241 GLboolean jit_gl_destroy_native_context(t_jit_gl_native_context native) 01242 { 01243 01244 #ifdef MAC_VERSION 01245 01246 if (native) 01247 return aglDestroyContext(native); 01248 01249 #endif 01250 #ifdef WIN_VERSION 01251 01252 if (native) 01253 return wglDeleteContext(native); 01254 01255 #endif 01256 01257 return FALSE; 01258 } 01259 01260 /****************************************************************************/ 01261 01262 GLboolean jit_gl_update_context(t_jit_gl_context ctx) 01263 { 01264 #ifdef MAC_VERSION 01265 01266 if (ctx && ctx->context) 01267 return aglUpdateContext(ctx->context); 01268 else 01269 return FALSE; 01270 01271 #endif 01272 #ifdef WIN_VERSION 01273 01274 t_box *maxobj; 01275 method meth=NULL; 01276 01277 if (ctx && ctx->context) 01278 { 01279 switch (ctx->targettype) 01280 { 01281 01282 case JIT_GL_TARGET_PWINDOW: 01283 jit_object_method(ctx->target, gensym("get_max_obj"), &maxobj); 01284 01285 if (!maxobj) 01286 { 01287 post ("jit_gl_update_context: no max object for jit.pwindow!"); 01288 return FALSE; 01289 } 01290 01291 if (!ctx->auxdata) 01292 { 01293 post ("jit_gl_update_context: no HWND for jit.pwindow!"); 01294 return FALSE; 01295 } 01296 01297 01298 if (meth=zgetfn((t_object *)maxobj,gensym("nativeparentwind"))) { 01299 double jr[4]; 01300 // rbs -- need to convert from screen-relative coordinates to parent-relative 01301 HWND hwnd = (HWND) ctx->auxdata; 01302 HWND hwndParent = GetParent(hwnd); 01303 POINT topleft; 01304 POINT bottomright; 01305 01306 object_method(maxobj, gensym("patch_rect"), jr); 01307 topleft.x = (int) jr[0]; 01308 topleft.y = (int) jr[1]; 01309 bottomright.x = topleft.x + (int)jr[2]; 01310 bottomright.y = topleft.y + (int)jr[3]; 01311 ScreenToClient(hwndParent, &topleft); 01312 ScreenToClient(hwndParent, &bottomright); 01313 MoveWindow((HWND)ctx->auxdata, 01314 topleft.x, topleft.y, 01315 bottomright.x - topleft.x, 01316 bottomright.y - topleft.y, 01317 TRUE); // rbs -- TRUE causes repaint and gets rid of window trash 01318 } 01319 else { 01320 error("update context: not in max5"); 01321 } 01322 break; 01323 } 01324 } 01325 01326 return TRUE; // no win equivalent? 01327 #endif 01328 } 01329 01330 //MORE WORK for pwindows/matrices 01331 GLboolean jit_gl_set_target(t_jit_gl_context ctx, void *target, long targettype) 01332 { 01333 ctx->target = target; 01334 ctx->targettype = targettype; 01335 #ifdef MAC_VERSION 01336 01337 switch (targettype) 01338 { 01339 01340 case JIT_GL_TARGET_MATRIX: 01341 /* if (!check_dest_matrix(target, &minfo, &baseaddr)) 01342 return NULL; 01343 pixelsize = 32; 01344 rowbytes = info.dimstride[1]; 01345 aglSetOffScreen(ctx, width, height, rowbytes, baseaddr); 01346 */ 01347 return FALSE; 01348 01349 case JIT_GL_TARGET_PWINDOW: 01350 01351 if (ctx && ctx->context) 01352 { 01353 void *maxobj = NULL; 01354 method meth = NULL; 01355 AGLDrawable w = 0; 01356 01357 if (target) { 01358 jit_object_method(target, gensym("get_max_obj"), &maxobj); 01359 } 01360 01361 if (maxobj && (meth=zgetfn(maxobj,gensym("nativeparentwind")))) { 01362 if ((w = (AGLDrawable) meth(maxobj))) 01363 return aglSetDrawable(ctx->context, w); 01364 else 01365 return aglSetDrawable(ctx->context, NULL); 01366 } 01367 else { 01368 return aglSetDrawable(ctx->context, NULL); 01369 } 01370 } 01371 01372 return FALSE; 01373 01374 case JIT_GL_TARGET_WINDOW: 01375 01376 default: 01377 01378 if (ctx && ctx->context) 01379 { 01380 // if (target) 01381 // return aglSetDrawable(ctx->context, GetWindowPort((CWindowPtr)wind_syswind((t_wind *)target))); 01382 // else 01383 return aglSetDrawable(ctx->context, NULL); 01384 } 01385 01386 return FALSE; 01387 } 01388 01389 #endif 01390 #ifdef WIN_VERSION 01391 //we might need to kill/recreate? 01392 return TRUE; //place holder 01393 01394 #endif 01395 } 01396 01397 GLboolean jit_gl_set_context(t_jit_gl_context ctx) 01398 { 01399 g_jit_gl_context = ctx; 01400 01401 #ifdef MAC_VERSION 01402 if (ctx && ctx->context && aglGetCurrentContext() != ctx->context ) 01403 { 01404 return aglSetCurrentContext(ctx->context); 01405 } 01406 else 01407 return TRUE; 01408 #endif 01409 #ifdef WIN_VERSION 01410 if (ctx) 01411 { 01412 SelectClipRgn((HDC)ctx->drawable, NULL); 01413 01414 if (wglGetCurrentContext() != ctx->context) 01415 return wglMakeCurrent((HDC)ctx->drawable, ctx->context); 01416 else 01417 return TRUE; 01418 } 01419 else 01420 return wglMakeCurrent(NULL, NULL); 01421 01422 #endif 01423 } 01424 01425 t_jit_gl_context jit_gl_get_context(void) 01426 { 01427 if (g_jit_gl_context&&g_jit_gl_context->context) 01428 { 01429 #ifdef MAC_VERSION 01430 if (aglGetCurrentContext() == g_jit_gl_context->context) 01431 #endif 01432 #ifdef WIN_VERSION 01433 if (wglGetCurrentContext() == g_jit_gl_context->context) 01434 #endif 01435 return g_jit_gl_context; 01436 } 01437 01438 return NULL; 01439 } 01440 01441 t_jit_gl_support *jit_gl_get_support(void) 01442 { 01443 if (g_jit_gl_context) 01444 return g_jit_gl_context->support; 01445 01446 return NULL; 01447 } 01448 01449 long jit_gl_support_valid(t_jit_gl_support **support) 01450 { 01451 if (!support) 01452 return FALSE; 01453 01454 if (g_jit_gl_context) 01455 (*support) = g_jit_gl_context->support; 01456 01457 if (!(*support)) 01458 return FALSE; 01459 01460 if (!(*support)->initialized) 01461 return FALSE; 01462 01463 return TRUE; 01464 } 01465 01466 01467 // MORE WORK/RESEARCH 01468 // used for things like AGL_SWAP_INTERVAL, and AGL_CLIP_REGION 01469 GLboolean jit_gl_set_context_state(t_jit_gl_context ctx, long which, GLint *vals) 01470 { 01471 #ifdef MAC_VERSION 01472 return aglSetInteger(ctx->context, which, vals); 01473 #endif 01474 #ifdef WIN_VERSION 01475 01476 return TRUE; //placeholder 01477 #endif 01478 } 01479 01480 static long jit_gl_context_check_matrix(void *m, t_jit_matrix_info *p_info, void **p_baseaddr) 01481 { 01482 // check parameters of jit_matrix to see if we can draw to it. 01483 // return matrix info and data ptr in p_info and p_baseaddr. 01484 // we are very restrictive about offscreen destinations for now. 01485 jit_object_method(m, _jit_sym_getinfo, p_info); 01486 jit_object_method(m, _jit_sym_getdata, p_baseaddr); 01487 01488 if (p_info->dimcount != 2) 01489 { 01490 error("jit_gl_context_check_matrix: destination must be a 2D matrix."); 01491 return FALSE; 01492 } 01493 01494 if (p_info->planecount != 4) 01495 { 01496 error("jit_gl_context_check_matrix: planecount of destination matrix must be 4."); 01497 return FALSE; 01498 } 01499 01500 if (p_info->type != _jit_sym_char) 01501 { 01502 error("jit_gl_context_check_matrix: type of destination matrix must be char."); 01503 return FALSE; 01504 } 01505 01506 if (*p_baseaddr == 0) 01507 { 01508 error("jit_gl_context_check_matrix: null data ptr for destination matrix!"); 01509 return FALSE; 01510 } 01511 01512 return TRUE; 01513 } 01514 01515 /****************************************************************************/ 01516 01517 // MORE WORK/RESEARCH!!! 01518 #ifdef MAC_VERSION 01519 GDHandle jit_gl_context_getdevice(t_jit_gl_context ctx); 01520 GDHandle jit_gl_context_getdevice(t_jit_gl_context ctx) 01521 { 01522 double rect[4]; 01523 Point tl, lr; 01524 void *maxobj = NULL; 01525 01526 if (ctx && ctx->context && ctx->target) 01527 { 01528 switch (ctx->targettype) { 01529 case JIT_GL_TARGET_MATRIX: 01530 return NULL; 01531 case JIT_GL_TARGET_PWINDOW: 01532 jit_object_method(ctx->target, gensym("get_max_obj"), &maxobj); 01533 if (!maxobj) 01534 return NULL; 01535 01536 object_method(maxobj, gensym("patch_rect"), rect); 01537 01538 tl.h = rect[0]; 01539 tl.v = rect[1]; 01540 lr.h = rect[0]+rect[2]; 01541 lr.v = rect[1]+rect[3]; 01542 01543 LocalToGlobal((Point *)&tl); 01544 LocalToGlobal((Point *)&lr); 01545 return GetDeviceAtRect(tl.v, tl.h, lr.v, lr.h); 01546 case JIT_GL_TARGET_WINDOW: 01547 //w = (t_wind *)ctx->target; 01548 //return GetDeviceAtRect(w->w_y1, w->w_x1, w->w_y2, w->w_x2); 01549 return NULL; 01550 } 01551 } 01552 return NULL; 01553 } 01554 01555 static GDHandle GetDeviceAtPoint(Point loc) 01556 { 01557 GDHandle hDev; 01558 Rect rdev; 01559 int i = 0; 01560 01561 //post("checking for device at point: %d %d",loc.h,loc.v); 01562 01563 for (hDev = GetDeviceList(); 01564 hDev; 01565 hDev = GetNextDevice(hDev)) 01566 { 01567 rdev = (*hDev)->gdRect; 01568 //post("(device[%d]: %d %d %d %d",i++, rdev.top,rdev.left,rdev.bottom,rdev.right); 01569 01570 if (MacPtInRect(loc, &rdev)) 01571 return hDev; 01572 } 01573 01574 return 0; 01575 } 01576 01577 static GDHandle GetDeviceAtRect(long top, long left, long bottom, long right) 01578 { 01579 Point collidePt; 01580 GDHandle hdev; 01581 01582 // post("checking for device in rect: %d %d %d %d",top,left,bottom,right); 01583 01584 collidePt.v = (top + bottom) / 2, 01585 collidePt.h = (left + right) / 2; 01586 01587 hdev = GetDeviceAtPoint(collidePt); 01588 01589 if (hdev) 01590 return hdev; 01591 01592 collidePt.v = bottom; 01593 collidePt.h = left; 01594 01595 hdev = GetDeviceAtPoint(collidePt); 01596 01597 if (hdev) 01598 return hdev; 01599 01600 collidePt.v = top; 01601 collidePt.h = left; 01602 01603 hdev = GetDeviceAtPoint(collidePt); 01604 01605 if (hdev) 01606 return hdev; 01607 01608 collidePt.v = bottom; 01609 collidePt.h = right; 01610 01611 hdev = GetDeviceAtPoint(collidePt); 01612 01613 if (hdev) 01614 return hdev; 01615 01616 collidePt.v = top; 01617 collidePt.h = right; 01618 01619 hdev = GetDeviceAtPoint(collidePt); 01620 01621 if (hdev) 01622 return hdev; 01623 01624 return 0; 01625 } 01626 01627 long check_dest_matrix(void *m, t_jit_matrix_info *p_info, void **p_baseaddr) 01628 { 01629 // check parameters of jit_matrix to see if we can draw to it. 01630 // return matrix info and data ptr in p_info and p_baseaddr. 01631 // we are very restrictive about offscreen destinations for now. 01632 jit_object_method(m, _jit_sym_getinfo, p_info); 01633 jit_object_method(m, _jit_sym_getdata, p_baseaddr); 01634 01635 if (p_info->dimcount != 2) 01636 { 01637 error("jit.gl.render: destination must be a 2D matrix."); 01638 return false; 01639 } 01640 01641 // when we move this fn into a jit lib, make a variable arg for min (max?) sizes. 01642 /* if (p_info->dim[0] < 9 || p_info->dim[1] < 9) 01643 { 01644 error("jit.gl.render: width and height of destination must be > 8."); 01645 return false; 01646 } 01647 */ 01648 01649 if (p_info->planecount != 4) 01650 { 01651 error("jit.gl.render: planecount of destination matrix must be 4."); 01652 return false; 01653 } 01654 01655 if (p_info->type != _jit_sym_char) 01656 { 01657 error("jit.gl.render: type of destination matrix must be char."); 01658 return false; 01659 } 01660 01661 if (*p_baseaddr == 0) 01662 { 01663 error("jit.gl.render: null data ptr for destination matrix!"); 01664 return false; 01665 } 01666 01667 return true; 01668 } 01669 01670 #endif // MAC_VERSION 01671 01672 01673 /****************************************************************************/
Copyright © 2008, Cycling '74