1 /************************************************************************** 2 * 3 * Copyright 2008 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 #include <windows.h> 29 30 #define WGL_WGLEXT_PROTOTYPES 31 32 #include <GL/gl.h> 33 #include <GL/wglext.h> 34 35 #include "pipe/p_compiler.h" 36 #include "pipe/p_context.h" 37 #include "pipe/p_state.h" 38 #include "util/u_memory.h" 39 #include "util/u_atomic.h" 40 #include "state_tracker/st_api.h" 41 #include "hud/hud_context.h" 42 43 #include "stw_icd.h" 44 #include "stw_device.h" 45 #include "stw_winsys.h" 46 #include "stw_framebuffer.h" 47 #include "stw_pixelformat.h" 48 #include "stw_context.h" 49 #include "stw_tls.h" 50 51 52 struct stw_context * 53 stw_current_context(void) 54 { 55 struct st_context_iface *st; 56 57 st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL; 58 59 return (struct stw_context *) ((st) ? st->st_manager_private : NULL); 60 } 61 62 63 BOOL APIENTRY 64 DrvCopyContext(DHGLRC dhrcSource, DHGLRC dhrcDest, UINT fuMask) 65 { 66 struct stw_context *src; 67 struct stw_context *dst; 68 BOOL ret = FALSE; 69 70 if (!stw_dev) 71 return FALSE; 72 73 stw_lock_contexts(stw_dev); 74 75 src = stw_lookup_context_locked( dhrcSource ); 76 dst = stw_lookup_context_locked( dhrcDest ); 77 78 if (src && dst) { 79 /* FIXME */ 80 assert(0); 81 (void) src; 82 (void) dst; 83 (void) fuMask; 84 } 85 86 stw_unlock_contexts(stw_dev); 87 88 return ret; 89 } 90 91 92 BOOL APIENTRY 93 DrvShareLists(DHGLRC dhglrc1, DHGLRC dhglrc2) 94 { 95 struct stw_context *ctx1; 96 struct stw_context *ctx2; 97 BOOL ret = FALSE; 98 99 if (!stw_dev) 100 return FALSE; 101 102 stw_lock_contexts(stw_dev); 103 104 ctx1 = stw_lookup_context_locked( dhglrc1 ); 105 ctx2 = stw_lookup_context_locked( dhglrc2 ); 106 107 if (ctx1 && ctx2 && ctx2->st->share) 108 ret = ctx2->st->share(ctx2->st, ctx1->st); 109 110 stw_unlock_contexts(stw_dev); 111 112 return ret; 113 } 114 115 116 DHGLRC APIENTRY 117 DrvCreateContext(HDC hdc) 118 { 119 return DrvCreateLayerContext( hdc, 0 ); 120 } 121 122 123 DHGLRC APIENTRY 124 DrvCreateLayerContext(HDC hdc, INT iLayerPlane) 125 { 126 return stw_create_context_attribs(hdc, iLayerPlane, 0, 1, 0, 0, 127 WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 128 0); 129 } 130 131 132 /** 133 * Called via DrvCreateContext(), DrvCreateLayerContext() and 134 * wglCreateContextAttribsARB() to actually create a rendering context. 135 * \param handle the desired DHGLRC handle to use for the context, or zero 136 * if a new handle should be allocated. 137 * \return the handle for the new context or zero if there was a problem. 138 */ 139 DHGLRC 140 stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext, 141 int majorVersion, int minorVersion, 142 int contextFlags, int profileMask, 143 DHGLRC handle) 144 { 145 int iPixelFormat; 146 struct stw_framebuffer *fb; 147 const struct stw_pixelformat_info *pfi; 148 struct st_context_attribs attribs; 149 struct stw_context *ctx = NULL; 150 struct stw_context *shareCtx = NULL; 151 enum st_context_error ctx_err = 0; 152 153 if (!stw_dev) 154 return 0; 155 156 if (iLayerPlane != 0) 157 return 0; 158 159 /* 160 * GDI only knows about displayable pixel formats, so determine the pixel 161 * format from the framebuffer. 162 * 163 * This also allows to use a OpenGL DLL / ICD without installing. 164 */ 165 fb = stw_framebuffer_from_hdc( hdc ); 166 if (fb) { 167 iPixelFormat = fb->iPixelFormat; 168 stw_framebuffer_unlock(fb); 169 } else { 170 return 0; 171 } 172 173 pfi = stw_pixelformat_get_info( iPixelFormat ); 174 175 if (hShareContext != 0) { 176 stw_lock_contexts(stw_dev); 177 shareCtx = stw_lookup_context_locked( hShareContext ); 178 stw_unlock_contexts(stw_dev); 179 } 180 181 ctx = CALLOC_STRUCT( stw_context ); 182 if (ctx == NULL) 183 goto no_ctx; 184 185 ctx->hdc = hdc; 186 ctx->iPixelFormat = iPixelFormat; 187 188 memset(&attribs, 0, sizeof(attribs)); 189 attribs.visual = pfi->stvis; 190 attribs.major = majorVersion; 191 attribs.minor = minorVersion; 192 if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) 193 attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE; 194 if (contextFlags & WGL_CONTEXT_DEBUG_BIT_ARB) 195 attribs.flags |= ST_CONTEXT_FLAG_DEBUG; 196 197 switch (profileMask) { 198 case WGL_CONTEXT_CORE_PROFILE_BIT_ARB: 199 /* There are no profiles before OpenGL 3.2. The 200 * WGL_ARB_create_context_profile spec says: 201 * 202 * "If the requested OpenGL version is less than 3.2, 203 * WGL_CONTEXT_PROFILE_MASK_ARB is ignored and the functionality 204 * of the context is determined solely by the requested version." 205 */ 206 if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2)) { 207 attribs.profile = ST_PROFILE_OPENGL_CORE; 208 break; 209 } 210 /* fall-through */ 211 case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB: 212 /* 213 * The spec also says: 214 * 215 * "If version 3.1 is requested, the context returned may implement 216 * any of the following versions: 217 * 218 * * Version 3.1. The GL_ARB_compatibility extension may or may not 219 * be implemented, as determined by the implementation. 220 * * The core profile of version 3.2 or greater." 221 * 222 * But Mesa doesn't support GL_ARB_compatibility, while most prevalent 223 * Windows OpenGL implementations do, and unfortunately many Windows 224 * applications don't check whether they receive or not a context with 225 * GL_ARB_compatibility, so returning a core profile here does more harm 226 * than good. 227 */ 228 attribs.profile = ST_PROFILE_DEFAULT; 229 break; 230 case WGL_CONTEXT_ES_PROFILE_BIT_EXT: 231 if (majorVersion >= 2) { 232 attribs.profile = ST_PROFILE_OPENGL_ES2; 233 } else { 234 attribs.profile = ST_PROFILE_OPENGL_ES1; 235 } 236 break; 237 default: 238 assert(0); 239 goto no_st_ctx; 240 } 241 242 ctx->st = stw_dev->stapi->create_context(stw_dev->stapi, 243 stw_dev->smapi, &attribs, &ctx_err, shareCtx ? shareCtx->st : NULL); 244 if (ctx->st == NULL) 245 goto no_st_ctx; 246 247 ctx->st->st_manager_private = (void *) ctx; 248 249 if (ctx->st->cso_context) { 250 ctx->hud = hud_create(ctx->st->pipe, ctx->st->cso_context); 251 } 252 253 stw_lock_contexts(stw_dev); 254 if (handle) { 255 /* We're replacing the context data for this handle. See the 256 * wglCreateContextAttribsARB() function. 257 */ 258 struct stw_context *old_ctx = 259 stw_lookup_context_locked((unsigned) handle); 260 if (old_ctx) { 261 /* free the old context data associated with this handle */ 262 if (old_ctx->hud) { 263 hud_destroy(old_ctx->hud); 264 } 265 ctx->st->destroy(old_ctx->st); 266 FREE(old_ctx); 267 } 268 269 /* replace table entry */ 270 handle_table_set(stw_dev->ctx_table, (unsigned) handle, ctx); 271 } 272 else { 273 /* create new table entry */ 274 handle = (DHGLRC) handle_table_add(stw_dev->ctx_table, ctx); 275 } 276 277 ctx->dhglrc = handle; 278 279 stw_unlock_contexts(stw_dev); 280 281 if (!ctx->dhglrc) 282 goto no_hglrc; 283 284 return ctx->dhglrc; 285 286 no_hglrc: 287 if (ctx->hud) { 288 hud_destroy(ctx->hud); 289 } 290 ctx->st->destroy(ctx->st); 291 no_st_ctx: 292 FREE(ctx); 293 no_ctx: 294 return 0; 295 } 296 297 298 BOOL APIENTRY 299 DrvDeleteContext(DHGLRC dhglrc) 300 { 301 struct stw_context *ctx ; 302 BOOL ret = FALSE; 303 304 if (!stw_dev) 305 return FALSE; 306 307 stw_lock_contexts(stw_dev); 308 ctx = stw_lookup_context_locked(dhglrc); 309 handle_table_remove(stw_dev->ctx_table, dhglrc); 310 stw_unlock_contexts(stw_dev); 311 312 if (ctx) { 313 struct stw_context *curctx = stw_current_context(); 314 315 /* Unbind current if deleting current context. */ 316 if (curctx == ctx) 317 stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); 318 319 if (ctx->hud) { 320 hud_destroy(ctx->hud); 321 } 322 323 ctx->st->destroy(ctx->st); 324 FREE(ctx); 325 326 ret = TRUE; 327 } 328 329 return ret; 330 } 331 332 333 BOOL APIENTRY 334 DrvReleaseContext(DHGLRC dhglrc) 335 { 336 struct stw_context *ctx; 337 338 if (!stw_dev) 339 return FALSE; 340 341 stw_lock_contexts(stw_dev); 342 ctx = stw_lookup_context_locked( dhglrc ); 343 stw_unlock_contexts(stw_dev); 344 345 if (!ctx) 346 return FALSE; 347 348 /* The expectation is that ctx is the same context which is 349 * current for this thread. We should check that and return False 350 * if not the case. 351 */ 352 if (ctx != stw_current_context()) 353 return FALSE; 354 355 if (stw_make_current( NULL, 0 ) == FALSE) 356 return FALSE; 357 358 return TRUE; 359 } 360 361 362 DHGLRC 363 stw_get_current_context( void ) 364 { 365 struct stw_context *ctx; 366 367 ctx = stw_current_context(); 368 if (!ctx) 369 return 0; 370 371 return ctx->dhglrc; 372 } 373 374 375 HDC 376 stw_get_current_dc( void ) 377 { 378 struct stw_context *ctx; 379 380 ctx = stw_current_context(); 381 if (!ctx) 382 return NULL; 383 384 return ctx->hdc; 385 } 386 387 388 BOOL 389 stw_make_current(HDC hdc, DHGLRC dhglrc) 390 { 391 struct stw_context *old_ctx = NULL; 392 struct stw_context *ctx = NULL; 393 BOOL ret = FALSE; 394 395 if (!stw_dev) 396 return FALSE; 397 398 old_ctx = stw_current_context(); 399 if (old_ctx != NULL) { 400 if (old_ctx->dhglrc == dhglrc) { 401 if (old_ctx->hdc == hdc) { 402 /* Return if already current. */ 403 return TRUE; 404 } 405 } else { 406 old_ctx->st->flush(old_ctx->st, ST_FLUSH_FRONT, NULL); 407 } 408 } 409 410 if (dhglrc) { 411 struct stw_framebuffer *fb = NULL; 412 stw_lock_contexts(stw_dev); 413 ctx = stw_lookup_context_locked( dhglrc ); 414 stw_unlock_contexts(stw_dev); 415 if (!ctx) { 416 goto fail; 417 } 418 419 /* This call locks fb's mutex */ 420 fb = stw_framebuffer_from_hdc( hdc ); 421 if (fb) { 422 stw_framebuffer_update(fb); 423 } 424 else { 425 /* Applications should call SetPixelFormat before creating a context, 426 * but not all do, and the opengl32 runtime seems to use a default 427 * pixel format in some cases, so we must create a framebuffer for 428 * those here. 429 */ 430 int iPixelFormat = GetPixelFormat(hdc); 431 if (iPixelFormat) 432 fb = stw_framebuffer_create( hdc, iPixelFormat ); 433 if (!fb) 434 goto fail; 435 } 436 437 if (fb->iPixelFormat != ctx->iPixelFormat) { 438 stw_framebuffer_unlock(fb); 439 SetLastError(ERROR_INVALID_PIXEL_FORMAT); 440 goto fail; 441 } 442 443 /* Bind the new framebuffer */ 444 ctx->hdc = hdc; 445 446 struct stw_framebuffer *old_fb = ctx->current_framebuffer; 447 if (old_fb != fb) { 448 stw_framebuffer_reference_locked(fb); 449 ctx->current_framebuffer = fb; 450 } 451 stw_framebuffer_unlock(fb); 452 453 /* Note: when we call this function we will wind up in the 454 * stw_st_framebuffer_validate_locked() function which will incur 455 * a recursive fb->mutex lock. 456 */ 457 ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, 458 fb->stfb, fb->stfb); 459 460 if (old_fb && old_fb != fb) { 461 stw_lock_framebuffers(stw_dev); 462 stw_framebuffer_lock(old_fb); 463 stw_framebuffer_release_locked(old_fb); 464 stw_unlock_framebuffers(stw_dev); 465 } 466 467 fail: 468 /* fb must be unlocked at this point. */ 469 assert(!stw_own_mutex(&fb->mutex)); 470 471 /* On failure, make the thread's current rendering context not current 472 * before returning. 473 */ 474 if (!ret) { 475 stw_make_current(NULL, 0); 476 } 477 } else { 478 ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); 479 } 480 481 /* Unreference the previous framebuffer if any. It must be done after 482 * make_current, as it can be referenced inside. 483 */ 484 if (old_ctx && old_ctx != ctx) { 485 struct stw_framebuffer *old_fb = old_ctx->current_framebuffer; 486 if (old_fb) { 487 old_ctx->current_framebuffer = NULL; 488 stw_lock_framebuffers(stw_dev); 489 stw_framebuffer_lock(old_fb); 490 stw_framebuffer_release_locked(old_fb); 491 stw_unlock_framebuffers(stw_dev); 492 } 493 } 494 495 return ret; 496 } 497 498 499 /** 500 * Notify the current context that the framebuffer has become invalid. 501 */ 502 void 503 stw_notify_current_locked( struct stw_framebuffer *fb ) 504 { 505 p_atomic_inc(&fb->stfb->stamp); 506 } 507 508 509 /** 510 * Although WGL allows different dispatch entrypoints per context 511 */ 512 static const GLCLTPROCTABLE cpt = 513 { 514 OPENGL_VERSION_110_ENTRIES, 515 { 516 &glNewList, 517 &glEndList, 518 &glCallList, 519 &glCallLists, 520 &glDeleteLists, 521 &glGenLists, 522 &glListBase, 523 &glBegin, 524 &glBitmap, 525 &glColor3b, 526 &glColor3bv, 527 &glColor3d, 528 &glColor3dv, 529 &glColor3f, 530 &glColor3fv, 531 &glColor3i, 532 &glColor3iv, 533 &glColor3s, 534 &glColor3sv, 535 &glColor3ub, 536 &glColor3ubv, 537 &glColor3ui, 538 &glColor3uiv, 539 &glColor3us, 540 &glColor3usv, 541 &glColor4b, 542 &glColor4bv, 543 &glColor4d, 544 &glColor4dv, 545 &glColor4f, 546 &glColor4fv, 547 &glColor4i, 548 &glColor4iv, 549 &glColor4s, 550 &glColor4sv, 551 &glColor4ub, 552 &glColor4ubv, 553 &glColor4ui, 554 &glColor4uiv, 555 &glColor4us, 556 &glColor4usv, 557 &glEdgeFlag, 558 &glEdgeFlagv, 559 &glEnd, 560 &glIndexd, 561 &glIndexdv, 562 &glIndexf, 563 &glIndexfv, 564 &glIndexi, 565 &glIndexiv, 566 &glIndexs, 567 &glIndexsv, 568 &glNormal3b, 569 &glNormal3bv, 570 &glNormal3d, 571 &glNormal3dv, 572 &glNormal3f, 573 &glNormal3fv, 574 &glNormal3i, 575 &glNormal3iv, 576 &glNormal3s, 577 &glNormal3sv, 578 &glRasterPos2d, 579 &glRasterPos2dv, 580 &glRasterPos2f, 581 &glRasterPos2fv, 582 &glRasterPos2i, 583 &glRasterPos2iv, 584 &glRasterPos2s, 585 &glRasterPos2sv, 586 &glRasterPos3d, 587 &glRasterPos3dv, 588 &glRasterPos3f, 589 &glRasterPos3fv, 590 &glRasterPos3i, 591 &glRasterPos3iv, 592 &glRasterPos3s, 593 &glRasterPos3sv, 594 &glRasterPos4d, 595 &glRasterPos4dv, 596 &glRasterPos4f, 597 &glRasterPos4fv, 598 &glRasterPos4i, 599 &glRasterPos4iv, 600 &glRasterPos4s, 601 &glRasterPos4sv, 602 &glRectd, 603 &glRectdv, 604 &glRectf, 605 &glRectfv, 606 &glRecti, 607 &glRectiv, 608 &glRects, 609 &glRectsv, 610 &glTexCoord1d, 611 &glTexCoord1dv, 612 &glTexCoord1f, 613 &glTexCoord1fv, 614 &glTexCoord1i, 615 &glTexCoord1iv, 616 &glTexCoord1s, 617 &glTexCoord1sv, 618 &glTexCoord2d, 619 &glTexCoord2dv, 620 &glTexCoord2f, 621 &glTexCoord2fv, 622 &glTexCoord2i, 623 &glTexCoord2iv, 624 &glTexCoord2s, 625 &glTexCoord2sv, 626 &glTexCoord3d, 627 &glTexCoord3dv, 628 &glTexCoord3f, 629 &glTexCoord3fv, 630 &glTexCoord3i, 631 &glTexCoord3iv, 632 &glTexCoord3s, 633 &glTexCoord3sv, 634 &glTexCoord4d, 635 &glTexCoord4dv, 636 &glTexCoord4f, 637 &glTexCoord4fv, 638 &glTexCoord4i, 639 &glTexCoord4iv, 640 &glTexCoord4s, 641 &glTexCoord4sv, 642 &glVertex2d, 643 &glVertex2dv, 644 &glVertex2f, 645 &glVertex2fv, 646 &glVertex2i, 647 &glVertex2iv, 648 &glVertex2s, 649 &glVertex2sv, 650 &glVertex3d, 651 &glVertex3dv, 652 &glVertex3f, 653 &glVertex3fv, 654 &glVertex3i, 655 &glVertex3iv, 656 &glVertex3s, 657 &glVertex3sv, 658 &glVertex4d, 659 &glVertex4dv, 660 &glVertex4f, 661 &glVertex4fv, 662 &glVertex4i, 663 &glVertex4iv, 664 &glVertex4s, 665 &glVertex4sv, 666 &glClipPlane, 667 &glColorMaterial, 668 &glCullFace, 669 &glFogf, 670 &glFogfv, 671 &glFogi, 672 &glFogiv, 673 &glFrontFace, 674 &glHint, 675 &glLightf, 676 &glLightfv, 677 &glLighti, 678 &glLightiv, 679 &glLightModelf, 680 &glLightModelfv, 681 &glLightModeli, 682 &glLightModeliv, 683 &glLineStipple, 684 &glLineWidth, 685 &glMaterialf, 686 &glMaterialfv, 687 &glMateriali, 688 &glMaterialiv, 689 &glPointSize, 690 &glPolygonMode, 691 &glPolygonStipple, 692 &glScissor, 693 &glShadeModel, 694 &glTexParameterf, 695 &glTexParameterfv, 696 &glTexParameteri, 697 &glTexParameteriv, 698 &glTexImage1D, 699 &glTexImage2D, 700 &glTexEnvf, 701 &glTexEnvfv, 702 &glTexEnvi, 703 &glTexEnviv, 704 &glTexGend, 705 &glTexGendv, 706 &glTexGenf, 707 &glTexGenfv, 708 &glTexGeni, 709 &glTexGeniv, 710 &glFeedbackBuffer, 711 &glSelectBuffer, 712 &glRenderMode, 713 &glInitNames, 714 &glLoadName, 715 &glPassThrough, 716 &glPopName, 717 &glPushName, 718 &glDrawBuffer, 719 &glClear, 720 &glClearAccum, 721 &glClearIndex, 722 &glClearColor, 723 &glClearStencil, 724 &glClearDepth, 725 &glStencilMask, 726 &glColorMask, 727 &glDepthMask, 728 &glIndexMask, 729 &glAccum, 730 &glDisable, 731 &glEnable, 732 &glFinish, 733 &glFlush, 734 &glPopAttrib, 735 &glPushAttrib, 736 &glMap1d, 737 &glMap1f, 738 &glMap2d, 739 &glMap2f, 740 &glMapGrid1d, 741 &glMapGrid1f, 742 &glMapGrid2d, 743 &glMapGrid2f, 744 &glEvalCoord1d, 745 &glEvalCoord1dv, 746 &glEvalCoord1f, 747 &glEvalCoord1fv, 748 &glEvalCoord2d, 749 &glEvalCoord2dv, 750 &glEvalCoord2f, 751 &glEvalCoord2fv, 752 &glEvalMesh1, 753 &glEvalPoint1, 754 &glEvalMesh2, 755 &glEvalPoint2, 756 &glAlphaFunc, 757 &glBlendFunc, 758 &glLogicOp, 759 &glStencilFunc, 760 &glStencilOp, 761 &glDepthFunc, 762 &glPixelZoom, 763 &glPixelTransferf, 764 &glPixelTransferi, 765 &glPixelStoref, 766 &glPixelStorei, 767 &glPixelMapfv, 768 &glPixelMapuiv, 769 &glPixelMapusv, 770 &glReadBuffer, 771 &glCopyPixels, 772 &glReadPixels, 773 &glDrawPixels, 774 &glGetBooleanv, 775 &glGetClipPlane, 776 &glGetDoublev, 777 &glGetError, 778 &glGetFloatv, 779 &glGetIntegerv, 780 &glGetLightfv, 781 &glGetLightiv, 782 &glGetMapdv, 783 &glGetMapfv, 784 &glGetMapiv, 785 &glGetMaterialfv, 786 &glGetMaterialiv, 787 &glGetPixelMapfv, 788 &glGetPixelMapuiv, 789 &glGetPixelMapusv, 790 &glGetPolygonStipple, 791 &glGetString, 792 &glGetTexEnvfv, 793 &glGetTexEnviv, 794 &glGetTexGendv, 795 &glGetTexGenfv, 796 &glGetTexGeniv, 797 &glGetTexImage, 798 &glGetTexParameterfv, 799 &glGetTexParameteriv, 800 &glGetTexLevelParameterfv, 801 &glGetTexLevelParameteriv, 802 &glIsEnabled, 803 &glIsList, 804 &glDepthRange, 805 &glFrustum, 806 &glLoadIdentity, 807 &glLoadMatrixf, 808 &glLoadMatrixd, 809 &glMatrixMode, 810 &glMultMatrixf, 811 &glMultMatrixd, 812 &glOrtho, 813 &glPopMatrix, 814 &glPushMatrix, 815 &glRotated, 816 &glRotatef, 817 &glScaled, 818 &glScalef, 819 &glTranslated, 820 &glTranslatef, 821 &glViewport, 822 &glArrayElement, 823 &glBindTexture, 824 &glColorPointer, 825 &glDisableClientState, 826 &glDrawArrays, 827 &glDrawElements, 828 &glEdgeFlagPointer, 829 &glEnableClientState, 830 &glIndexPointer, 831 &glIndexub, 832 &glIndexubv, 833 &glInterleavedArrays, 834 &glNormalPointer, 835 &glPolygonOffset, 836 &glTexCoordPointer, 837 &glVertexPointer, 838 &glAreTexturesResident, 839 &glCopyTexImage1D, 840 &glCopyTexImage2D, 841 &glCopyTexSubImage1D, 842 &glCopyTexSubImage2D, 843 &glDeleteTextures, 844 &glGenTextures, 845 &glGetPointerv, 846 &glIsTexture, 847 &glPrioritizeTextures, 848 &glTexSubImage1D, 849 &glTexSubImage2D, 850 &glPopClientAttrib, 851 &glPushClientAttrib 852 } 853 }; 854 855 856 PGLCLTPROCTABLE APIENTRY 857 DrvSetContext(HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable) 858 { 859 PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt; 860 861 if (!stw_make_current(hdc, dhglrc)) 862 r = NULL; 863 864 return r; 865 } 866