1 #include "precompiled.h" 2 // 3 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style license that can be 5 // found in the LICENSE file. 6 // 7 8 // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions. 9 10 #include "common/version.h" 11 12 #include "libGLESv2/main.h" 13 #include "libGLESv2/utilities.h" 14 #include "libGLESv2/Buffer.h" 15 #include "libGLESv2/Fence.h" 16 #include "libGLESv2/Framebuffer.h" 17 #include "libGLESv2/Renderbuffer.h" 18 #include "libGLESv2/Program.h" 19 #include "libGLESv2/ProgramBinary.h" 20 #include "libGLESv2/Texture.h" 21 #include "libGLESv2/Query.h" 22 #include "libGLESv2/Context.h" 23 24 bool validImageSize(GLint level, GLsizei width, GLsizei height) 25 { 26 if (level < 0 || width < 0 || height < 0) 27 { 28 return false; 29 } 30 31 if (gl::getContext() && gl::getContext()->supportsNonPower2Texture()) 32 { 33 return true; 34 } 35 36 if (level == 0) 37 { 38 return true; 39 } 40 41 if (gl::isPow2(width) && gl::isPow2(height)) 42 { 43 return true; 44 } 45 46 return false; 47 } 48 49 // Verify that format/type are one of the combinations from table 3.4. 50 bool checkTextureFormatType(GLenum format, GLenum type) 51 { 52 // validate <format> by itself (used as secondary key below) 53 switch (format) 54 { 55 case GL_RGBA: 56 case GL_BGRA_EXT: 57 case GL_RGB: 58 case GL_ALPHA: 59 case GL_LUMINANCE: 60 case GL_LUMINANCE_ALPHA: 61 case GL_DEPTH_COMPONENT: 62 case GL_DEPTH_STENCIL_OES: 63 break; 64 default: 65 return gl::error(GL_INVALID_ENUM, false); 66 } 67 68 // invalid <type> -> sets INVALID_ENUM 69 // invalid <format>+<type> combination -> sets INVALID_OPERATION 70 switch (type) 71 { 72 case GL_UNSIGNED_BYTE: 73 switch (format) 74 { 75 case GL_RGBA: 76 case GL_BGRA_EXT: 77 case GL_RGB: 78 case GL_ALPHA: 79 case GL_LUMINANCE: 80 case GL_LUMINANCE_ALPHA: 81 return true; 82 default: 83 return gl::error(GL_INVALID_OPERATION, false); 84 } 85 86 case GL_FLOAT: 87 case GL_HALF_FLOAT_OES: 88 switch (format) 89 { 90 case GL_RGBA: 91 case GL_RGB: 92 case GL_ALPHA: 93 case GL_LUMINANCE: 94 case GL_LUMINANCE_ALPHA: 95 return true; 96 default: 97 return gl::error(GL_INVALID_OPERATION, false); 98 } 99 100 case GL_UNSIGNED_SHORT_4_4_4_4: 101 case GL_UNSIGNED_SHORT_5_5_5_1: 102 switch (format) 103 { 104 case GL_RGBA: 105 return true; 106 default: 107 return gl::error(GL_INVALID_OPERATION, false); 108 } 109 110 case GL_UNSIGNED_SHORT_5_6_5: 111 switch (format) 112 { 113 case GL_RGB: 114 return true; 115 default: 116 return gl::error(GL_INVALID_OPERATION, false); 117 } 118 119 case GL_UNSIGNED_SHORT: 120 case GL_UNSIGNED_INT: 121 switch (format) 122 { 123 case GL_DEPTH_COMPONENT: 124 return true; 125 default: 126 return gl::error(GL_INVALID_OPERATION, false); 127 } 128 129 case GL_UNSIGNED_INT_24_8_OES: 130 switch (format) 131 { 132 case GL_DEPTH_STENCIL_OES: 133 return true; 134 default: 135 return gl::error(GL_INVALID_OPERATION, false); 136 } 137 138 default: 139 return gl::error(GL_INVALID_ENUM, false); 140 } 141 } 142 143 bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height, 144 GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type, 145 gl::Texture2D *texture) 146 { 147 if (!texture) 148 { 149 return gl::error(GL_INVALID_OPERATION, false); 150 } 151 152 if (compressed != texture->isCompressed(level)) 153 { 154 return gl::error(GL_INVALID_OPERATION, false); 155 } 156 157 if (format != GL_NONE) 158 { 159 GLenum internalformat = gl::ConvertSizedInternalFormat(format, type); 160 if (internalformat != texture->getInternalFormat(level)) 161 { 162 return gl::error(GL_INVALID_OPERATION, false); 163 } 164 } 165 166 if (compressed) 167 { 168 if ((width % 4 != 0 && width != texture->getWidth(0)) || 169 (height % 4 != 0 && height != texture->getHeight(0))) 170 { 171 return gl::error(GL_INVALID_OPERATION, false); 172 } 173 } 174 175 if (xoffset + width > texture->getWidth(level) || 176 yoffset + height > texture->getHeight(level)) 177 { 178 return gl::error(GL_INVALID_VALUE, false); 179 } 180 181 return true; 182 } 183 184 bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height, 185 GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type, 186 gl::TextureCubeMap *texture) 187 { 188 if (!texture) 189 { 190 return gl::error(GL_INVALID_OPERATION, false); 191 } 192 193 if (compressed != texture->isCompressed(target, level)) 194 { 195 return gl::error(GL_INVALID_OPERATION, false); 196 } 197 198 if (format != GL_NONE) 199 { 200 GLenum internalformat = gl::ConvertSizedInternalFormat(format, type); 201 if (internalformat != texture->getInternalFormat(target, level)) 202 { 203 return gl::error(GL_INVALID_OPERATION, false); 204 } 205 } 206 207 if (compressed) 208 { 209 if ((width % 4 != 0 && width != texture->getWidth(target, 0)) || 210 (height % 4 != 0 && height != texture->getHeight(target, 0))) 211 { 212 return gl::error(GL_INVALID_OPERATION, false); 213 } 214 } 215 216 if (xoffset + width > texture->getWidth(target, level) || 217 yoffset + height > texture->getHeight(target, level)) 218 { 219 return gl::error(GL_INVALID_VALUE, false); 220 } 221 222 return true; 223 } 224 225 // check for combinations of format and type that are valid for ReadPixels 226 bool validReadFormatType(GLenum format, GLenum type) 227 { 228 switch (format) 229 { 230 case GL_RGBA: 231 switch (type) 232 { 233 case GL_UNSIGNED_BYTE: 234 break; 235 default: 236 return false; 237 } 238 break; 239 case GL_BGRA_EXT: 240 switch (type) 241 { 242 case GL_UNSIGNED_BYTE: 243 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: 244 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: 245 break; 246 default: 247 return false; 248 } 249 break; 250 default: 251 return false; 252 } 253 return true; 254 } 255 256 extern "C" 257 { 258 259 void __stdcall glActiveTexture(GLenum texture) 260 { 261 EVENT("(GLenum texture = 0x%X)", texture); 262 263 try 264 { 265 gl::Context *context = gl::getNonLostContext(); 266 267 if (context) 268 { 269 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1) 270 { 271 return gl::error(GL_INVALID_ENUM); 272 } 273 274 context->setActiveSampler(texture - GL_TEXTURE0); 275 } 276 } 277 catch(std::bad_alloc&) 278 { 279 return gl::error(GL_OUT_OF_MEMORY); 280 } 281 } 282 283 void __stdcall glAttachShader(GLuint program, GLuint shader) 284 { 285 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); 286 287 try 288 { 289 gl::Context *context = gl::getNonLostContext(); 290 291 if (context) 292 { 293 gl::Program *programObject = context->getProgram(program); 294 gl::Shader *shaderObject = context->getShader(shader); 295 296 if (!programObject) 297 { 298 if (context->getShader(program)) 299 { 300 return gl::error(GL_INVALID_OPERATION); 301 } 302 else 303 { 304 return gl::error(GL_INVALID_VALUE); 305 } 306 } 307 308 if (!shaderObject) 309 { 310 if (context->getProgram(shader)) 311 { 312 return gl::error(GL_INVALID_OPERATION); 313 } 314 else 315 { 316 return gl::error(GL_INVALID_VALUE); 317 } 318 } 319 320 if (!programObject->attachShader(shaderObject)) 321 { 322 return gl::error(GL_INVALID_OPERATION); 323 } 324 } 325 } 326 catch(std::bad_alloc&) 327 { 328 return gl::error(GL_OUT_OF_MEMORY); 329 } 330 } 331 332 void __stdcall glBeginQueryEXT(GLenum target, GLuint id) 333 { 334 EVENT("(GLenum target = 0x%X, GLuint %d)", target, id); 335 336 try 337 { 338 switch (target) 339 { 340 case GL_ANY_SAMPLES_PASSED_EXT: 341 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 342 break; 343 default: 344 return gl::error(GL_INVALID_ENUM); 345 } 346 347 if (id == 0) 348 { 349 return gl::error(GL_INVALID_OPERATION); 350 } 351 352 gl::Context *context = gl::getNonLostContext(); 353 354 if (context) 355 { 356 context->beginQuery(target, id); 357 } 358 } 359 catch(std::bad_alloc&) 360 { 361 return gl::error(GL_OUT_OF_MEMORY); 362 } 363 } 364 365 void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name) 366 { 367 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name); 368 369 try 370 { 371 if (index >= gl::MAX_VERTEX_ATTRIBS) 372 { 373 return gl::error(GL_INVALID_VALUE); 374 } 375 376 gl::Context *context = gl::getNonLostContext(); 377 378 if (context) 379 { 380 gl::Program *programObject = context->getProgram(program); 381 382 if (!programObject) 383 { 384 if (context->getShader(program)) 385 { 386 return gl::error(GL_INVALID_OPERATION); 387 } 388 else 389 { 390 return gl::error(GL_INVALID_VALUE); 391 } 392 } 393 394 if (strncmp(name, "gl_", 3) == 0) 395 { 396 return gl::error(GL_INVALID_OPERATION); 397 } 398 399 programObject->bindAttributeLocation(index, name); 400 } 401 } 402 catch(std::bad_alloc&) 403 { 404 return gl::error(GL_OUT_OF_MEMORY); 405 } 406 } 407 408 void __stdcall glBindBuffer(GLenum target, GLuint buffer) 409 { 410 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer); 411 412 try 413 { 414 gl::Context *context = gl::getNonLostContext(); 415 416 if (context) 417 { 418 switch (target) 419 { 420 case GL_ARRAY_BUFFER: 421 context->bindArrayBuffer(buffer); 422 return; 423 case GL_ELEMENT_ARRAY_BUFFER: 424 context->bindElementArrayBuffer(buffer); 425 return; 426 default: 427 return gl::error(GL_INVALID_ENUM); 428 } 429 } 430 } 431 catch(std::bad_alloc&) 432 { 433 return gl::error(GL_OUT_OF_MEMORY); 434 } 435 } 436 437 void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) 438 { 439 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); 440 441 try 442 { 443 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) 444 { 445 return gl::error(GL_INVALID_ENUM); 446 } 447 448 gl::Context *context = gl::getNonLostContext(); 449 450 if (context) 451 { 452 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER) 453 { 454 context->bindReadFramebuffer(framebuffer); 455 } 456 457 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER) 458 { 459 context->bindDrawFramebuffer(framebuffer); 460 } 461 } 462 } 463 catch(std::bad_alloc&) 464 { 465 return gl::error(GL_OUT_OF_MEMORY); 466 } 467 } 468 469 void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer) 470 { 471 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer); 472 473 try 474 { 475 if (target != GL_RENDERBUFFER) 476 { 477 return gl::error(GL_INVALID_ENUM); 478 } 479 480 gl::Context *context = gl::getNonLostContext(); 481 482 if (context) 483 { 484 context->bindRenderbuffer(renderbuffer); 485 } 486 } 487 catch(std::bad_alloc&) 488 { 489 return gl::error(GL_OUT_OF_MEMORY); 490 } 491 } 492 493 void __stdcall glBindTexture(GLenum target, GLuint texture) 494 { 495 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture); 496 497 try 498 { 499 gl::Context *context = gl::getNonLostContext(); 500 501 if (context) 502 { 503 gl::Texture *textureObject = context->getTexture(texture); 504 505 if (textureObject && textureObject->getTarget() != target && texture != 0) 506 { 507 return gl::error(GL_INVALID_OPERATION); 508 } 509 510 switch (target) 511 { 512 case GL_TEXTURE_2D: 513 context->bindTexture2D(texture); 514 return; 515 case GL_TEXTURE_CUBE_MAP: 516 context->bindTextureCubeMap(texture); 517 return; 518 default: 519 return gl::error(GL_INVALID_ENUM); 520 } 521 } 522 } 523 catch(std::bad_alloc&) 524 { 525 return gl::error(GL_OUT_OF_MEMORY); 526 } 527 } 528 529 void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) 530 { 531 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", 532 red, green, blue, alpha); 533 534 try 535 { 536 gl::Context* context = gl::getNonLostContext(); 537 538 if (context) 539 { 540 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha)); 541 } 542 } 543 catch(std::bad_alloc&) 544 { 545 return gl::error(GL_OUT_OF_MEMORY); 546 } 547 } 548 549 void __stdcall glBlendEquation(GLenum mode) 550 { 551 glBlendEquationSeparate(mode, mode); 552 } 553 554 void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) 555 { 556 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); 557 558 try 559 { 560 switch (modeRGB) 561 { 562 case GL_FUNC_ADD: 563 case GL_FUNC_SUBTRACT: 564 case GL_FUNC_REVERSE_SUBTRACT: 565 break; 566 default: 567 return gl::error(GL_INVALID_ENUM); 568 } 569 570 switch (modeAlpha) 571 { 572 case GL_FUNC_ADD: 573 case GL_FUNC_SUBTRACT: 574 case GL_FUNC_REVERSE_SUBTRACT: 575 break; 576 default: 577 return gl::error(GL_INVALID_ENUM); 578 } 579 580 gl::Context *context = gl::getNonLostContext(); 581 582 if (context) 583 { 584 context->setBlendEquation(modeRGB, modeAlpha); 585 } 586 } 587 catch(std::bad_alloc&) 588 { 589 return gl::error(GL_OUT_OF_MEMORY); 590 } 591 } 592 593 void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor) 594 { 595 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); 596 } 597 598 void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) 599 { 600 EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)", 601 srcRGB, dstRGB, srcAlpha, dstAlpha); 602 603 try 604 { 605 switch (srcRGB) 606 { 607 case GL_ZERO: 608 case GL_ONE: 609 case GL_SRC_COLOR: 610 case GL_ONE_MINUS_SRC_COLOR: 611 case GL_DST_COLOR: 612 case GL_ONE_MINUS_DST_COLOR: 613 case GL_SRC_ALPHA: 614 case GL_ONE_MINUS_SRC_ALPHA: 615 case GL_DST_ALPHA: 616 case GL_ONE_MINUS_DST_ALPHA: 617 case GL_CONSTANT_COLOR: 618 case GL_ONE_MINUS_CONSTANT_COLOR: 619 case GL_CONSTANT_ALPHA: 620 case GL_ONE_MINUS_CONSTANT_ALPHA: 621 case GL_SRC_ALPHA_SATURATE: 622 break; 623 default: 624 return gl::error(GL_INVALID_ENUM); 625 } 626 627 switch (dstRGB) 628 { 629 case GL_ZERO: 630 case GL_ONE: 631 case GL_SRC_COLOR: 632 case GL_ONE_MINUS_SRC_COLOR: 633 case GL_DST_COLOR: 634 case GL_ONE_MINUS_DST_COLOR: 635 case GL_SRC_ALPHA: 636 case GL_ONE_MINUS_SRC_ALPHA: 637 case GL_DST_ALPHA: 638 case GL_ONE_MINUS_DST_ALPHA: 639 case GL_CONSTANT_COLOR: 640 case GL_ONE_MINUS_CONSTANT_COLOR: 641 case GL_CONSTANT_ALPHA: 642 case GL_ONE_MINUS_CONSTANT_ALPHA: 643 break; 644 default: 645 return gl::error(GL_INVALID_ENUM); 646 } 647 648 switch (srcAlpha) 649 { 650 case GL_ZERO: 651 case GL_ONE: 652 case GL_SRC_COLOR: 653 case GL_ONE_MINUS_SRC_COLOR: 654 case GL_DST_COLOR: 655 case GL_ONE_MINUS_DST_COLOR: 656 case GL_SRC_ALPHA: 657 case GL_ONE_MINUS_SRC_ALPHA: 658 case GL_DST_ALPHA: 659 case GL_ONE_MINUS_DST_ALPHA: 660 case GL_CONSTANT_COLOR: 661 case GL_ONE_MINUS_CONSTANT_COLOR: 662 case GL_CONSTANT_ALPHA: 663 case GL_ONE_MINUS_CONSTANT_ALPHA: 664 case GL_SRC_ALPHA_SATURATE: 665 break; 666 default: 667 return gl::error(GL_INVALID_ENUM); 668 } 669 670 switch (dstAlpha) 671 { 672 case GL_ZERO: 673 case GL_ONE: 674 case GL_SRC_COLOR: 675 case GL_ONE_MINUS_SRC_COLOR: 676 case GL_DST_COLOR: 677 case GL_ONE_MINUS_DST_COLOR: 678 case GL_SRC_ALPHA: 679 case GL_ONE_MINUS_SRC_ALPHA: 680 case GL_DST_ALPHA: 681 case GL_ONE_MINUS_DST_ALPHA: 682 case GL_CONSTANT_COLOR: 683 case GL_ONE_MINUS_CONSTANT_COLOR: 684 case GL_CONSTANT_ALPHA: 685 case GL_ONE_MINUS_CONSTANT_ALPHA: 686 break; 687 default: 688 return gl::error(GL_INVALID_ENUM); 689 } 690 691 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR || 692 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR); 693 694 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA || 695 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA); 696 697 if (constantColorUsed && constantAlphaUsed) 698 { 699 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL"); 700 return gl::error(GL_INVALID_OPERATION); 701 } 702 703 gl::Context *context = gl::getNonLostContext(); 704 705 if (context) 706 { 707 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha); 708 } 709 } 710 catch(std::bad_alloc&) 711 { 712 return gl::error(GL_OUT_OF_MEMORY); 713 } 714 } 715 716 void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) 717 { 718 EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)", 719 target, size, data, usage); 720 721 try 722 { 723 if (size < 0) 724 { 725 return gl::error(GL_INVALID_VALUE); 726 } 727 728 switch (usage) 729 { 730 case GL_STREAM_DRAW: 731 case GL_STATIC_DRAW: 732 case GL_DYNAMIC_DRAW: 733 break; 734 default: 735 return gl::error(GL_INVALID_ENUM); 736 } 737 738 gl::Context *context = gl::getNonLostContext(); 739 740 if (context) 741 { 742 gl::Buffer *buffer; 743 744 switch (target) 745 { 746 case GL_ARRAY_BUFFER: 747 buffer = context->getArrayBuffer(); 748 break; 749 case GL_ELEMENT_ARRAY_BUFFER: 750 buffer = context->getElementArrayBuffer(); 751 break; 752 default: 753 return gl::error(GL_INVALID_ENUM); 754 } 755 756 if (!buffer) 757 { 758 return gl::error(GL_INVALID_OPERATION); 759 } 760 761 buffer->bufferData(data, size, usage); 762 } 763 } 764 catch(std::bad_alloc&) 765 { 766 return gl::error(GL_OUT_OF_MEMORY); 767 } 768 } 769 770 void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) 771 { 772 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)", 773 target, offset, size, data); 774 775 try 776 { 777 if (size < 0 || offset < 0) 778 { 779 return gl::error(GL_INVALID_VALUE); 780 } 781 782 if (data == NULL) 783 { 784 return; 785 } 786 787 gl::Context *context = gl::getNonLostContext(); 788 789 if (context) 790 { 791 gl::Buffer *buffer; 792 793 switch (target) 794 { 795 case GL_ARRAY_BUFFER: 796 buffer = context->getArrayBuffer(); 797 break; 798 case GL_ELEMENT_ARRAY_BUFFER: 799 buffer = context->getElementArrayBuffer(); 800 break; 801 default: 802 return gl::error(GL_INVALID_ENUM); 803 } 804 805 if (!buffer) 806 { 807 return gl::error(GL_INVALID_OPERATION); 808 } 809 810 if ((size_t)size + offset > buffer->size()) 811 { 812 return gl::error(GL_INVALID_VALUE); 813 } 814 815 buffer->bufferSubData(data, size, offset); 816 } 817 } 818 catch(std::bad_alloc&) 819 { 820 return gl::error(GL_OUT_OF_MEMORY); 821 } 822 } 823 824 GLenum __stdcall glCheckFramebufferStatus(GLenum target) 825 { 826 EVENT("(GLenum target = 0x%X)", target); 827 828 try 829 { 830 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) 831 { 832 return gl::error(GL_INVALID_ENUM, 0); 833 } 834 835 gl::Context *context = gl::getNonLostContext(); 836 837 if (context) 838 { 839 gl::Framebuffer *framebuffer = NULL; 840 if (target == GL_READ_FRAMEBUFFER_ANGLE) 841 { 842 framebuffer = context->getReadFramebuffer(); 843 } 844 else 845 { 846 framebuffer = context->getDrawFramebuffer(); 847 } 848 849 return framebuffer->completeness(); 850 } 851 } 852 catch(std::bad_alloc&) 853 { 854 return gl::error(GL_OUT_OF_MEMORY, 0); 855 } 856 857 return 0; 858 } 859 860 void __stdcall glClear(GLbitfield mask) 861 { 862 EVENT("(GLbitfield mask = %X)", mask); 863 864 try 865 { 866 gl::Context *context = gl::getNonLostContext(); 867 868 if (context) 869 { 870 context->clear(mask); 871 } 872 } 873 catch(std::bad_alloc&) 874 { 875 return gl::error(GL_OUT_OF_MEMORY); 876 } 877 } 878 879 void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) 880 { 881 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", 882 red, green, blue, alpha); 883 884 try 885 { 886 gl::Context *context = gl::getNonLostContext(); 887 888 if (context) 889 { 890 context->setClearColor(red, green, blue, alpha); 891 } 892 } 893 catch(std::bad_alloc&) 894 { 895 return gl::error(GL_OUT_OF_MEMORY); 896 } 897 } 898 899 void __stdcall glClearDepthf(GLclampf depth) 900 { 901 EVENT("(GLclampf depth = %f)", depth); 902 903 try 904 { 905 gl::Context *context = gl::getNonLostContext(); 906 907 if (context) 908 { 909 context->setClearDepth(depth); 910 } 911 } 912 catch(std::bad_alloc&) 913 { 914 return gl::error(GL_OUT_OF_MEMORY); 915 } 916 } 917 918 void __stdcall glClearStencil(GLint s) 919 { 920 EVENT("(GLint s = %d)", s); 921 922 try 923 { 924 gl::Context *context = gl::getNonLostContext(); 925 926 if (context) 927 { 928 context->setClearStencil(s); 929 } 930 } 931 catch(std::bad_alloc&) 932 { 933 return gl::error(GL_OUT_OF_MEMORY); 934 } 935 } 936 937 void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) 938 { 939 EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)", 940 red, green, blue, alpha); 941 942 try 943 { 944 gl::Context *context = gl::getNonLostContext(); 945 946 if (context) 947 { 948 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE); 949 } 950 } 951 catch(std::bad_alloc&) 952 { 953 return gl::error(GL_OUT_OF_MEMORY); 954 } 955 } 956 957 void __stdcall glCompileShader(GLuint shader) 958 { 959 EVENT("(GLuint shader = %d)", shader); 960 961 try 962 { 963 gl::Context *context = gl::getNonLostContext(); 964 965 if (context) 966 { 967 gl::Shader *shaderObject = context->getShader(shader); 968 969 if (!shaderObject) 970 { 971 if (context->getProgram(shader)) 972 { 973 return gl::error(GL_INVALID_OPERATION); 974 } 975 else 976 { 977 return gl::error(GL_INVALID_VALUE); 978 } 979 } 980 981 shaderObject->compile(); 982 } 983 } 984 catch(std::bad_alloc&) 985 { 986 return gl::error(GL_OUT_OF_MEMORY); 987 } 988 } 989 990 void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, 991 GLint border, GLsizei imageSize, const GLvoid* data) 992 { 993 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " 994 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", 995 target, level, internalformat, width, height, border, imageSize, data); 996 997 try 998 { 999 if (!validImageSize(level, width, height) || border != 0 || imageSize < 0) 1000 { 1001 return gl::error(GL_INVALID_VALUE); 1002 } 1003 1004 switch (internalformat) 1005 { 1006 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 1007 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 1008 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: 1009 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: 1010 break; 1011 default: 1012 return gl::error(GL_INVALID_ENUM); 1013 } 1014 1015 if (border != 0) 1016 { 1017 return gl::error(GL_INVALID_OPERATION); 1018 } 1019 1020 if (width != 1 && width != 2 && width % 4 != 0) 1021 { 1022 return gl::error(GL_INVALID_OPERATION); 1023 } 1024 1025 if (height != 1 && height != 2 && height % 4 != 0) 1026 { 1027 return gl::error(GL_INVALID_OPERATION); 1028 } 1029 1030 gl::Context *context = gl::getNonLostContext(); 1031 1032 if (context) 1033 { 1034 if (level > context->getMaximumTextureLevel()) 1035 { 1036 return gl::error(GL_INVALID_VALUE); 1037 } 1038 1039 switch (target) 1040 { 1041 case GL_TEXTURE_2D: 1042 if (width > (context->getMaximumTextureDimension() >> level) || 1043 height > (context->getMaximumTextureDimension() >> level)) 1044 { 1045 return gl::error(GL_INVALID_VALUE); 1046 } 1047 break; 1048 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1049 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1050 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1051 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1052 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1053 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1054 if (width != height) 1055 { 1056 return gl::error(GL_INVALID_VALUE); 1057 } 1058 1059 if (width > (context->getMaximumCubeTextureDimension() >> level) || 1060 height > (context->getMaximumCubeTextureDimension() >> level)) 1061 { 1062 return gl::error(GL_INVALID_VALUE); 1063 } 1064 break; 1065 default: 1066 return gl::error(GL_INVALID_ENUM); 1067 } 1068 1069 switch (internalformat) { 1070 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 1071 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 1072 if (!context->supportsDXT1Textures()) 1073 { 1074 return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed 1075 } 1076 break; 1077 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: 1078 if (!context->supportsDXT3Textures()) 1079 { 1080 return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed 1081 } 1082 break; 1083 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: 1084 if (!context->supportsDXT5Textures()) 1085 { 1086 return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed 1087 } 1088 break; 1089 default: UNREACHABLE(); 1090 } 1091 1092 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat)) 1093 { 1094 return gl::error(GL_INVALID_VALUE); 1095 } 1096 1097 if (target == GL_TEXTURE_2D) 1098 { 1099 gl::Texture2D *texture = context->getTexture2D(); 1100 1101 if (!texture) 1102 { 1103 return gl::error(GL_INVALID_OPERATION); 1104 } 1105 1106 if (texture->isImmutable()) 1107 { 1108 return gl::error(GL_INVALID_OPERATION); 1109 } 1110 1111 texture->setCompressedImage(level, internalformat, width, height, imageSize, data); 1112 } 1113 else 1114 { 1115 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 1116 1117 if (!texture) 1118 { 1119 return gl::error(GL_INVALID_OPERATION); 1120 } 1121 1122 if (texture->isImmutable()) 1123 { 1124 return gl::error(GL_INVALID_OPERATION); 1125 } 1126 1127 switch (target) 1128 { 1129 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1130 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1131 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1132 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1133 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1134 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1135 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data); 1136 break; 1137 default: UNREACHABLE(); 1138 } 1139 } 1140 } 1141 1142 } 1143 catch(std::bad_alloc&) 1144 { 1145 return gl::error(GL_OUT_OF_MEMORY); 1146 } 1147 } 1148 1149 void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, 1150 GLenum format, GLsizei imageSize, const GLvoid* data) 1151 { 1152 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 1153 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, " 1154 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", 1155 target, level, xoffset, yoffset, width, height, format, imageSize, data); 1156 1157 try 1158 { 1159 if (!gl::IsInternalTextureTarget(target)) 1160 { 1161 return gl::error(GL_INVALID_ENUM); 1162 } 1163 1164 if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0) 1165 { 1166 return gl::error(GL_INVALID_VALUE); 1167 } 1168 1169 switch (format) 1170 { 1171 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 1172 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 1173 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: 1174 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: 1175 break; 1176 default: 1177 return gl::error(GL_INVALID_ENUM); 1178 } 1179 1180 if (width == 0 || height == 0 || data == NULL) 1181 { 1182 return; 1183 } 1184 1185 gl::Context *context = gl::getNonLostContext(); 1186 1187 if (context) 1188 { 1189 if (level > context->getMaximumTextureLevel()) 1190 { 1191 return gl::error(GL_INVALID_VALUE); 1192 } 1193 1194 switch (format) { 1195 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 1196 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 1197 if (!context->supportsDXT1Textures()) 1198 { 1199 return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed 1200 } 1201 break; 1202 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: 1203 if (!context->supportsDXT3Textures()) 1204 { 1205 return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed 1206 } 1207 break; 1208 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: 1209 if (!context->supportsDXT5Textures()) 1210 { 1211 return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed 1212 } 1213 break; 1214 default: UNREACHABLE(); 1215 } 1216 1217 if (imageSize != gl::ComputeCompressedSize(width, height, format)) 1218 { 1219 return gl::error(GL_INVALID_VALUE); 1220 } 1221 1222 if (xoffset % 4 != 0 || yoffset % 4 != 0) 1223 { 1224 return gl::error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction 1225 // does not exist unless DXT textures are supported. 1226 } 1227 1228 if (target == GL_TEXTURE_2D) 1229 { 1230 gl::Texture2D *texture = context->getTexture2D(); 1231 if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, GL_NONE, texture)) 1232 { 1233 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); 1234 } 1235 } 1236 else if (gl::IsCubemapTextureTarget(target)) 1237 { 1238 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 1239 if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, GL_NONE, texture)) 1240 { 1241 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data); 1242 } 1243 } 1244 else 1245 { 1246 UNREACHABLE(); 1247 } 1248 } 1249 } 1250 catch(std::bad_alloc&) 1251 { 1252 return gl::error(GL_OUT_OF_MEMORY); 1253 } 1254 } 1255 1256 void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) 1257 { 1258 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " 1259 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)", 1260 target, level, internalformat, x, y, width, height, border); 1261 1262 try 1263 { 1264 if (!validImageSize(level, width, height)) 1265 { 1266 return gl::error(GL_INVALID_VALUE); 1267 } 1268 1269 if (border != 0) 1270 { 1271 return gl::error(GL_INVALID_VALUE); 1272 } 1273 1274 gl::Context *context = gl::getNonLostContext(); 1275 1276 if (context) 1277 { 1278 if (level > context->getMaximumTextureLevel()) 1279 { 1280 return gl::error(GL_INVALID_VALUE); 1281 } 1282 1283 switch (target) 1284 { 1285 case GL_TEXTURE_2D: 1286 if (width > (context->getMaximumTextureDimension() >> level) || 1287 height > (context->getMaximumTextureDimension() >> level)) 1288 { 1289 return gl::error(GL_INVALID_VALUE); 1290 } 1291 break; 1292 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1293 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1294 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1295 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1296 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1297 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1298 if (width != height) 1299 { 1300 return gl::error(GL_INVALID_VALUE); 1301 } 1302 1303 if (width > (context->getMaximumCubeTextureDimension() >> level) || 1304 height > (context->getMaximumCubeTextureDimension() >> level)) 1305 { 1306 return gl::error(GL_INVALID_VALUE); 1307 } 1308 break; 1309 default: 1310 return gl::error(GL_INVALID_ENUM); 1311 } 1312 1313 gl::Framebuffer *framebuffer = context->getReadFramebuffer(); 1314 1315 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) 1316 { 1317 return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); 1318 } 1319 1320 if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0) 1321 { 1322 return gl::error(GL_INVALID_OPERATION); 1323 } 1324 1325 gl::Renderbuffer *source = framebuffer->getReadColorbuffer(); 1326 GLenum colorbufferFormat = source->getInternalFormat(); 1327 1328 // [OpenGL ES 2.0.24] table 3.9 1329 switch (internalformat) 1330 { 1331 case GL_ALPHA: 1332 if (colorbufferFormat != GL_ALPHA8_EXT && 1333 colorbufferFormat != GL_RGBA4 && 1334 colorbufferFormat != GL_RGB5_A1 && 1335 colorbufferFormat != GL_BGRA8_EXT && 1336 colorbufferFormat != GL_RGBA8_OES) 1337 { 1338 return gl::error(GL_INVALID_OPERATION); 1339 } 1340 break; 1341 case GL_LUMINANCE: 1342 case GL_RGB: 1343 if (colorbufferFormat != GL_RGB565 && 1344 colorbufferFormat != GL_RGB8_OES && 1345 colorbufferFormat != GL_RGBA4 && 1346 colorbufferFormat != GL_RGB5_A1 && 1347 colorbufferFormat != GL_BGRA8_EXT && 1348 colorbufferFormat != GL_RGBA8_OES) 1349 { 1350 return gl::error(GL_INVALID_OPERATION); 1351 } 1352 break; 1353 case GL_LUMINANCE_ALPHA: 1354 case GL_RGBA: 1355 if (colorbufferFormat != GL_RGBA4 && 1356 colorbufferFormat != GL_RGB5_A1 && 1357 colorbufferFormat != GL_BGRA8_EXT && 1358 colorbufferFormat != GL_RGBA8_OES) 1359 { 1360 return gl::error(GL_INVALID_OPERATION); 1361 } 1362 break; 1363 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 1364 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 1365 if (context->supportsDXT1Textures()) 1366 { 1367 return gl::error(GL_INVALID_OPERATION); 1368 } 1369 else 1370 { 1371 return gl::error(GL_INVALID_ENUM); 1372 } 1373 break; 1374 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: 1375 if (context->supportsDXT3Textures()) 1376 { 1377 return gl::error(GL_INVALID_OPERATION); 1378 } 1379 else 1380 { 1381 return gl::error(GL_INVALID_ENUM); 1382 } 1383 break; 1384 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: 1385 if (context->supportsDXT5Textures()) 1386 { 1387 return gl::error(GL_INVALID_OPERATION); 1388 } 1389 else 1390 { 1391 return gl::error(GL_INVALID_ENUM); 1392 } 1393 break; 1394 case GL_DEPTH_COMPONENT: 1395 case GL_DEPTH_COMPONENT16: 1396 case GL_DEPTH_COMPONENT32_OES: 1397 case GL_DEPTH_STENCIL_OES: 1398 case GL_DEPTH24_STENCIL8_OES: 1399 if (context->supportsDepthTextures()) 1400 { 1401 return gl::error(GL_INVALID_OPERATION); 1402 } 1403 else 1404 { 1405 return gl::error(GL_INVALID_ENUM); 1406 } 1407 default: 1408 return gl::error(GL_INVALID_ENUM); 1409 } 1410 1411 if (target == GL_TEXTURE_2D) 1412 { 1413 gl::Texture2D *texture = context->getTexture2D(); 1414 1415 if (!texture) 1416 { 1417 return gl::error(GL_INVALID_OPERATION); 1418 } 1419 1420 if (texture->isImmutable()) 1421 { 1422 return gl::error(GL_INVALID_OPERATION); 1423 } 1424 1425 texture->copyImage(level, internalformat, x, y, width, height, framebuffer); 1426 } 1427 else if (gl::IsCubemapTextureTarget(target)) 1428 { 1429 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 1430 1431 if (!texture) 1432 { 1433 return gl::error(GL_INVALID_OPERATION); 1434 } 1435 1436 if (texture->isImmutable()) 1437 { 1438 return gl::error(GL_INVALID_OPERATION); 1439 } 1440 1441 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer); 1442 } 1443 else UNREACHABLE(); 1444 } 1445 } 1446 catch(std::bad_alloc&) 1447 { 1448 return gl::error(GL_OUT_OF_MEMORY); 1449 } 1450 } 1451 1452 void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) 1453 { 1454 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 1455 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", 1456 target, level, xoffset, yoffset, x, y, width, height); 1457 1458 try 1459 { 1460 if (!gl::IsInternalTextureTarget(target)) 1461 { 1462 return gl::error(GL_INVALID_ENUM); 1463 } 1464 1465 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0) 1466 { 1467 return gl::error(GL_INVALID_VALUE); 1468 } 1469 1470 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) 1471 { 1472 return gl::error(GL_INVALID_VALUE); 1473 } 1474 1475 if (width == 0 || height == 0) 1476 { 1477 return; 1478 } 1479 1480 gl::Context *context = gl::getNonLostContext(); 1481 1482 if (context) 1483 { 1484 if (level > context->getMaximumTextureLevel()) 1485 { 1486 return gl::error(GL_INVALID_VALUE); 1487 } 1488 1489 gl::Framebuffer *framebuffer = context->getReadFramebuffer(); 1490 1491 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) 1492 { 1493 return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); 1494 } 1495 1496 if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0) 1497 { 1498 return gl::error(GL_INVALID_OPERATION); 1499 } 1500 1501 gl::Renderbuffer *source = framebuffer->getReadColorbuffer(); 1502 GLenum colorbufferFormat = source->getInternalFormat(); 1503 gl::Texture *texture = NULL; 1504 GLenum textureFormat = GL_RGBA; 1505 1506 if (target == GL_TEXTURE_2D) 1507 { 1508 gl::Texture2D *tex2d = context->getTexture2D(); 1509 1510 if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, GL_NONE, tex2d)) 1511 { 1512 return; // error already registered by validateSubImageParams 1513 } 1514 textureFormat = gl::ExtractFormat(tex2d->getInternalFormat(level)); 1515 texture = tex2d; 1516 } 1517 else if (gl::IsCubemapTextureTarget(target)) 1518 { 1519 gl::TextureCubeMap *texcube = context->getTextureCubeMap(); 1520 1521 if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, GL_NONE, texcube)) 1522 { 1523 return; // error already registered by validateSubImageParams 1524 } 1525 textureFormat = gl::ExtractFormat(texcube->getInternalFormat(target, level)); 1526 texture = texcube; 1527 } 1528 else UNREACHABLE(); 1529 1530 // [OpenGL ES 2.0.24] table 3.9 1531 switch (textureFormat) 1532 { 1533 case GL_ALPHA: 1534 if (colorbufferFormat != GL_ALPHA8_EXT && 1535 colorbufferFormat != GL_RGBA4 && 1536 colorbufferFormat != GL_RGB5_A1 && 1537 colorbufferFormat != GL_RGBA8_OES) 1538 { 1539 return gl::error(GL_INVALID_OPERATION); 1540 } 1541 break; 1542 case GL_LUMINANCE: 1543 case GL_RGB: 1544 if (colorbufferFormat != GL_RGB565 && 1545 colorbufferFormat != GL_RGB8_OES && 1546 colorbufferFormat != GL_RGBA4 && 1547 colorbufferFormat != GL_RGB5_A1 && 1548 colorbufferFormat != GL_RGBA8_OES) 1549 { 1550 return gl::error(GL_INVALID_OPERATION); 1551 } 1552 break; 1553 case GL_LUMINANCE_ALPHA: 1554 case GL_RGBA: 1555 if (colorbufferFormat != GL_RGBA4 && 1556 colorbufferFormat != GL_RGB5_A1 && 1557 colorbufferFormat != GL_RGBA8_OES) 1558 { 1559 return gl::error(GL_INVALID_OPERATION); 1560 } 1561 break; 1562 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 1563 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 1564 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: 1565 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: 1566 return gl::error(GL_INVALID_OPERATION); 1567 case GL_DEPTH_COMPONENT: 1568 case GL_DEPTH_STENCIL_OES: 1569 return gl::error(GL_INVALID_OPERATION); 1570 default: 1571 return gl::error(GL_INVALID_OPERATION); 1572 } 1573 1574 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer); 1575 } 1576 } 1577 1578 catch(std::bad_alloc&) 1579 { 1580 return gl::error(GL_OUT_OF_MEMORY); 1581 } 1582 } 1583 1584 GLuint __stdcall glCreateProgram(void) 1585 { 1586 EVENT("()"); 1587 1588 try 1589 { 1590 gl::Context *context = gl::getNonLostContext(); 1591 1592 if (context) 1593 { 1594 return context->createProgram(); 1595 } 1596 } 1597 catch(std::bad_alloc&) 1598 { 1599 return gl::error(GL_OUT_OF_MEMORY, 0); 1600 } 1601 1602 return 0; 1603 } 1604 1605 GLuint __stdcall glCreateShader(GLenum type) 1606 { 1607 EVENT("(GLenum type = 0x%X)", type); 1608 1609 try 1610 { 1611 gl::Context *context = gl::getNonLostContext(); 1612 1613 if (context) 1614 { 1615 switch (type) 1616 { 1617 case GL_FRAGMENT_SHADER: 1618 case GL_VERTEX_SHADER: 1619 return context->createShader(type); 1620 default: 1621 return gl::error(GL_INVALID_ENUM, 0); 1622 } 1623 } 1624 } 1625 catch(std::bad_alloc&) 1626 { 1627 return gl::error(GL_OUT_OF_MEMORY, 0); 1628 } 1629 1630 return 0; 1631 } 1632 1633 void __stdcall glCullFace(GLenum mode) 1634 { 1635 EVENT("(GLenum mode = 0x%X)", mode); 1636 1637 try 1638 { 1639 switch (mode) 1640 { 1641 case GL_FRONT: 1642 case GL_BACK: 1643 case GL_FRONT_AND_BACK: 1644 { 1645 gl::Context *context = gl::getNonLostContext(); 1646 1647 if (context) 1648 { 1649 context->setCullMode(mode); 1650 } 1651 } 1652 break; 1653 default: 1654 return gl::error(GL_INVALID_ENUM); 1655 } 1656 } 1657 catch(std::bad_alloc&) 1658 { 1659 return gl::error(GL_OUT_OF_MEMORY); 1660 } 1661 } 1662 1663 void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers) 1664 { 1665 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers); 1666 1667 try 1668 { 1669 if (n < 0) 1670 { 1671 return gl::error(GL_INVALID_VALUE); 1672 } 1673 1674 gl::Context *context = gl::getNonLostContext(); 1675 1676 if (context) 1677 { 1678 for (int i = 0; i < n; i++) 1679 { 1680 context->deleteBuffer(buffers[i]); 1681 } 1682 } 1683 } 1684 catch(std::bad_alloc&) 1685 { 1686 return gl::error(GL_OUT_OF_MEMORY); 1687 } 1688 } 1689 1690 void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences) 1691 { 1692 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences); 1693 1694 try 1695 { 1696 if (n < 0) 1697 { 1698 return gl::error(GL_INVALID_VALUE); 1699 } 1700 1701 gl::Context *context = gl::getNonLostContext(); 1702 1703 if (context) 1704 { 1705 for (int i = 0; i < n; i++) 1706 { 1707 context->deleteFence(fences[i]); 1708 } 1709 } 1710 } 1711 catch(std::bad_alloc&) 1712 { 1713 return gl::error(GL_OUT_OF_MEMORY); 1714 } 1715 } 1716 1717 void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) 1718 { 1719 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers); 1720 1721 try 1722 { 1723 if (n < 0) 1724 { 1725 return gl::error(GL_INVALID_VALUE); 1726 } 1727 1728 gl::Context *context = gl::getNonLostContext(); 1729 1730 if (context) 1731 { 1732 for (int i = 0; i < n; i++) 1733 { 1734 if (framebuffers[i] != 0) 1735 { 1736 context->deleteFramebuffer(framebuffers[i]); 1737 } 1738 } 1739 } 1740 } 1741 catch(std::bad_alloc&) 1742 { 1743 return gl::error(GL_OUT_OF_MEMORY); 1744 } 1745 } 1746 1747 void __stdcall glDeleteProgram(GLuint program) 1748 { 1749 EVENT("(GLuint program = %d)", program); 1750 1751 try 1752 { 1753 if (program == 0) 1754 { 1755 return; 1756 } 1757 1758 gl::Context *context = gl::getNonLostContext(); 1759 1760 if (context) 1761 { 1762 if (!context->getProgram(program)) 1763 { 1764 if(context->getShader(program)) 1765 { 1766 return gl::error(GL_INVALID_OPERATION); 1767 } 1768 else 1769 { 1770 return gl::error(GL_INVALID_VALUE); 1771 } 1772 } 1773 1774 context->deleteProgram(program); 1775 } 1776 } 1777 catch(std::bad_alloc&) 1778 { 1779 return gl::error(GL_OUT_OF_MEMORY); 1780 } 1781 } 1782 1783 void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids) 1784 { 1785 EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids); 1786 1787 try 1788 { 1789 if (n < 0) 1790 { 1791 return gl::error(GL_INVALID_VALUE); 1792 } 1793 1794 gl::Context *context = gl::getNonLostContext(); 1795 1796 if (context) 1797 { 1798 for (int i = 0; i < n; i++) 1799 { 1800 context->deleteQuery(ids[i]); 1801 } 1802 } 1803 } 1804 catch(std::bad_alloc&) 1805 { 1806 return gl::error(GL_OUT_OF_MEMORY); 1807 } 1808 } 1809 1810 void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) 1811 { 1812 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); 1813 1814 try 1815 { 1816 if (n < 0) 1817 { 1818 return gl::error(GL_INVALID_VALUE); 1819 } 1820 1821 gl::Context *context = gl::getNonLostContext(); 1822 1823 if (context) 1824 { 1825 for (int i = 0; i < n; i++) 1826 { 1827 context->deleteRenderbuffer(renderbuffers[i]); 1828 } 1829 } 1830 } 1831 catch(std::bad_alloc&) 1832 { 1833 return gl::error(GL_OUT_OF_MEMORY); 1834 } 1835 } 1836 1837 void __stdcall glDeleteShader(GLuint shader) 1838 { 1839 EVENT("(GLuint shader = %d)", shader); 1840 1841 try 1842 { 1843 if (shader == 0) 1844 { 1845 return; 1846 } 1847 1848 gl::Context *context = gl::getNonLostContext(); 1849 1850 if (context) 1851 { 1852 if (!context->getShader(shader)) 1853 { 1854 if(context->getProgram(shader)) 1855 { 1856 return gl::error(GL_INVALID_OPERATION); 1857 } 1858 else 1859 { 1860 return gl::error(GL_INVALID_VALUE); 1861 } 1862 } 1863 1864 context->deleteShader(shader); 1865 } 1866 } 1867 catch(std::bad_alloc&) 1868 { 1869 return gl::error(GL_OUT_OF_MEMORY); 1870 } 1871 } 1872 1873 void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures) 1874 { 1875 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures); 1876 1877 try 1878 { 1879 if (n < 0) 1880 { 1881 return gl::error(GL_INVALID_VALUE); 1882 } 1883 1884 gl::Context *context = gl::getNonLostContext(); 1885 1886 if (context) 1887 { 1888 for (int i = 0; i < n; i++) 1889 { 1890 if (textures[i] != 0) 1891 { 1892 context->deleteTexture(textures[i]); 1893 } 1894 } 1895 } 1896 } 1897 catch(std::bad_alloc&) 1898 { 1899 return gl::error(GL_OUT_OF_MEMORY); 1900 } 1901 } 1902 1903 void __stdcall glDepthFunc(GLenum func) 1904 { 1905 EVENT("(GLenum func = 0x%X)", func); 1906 1907 try 1908 { 1909 switch (func) 1910 { 1911 case GL_NEVER: 1912 case GL_ALWAYS: 1913 case GL_LESS: 1914 case GL_LEQUAL: 1915 case GL_EQUAL: 1916 case GL_GREATER: 1917 case GL_GEQUAL: 1918 case GL_NOTEQUAL: 1919 break; 1920 default: 1921 return gl::error(GL_INVALID_ENUM); 1922 } 1923 1924 gl::Context *context = gl::getNonLostContext(); 1925 1926 if (context) 1927 { 1928 context->setDepthFunc(func); 1929 } 1930 } 1931 catch(std::bad_alloc&) 1932 { 1933 return gl::error(GL_OUT_OF_MEMORY); 1934 } 1935 } 1936 1937 void __stdcall glDepthMask(GLboolean flag) 1938 { 1939 EVENT("(GLboolean flag = %d)", flag); 1940 1941 try 1942 { 1943 gl::Context *context = gl::getNonLostContext(); 1944 1945 if (context) 1946 { 1947 context->setDepthMask(flag != GL_FALSE); 1948 } 1949 } 1950 catch(std::bad_alloc&) 1951 { 1952 return gl::error(GL_OUT_OF_MEMORY); 1953 } 1954 } 1955 1956 void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar) 1957 { 1958 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar); 1959 1960 try 1961 { 1962 gl::Context *context = gl::getNonLostContext(); 1963 1964 if (context) 1965 { 1966 context->setDepthRange(zNear, zFar); 1967 } 1968 } 1969 catch(std::bad_alloc&) 1970 { 1971 return gl::error(GL_OUT_OF_MEMORY); 1972 } 1973 } 1974 1975 void __stdcall glDetachShader(GLuint program, GLuint shader) 1976 { 1977 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); 1978 1979 try 1980 { 1981 gl::Context *context = gl::getNonLostContext(); 1982 1983 if (context) 1984 { 1985 1986 gl::Program *programObject = context->getProgram(program); 1987 gl::Shader *shaderObject = context->getShader(shader); 1988 1989 if (!programObject) 1990 { 1991 gl::Shader *shaderByProgramHandle; 1992 shaderByProgramHandle = context->getShader(program); 1993 if (!shaderByProgramHandle) 1994 { 1995 return gl::error(GL_INVALID_VALUE); 1996 } 1997 else 1998 { 1999 return gl::error(GL_INVALID_OPERATION); 2000 } 2001 } 2002 2003 if (!shaderObject) 2004 { 2005 gl::Program *programByShaderHandle = context->getProgram(shader); 2006 if (!programByShaderHandle) 2007 { 2008 return gl::error(GL_INVALID_VALUE); 2009 } 2010 else 2011 { 2012 return gl::error(GL_INVALID_OPERATION); 2013 } 2014 } 2015 2016 if (!programObject->detachShader(shaderObject)) 2017 { 2018 return gl::error(GL_INVALID_OPERATION); 2019 } 2020 } 2021 } 2022 catch(std::bad_alloc&) 2023 { 2024 return gl::error(GL_OUT_OF_MEMORY); 2025 } 2026 } 2027 2028 void __stdcall glDisable(GLenum cap) 2029 { 2030 EVENT("(GLenum cap = 0x%X)", cap); 2031 2032 try 2033 { 2034 gl::Context *context = gl::getNonLostContext(); 2035 2036 if (context) 2037 { 2038 switch (cap) 2039 { 2040 case GL_CULL_FACE: context->setCullFace(false); break; 2041 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break; 2042 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break; 2043 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break; 2044 case GL_SCISSOR_TEST: context->setScissorTest(false); break; 2045 case GL_STENCIL_TEST: context->setStencilTest(false); break; 2046 case GL_DEPTH_TEST: context->setDepthTest(false); break; 2047 case GL_BLEND: context->setBlend(false); break; 2048 case GL_DITHER: context->setDither(false); break; 2049 default: 2050 return gl::error(GL_INVALID_ENUM); 2051 } 2052 } 2053 } 2054 catch(std::bad_alloc&) 2055 { 2056 return gl::error(GL_OUT_OF_MEMORY); 2057 } 2058 } 2059 2060 void __stdcall glDisableVertexAttribArray(GLuint index) 2061 { 2062 EVENT("(GLuint index = %d)", index); 2063 2064 try 2065 { 2066 if (index >= gl::MAX_VERTEX_ATTRIBS) 2067 { 2068 return gl::error(GL_INVALID_VALUE); 2069 } 2070 2071 gl::Context *context = gl::getNonLostContext(); 2072 2073 if (context) 2074 { 2075 context->setEnableVertexAttribArray(index, false); 2076 } 2077 } 2078 catch(std::bad_alloc&) 2079 { 2080 return gl::error(GL_OUT_OF_MEMORY); 2081 } 2082 } 2083 2084 void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) 2085 { 2086 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); 2087 2088 try 2089 { 2090 if (count < 0 || first < 0) 2091 { 2092 return gl::error(GL_INVALID_VALUE); 2093 } 2094 2095 gl::Context *context = gl::getNonLostContext(); 2096 2097 if (context) 2098 { 2099 context->drawArrays(mode, first, count, 0); 2100 } 2101 } 2102 catch(std::bad_alloc&) 2103 { 2104 return gl::error(GL_OUT_OF_MEMORY); 2105 } 2106 } 2107 2108 void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount) 2109 { 2110 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount); 2111 2112 try 2113 { 2114 if (count < 0 || first < 0 || primcount < 0) 2115 { 2116 return gl::error(GL_INVALID_VALUE); 2117 } 2118 2119 if (primcount > 0) 2120 { 2121 gl::Context *context = gl::getNonLostContext(); 2122 2123 if (context) 2124 { 2125 context->drawArrays(mode, first, count, primcount); 2126 } 2127 } 2128 } 2129 catch(std::bad_alloc&) 2130 { 2131 return gl::error(GL_OUT_OF_MEMORY); 2132 } 2133 } 2134 2135 void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) 2136 { 2137 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)", 2138 mode, count, type, indices); 2139 2140 try 2141 { 2142 if (count < 0) 2143 { 2144 return gl::error(GL_INVALID_VALUE); 2145 } 2146 2147 gl::Context *context = gl::getNonLostContext(); 2148 2149 if (context) 2150 { 2151 switch (type) 2152 { 2153 case GL_UNSIGNED_BYTE: 2154 case GL_UNSIGNED_SHORT: 2155 break; 2156 case GL_UNSIGNED_INT: 2157 if (!context->supports32bitIndices()) 2158 { 2159 return gl::error(GL_INVALID_ENUM); 2160 } 2161 break; 2162 default: 2163 return gl::error(GL_INVALID_ENUM); 2164 } 2165 2166 context->drawElements(mode, count, type, indices, 0); 2167 } 2168 } 2169 catch(std::bad_alloc&) 2170 { 2171 return gl::error(GL_OUT_OF_MEMORY); 2172 } 2173 } 2174 2175 void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount) 2176 { 2177 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)", 2178 mode, count, type, indices, primcount); 2179 2180 try 2181 { 2182 if (count < 0 || primcount < 0) 2183 { 2184 return gl::error(GL_INVALID_VALUE); 2185 } 2186 2187 if (primcount > 0) 2188 { 2189 gl::Context *context = gl::getNonLostContext(); 2190 2191 if (context) 2192 { 2193 switch (type) 2194 { 2195 case GL_UNSIGNED_BYTE: 2196 case GL_UNSIGNED_SHORT: 2197 break; 2198 case GL_UNSIGNED_INT: 2199 if (!context->supports32bitIndices()) 2200 { 2201 return gl::error(GL_INVALID_ENUM); 2202 } 2203 break; 2204 default: 2205 return gl::error(GL_INVALID_ENUM); 2206 } 2207 2208 context->drawElements(mode, count, type, indices, primcount); 2209 } 2210 } 2211 } 2212 catch(std::bad_alloc&) 2213 { 2214 return gl::error(GL_OUT_OF_MEMORY); 2215 } 2216 } 2217 2218 void __stdcall glEnable(GLenum cap) 2219 { 2220 EVENT("(GLenum cap = 0x%X)", cap); 2221 2222 try 2223 { 2224 gl::Context *context = gl::getNonLostContext(); 2225 2226 if (context) 2227 { 2228 switch (cap) 2229 { 2230 case GL_CULL_FACE: context->setCullFace(true); break; 2231 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break; 2232 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break; 2233 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break; 2234 case GL_SCISSOR_TEST: context->setScissorTest(true); break; 2235 case GL_STENCIL_TEST: context->setStencilTest(true); break; 2236 case GL_DEPTH_TEST: context->setDepthTest(true); break; 2237 case GL_BLEND: context->setBlend(true); break; 2238 case GL_DITHER: context->setDither(true); break; 2239 default: 2240 return gl::error(GL_INVALID_ENUM); 2241 } 2242 } 2243 } 2244 catch(std::bad_alloc&) 2245 { 2246 return gl::error(GL_OUT_OF_MEMORY); 2247 } 2248 } 2249 2250 void __stdcall glEnableVertexAttribArray(GLuint index) 2251 { 2252 EVENT("(GLuint index = %d)", index); 2253 2254 try 2255 { 2256 if (index >= gl::MAX_VERTEX_ATTRIBS) 2257 { 2258 return gl::error(GL_INVALID_VALUE); 2259 } 2260 2261 gl::Context *context = gl::getNonLostContext(); 2262 2263 if (context) 2264 { 2265 context->setEnableVertexAttribArray(index, true); 2266 } 2267 } 2268 catch(std::bad_alloc&) 2269 { 2270 return gl::error(GL_OUT_OF_MEMORY); 2271 } 2272 } 2273 2274 void __stdcall glEndQueryEXT(GLenum target) 2275 { 2276 EVENT("GLenum target = 0x%X)", target); 2277 2278 try 2279 { 2280 switch (target) 2281 { 2282 case GL_ANY_SAMPLES_PASSED_EXT: 2283 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 2284 break; 2285 default: 2286 return gl::error(GL_INVALID_ENUM); 2287 } 2288 2289 gl::Context *context = gl::getNonLostContext(); 2290 2291 if (context) 2292 { 2293 context->endQuery(target); 2294 } 2295 } 2296 catch(std::bad_alloc&) 2297 { 2298 return gl::error(GL_OUT_OF_MEMORY); 2299 } 2300 } 2301 2302 void __stdcall glFinishFenceNV(GLuint fence) 2303 { 2304 EVENT("(GLuint fence = %d)", fence); 2305 2306 try 2307 { 2308 gl::Context *context = gl::getNonLostContext(); 2309 2310 if (context) 2311 { 2312 gl::Fence* fenceObject = context->getFence(fence); 2313 2314 if (fenceObject == NULL) 2315 { 2316 return gl::error(GL_INVALID_OPERATION); 2317 } 2318 2319 fenceObject->finishFence(); 2320 } 2321 } 2322 catch(std::bad_alloc&) 2323 { 2324 return gl::error(GL_OUT_OF_MEMORY); 2325 } 2326 } 2327 2328 void __stdcall glFinish(void) 2329 { 2330 EVENT("()"); 2331 2332 try 2333 { 2334 gl::Context *context = gl::getNonLostContext(); 2335 2336 if (context) 2337 { 2338 context->sync(true); 2339 } 2340 } 2341 catch(std::bad_alloc&) 2342 { 2343 return gl::error(GL_OUT_OF_MEMORY); 2344 } 2345 } 2346 2347 void __stdcall glFlush(void) 2348 { 2349 EVENT("()"); 2350 2351 try 2352 { 2353 gl::Context *context = gl::getNonLostContext(); 2354 2355 if (context) 2356 { 2357 context->sync(false); 2358 } 2359 } 2360 catch(std::bad_alloc&) 2361 { 2362 return gl::error(GL_OUT_OF_MEMORY); 2363 } 2364 } 2365 2366 void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) 2367 { 2368 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, " 2369 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer); 2370 2371 try 2372 { 2373 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) 2374 || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)) 2375 { 2376 return gl::error(GL_INVALID_ENUM); 2377 } 2378 2379 gl::Context *context = gl::getNonLostContext(); 2380 2381 if (context) 2382 { 2383 gl::Framebuffer *framebuffer = NULL; 2384 GLuint framebufferHandle = 0; 2385 if (target == GL_READ_FRAMEBUFFER_ANGLE) 2386 { 2387 framebuffer = context->getReadFramebuffer(); 2388 framebufferHandle = context->getReadFramebufferHandle(); 2389 } 2390 else 2391 { 2392 framebuffer = context->getDrawFramebuffer(); 2393 framebufferHandle = context->getDrawFramebufferHandle(); 2394 } 2395 2396 if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0)) 2397 { 2398 return gl::error(GL_INVALID_OPERATION); 2399 } 2400 2401 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) 2402 { 2403 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); 2404 2405 if (colorAttachment >= context->getMaximumRenderTargets()) 2406 { 2407 return gl::error(GL_INVALID_VALUE); 2408 } 2409 2410 framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer); 2411 } 2412 else 2413 { 2414 switch (attachment) 2415 { 2416 case GL_DEPTH_ATTACHMENT: 2417 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer); 2418 break; 2419 case GL_STENCIL_ATTACHMENT: 2420 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer); 2421 break; 2422 default: 2423 return gl::error(GL_INVALID_ENUM); 2424 } 2425 } 2426 } 2427 } 2428 catch(std::bad_alloc&) 2429 { 2430 return gl::error(GL_OUT_OF_MEMORY); 2431 } 2432 } 2433 2434 void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) 2435 { 2436 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " 2437 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level); 2438 2439 try 2440 { 2441 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) 2442 { 2443 return gl::error(GL_INVALID_ENUM); 2444 } 2445 2446 gl::Context *context = gl::getNonLostContext(); 2447 2448 if (context) 2449 { 2450 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) 2451 { 2452 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); 2453 2454 if (colorAttachment >= context->getMaximumRenderTargets()) 2455 { 2456 return gl::error(GL_INVALID_VALUE); 2457 } 2458 } 2459 else 2460 { 2461 switch (attachment) 2462 { 2463 case GL_DEPTH_ATTACHMENT: 2464 case GL_STENCIL_ATTACHMENT: 2465 break; 2466 default: 2467 return gl::error(GL_INVALID_ENUM); 2468 } 2469 } 2470 2471 if (texture == 0) 2472 { 2473 textarget = GL_NONE; 2474 } 2475 else 2476 { 2477 gl::Texture *tex = context->getTexture(texture); 2478 2479 if (tex == NULL) 2480 { 2481 return gl::error(GL_INVALID_OPERATION); 2482 } 2483 2484 switch (textarget) 2485 { 2486 case GL_TEXTURE_2D: 2487 { 2488 if (tex->getTarget() != GL_TEXTURE_2D) 2489 { 2490 return gl::error(GL_INVALID_OPERATION); 2491 } 2492 gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex); 2493 if (tex2d->isCompressed(0)) 2494 { 2495 return gl::error(GL_INVALID_OPERATION); 2496 } 2497 break; 2498 } 2499 2500 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 2501 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 2502 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2503 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 2504 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 2505 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 2506 { 2507 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP) 2508 { 2509 return gl::error(GL_INVALID_OPERATION); 2510 } 2511 gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex); 2512 if (texcube->isCompressed(textarget, level)) 2513 { 2514 return gl::error(GL_INVALID_OPERATION); 2515 } 2516 break; 2517 } 2518 2519 default: 2520 return gl::error(GL_INVALID_ENUM); 2521 } 2522 2523 if (level != 0) 2524 { 2525 return gl::error(GL_INVALID_VALUE); 2526 } 2527 } 2528 2529 gl::Framebuffer *framebuffer = NULL; 2530 GLuint framebufferHandle = 0; 2531 if (target == GL_READ_FRAMEBUFFER_ANGLE) 2532 { 2533 framebuffer = context->getReadFramebuffer(); 2534 framebufferHandle = context->getReadFramebufferHandle(); 2535 } 2536 else 2537 { 2538 framebuffer = context->getDrawFramebuffer(); 2539 framebufferHandle = context->getDrawFramebufferHandle(); 2540 } 2541 2542 if (framebufferHandle == 0 || !framebuffer) 2543 { 2544 return gl::error(GL_INVALID_OPERATION); 2545 } 2546 2547 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) 2548 { 2549 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); 2550 2551 if (colorAttachment >= context->getMaximumRenderTargets()) 2552 { 2553 return gl::error(GL_INVALID_VALUE); 2554 } 2555 2556 framebuffer->setColorbuffer(colorAttachment, textarget, texture); 2557 } 2558 else 2559 { 2560 switch (attachment) 2561 { 2562 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break; 2563 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break; 2564 } 2565 } 2566 } 2567 } 2568 catch(std::bad_alloc&) 2569 { 2570 return gl::error(GL_OUT_OF_MEMORY); 2571 } 2572 } 2573 2574 void __stdcall glFrontFace(GLenum mode) 2575 { 2576 EVENT("(GLenum mode = 0x%X)", mode); 2577 2578 try 2579 { 2580 switch (mode) 2581 { 2582 case GL_CW: 2583 case GL_CCW: 2584 { 2585 gl::Context *context = gl::getNonLostContext(); 2586 2587 if (context) 2588 { 2589 context->setFrontFace(mode); 2590 } 2591 } 2592 break; 2593 default: 2594 return gl::error(GL_INVALID_ENUM); 2595 } 2596 } 2597 catch(std::bad_alloc&) 2598 { 2599 return gl::error(GL_OUT_OF_MEMORY); 2600 } 2601 } 2602 2603 void __stdcall glGenBuffers(GLsizei n, GLuint* buffers) 2604 { 2605 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers); 2606 2607 try 2608 { 2609 if (n < 0) 2610 { 2611 return gl::error(GL_INVALID_VALUE); 2612 } 2613 2614 gl::Context *context = gl::getNonLostContext(); 2615 2616 if (context) 2617 { 2618 for (int i = 0; i < n; i++) 2619 { 2620 buffers[i] = context->createBuffer(); 2621 } 2622 } 2623 } 2624 catch(std::bad_alloc&) 2625 { 2626 return gl::error(GL_OUT_OF_MEMORY); 2627 } 2628 } 2629 2630 void __stdcall glGenerateMipmap(GLenum target) 2631 { 2632 EVENT("(GLenum target = 0x%X)", target); 2633 2634 try 2635 { 2636 gl::Context *context = gl::getNonLostContext(); 2637 2638 if (context) 2639 { 2640 switch (target) 2641 { 2642 case GL_TEXTURE_2D: 2643 { 2644 gl::Texture2D *tex2d = context->getTexture2D(); 2645 2646 if (tex2d->isCompressed(0)) 2647 { 2648 return gl::error(GL_INVALID_OPERATION); 2649 } 2650 if (tex2d->isDepth(0)) 2651 { 2652 return gl::error(GL_INVALID_OPERATION); 2653 } 2654 2655 tex2d->generateMipmaps(); 2656 break; 2657 } 2658 2659 case GL_TEXTURE_CUBE_MAP: 2660 { 2661 gl::TextureCubeMap *texcube = context->getTextureCubeMap(); 2662 2663 if (texcube->isCompressed(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)) 2664 { 2665 return gl::error(GL_INVALID_OPERATION); 2666 } 2667 2668 texcube->generateMipmaps(); 2669 break; 2670 } 2671 2672 default: 2673 return gl::error(GL_INVALID_ENUM); 2674 } 2675 } 2676 } 2677 catch(std::bad_alloc&) 2678 { 2679 return gl::error(GL_OUT_OF_MEMORY); 2680 } 2681 } 2682 2683 void __stdcall glGenFencesNV(GLsizei n, GLuint* fences) 2684 { 2685 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences); 2686 2687 try 2688 { 2689 if (n < 0) 2690 { 2691 return gl::error(GL_INVALID_VALUE); 2692 } 2693 2694 gl::Context *context = gl::getNonLostContext(); 2695 2696 if (context) 2697 { 2698 for (int i = 0; i < n; i++) 2699 { 2700 fences[i] = context->createFence(); 2701 } 2702 } 2703 } 2704 catch(std::bad_alloc&) 2705 { 2706 return gl::error(GL_OUT_OF_MEMORY); 2707 } 2708 } 2709 2710 void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers) 2711 { 2712 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers); 2713 2714 try 2715 { 2716 if (n < 0) 2717 { 2718 return gl::error(GL_INVALID_VALUE); 2719 } 2720 2721 gl::Context *context = gl::getNonLostContext(); 2722 2723 if (context) 2724 { 2725 for (int i = 0; i < n; i++) 2726 { 2727 framebuffers[i] = context->createFramebuffer(); 2728 } 2729 } 2730 } 2731 catch(std::bad_alloc&) 2732 { 2733 return gl::error(GL_OUT_OF_MEMORY); 2734 } 2735 } 2736 2737 void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids) 2738 { 2739 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); 2740 2741 try 2742 { 2743 if (n < 0) 2744 { 2745 return gl::error(GL_INVALID_VALUE); 2746 } 2747 2748 gl::Context *context = gl::getNonLostContext(); 2749 2750 if (context) 2751 { 2752 for (int i = 0; i < n; i++) 2753 { 2754 ids[i] = context->createQuery(); 2755 } 2756 } 2757 } 2758 catch(std::bad_alloc&) 2759 { 2760 return gl::error(GL_OUT_OF_MEMORY); 2761 } 2762 } 2763 2764 void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) 2765 { 2766 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); 2767 2768 try 2769 { 2770 if (n < 0) 2771 { 2772 return gl::error(GL_INVALID_VALUE); 2773 } 2774 2775 gl::Context *context = gl::getNonLostContext(); 2776 2777 if (context) 2778 { 2779 for (int i = 0; i < n; i++) 2780 { 2781 renderbuffers[i] = context->createRenderbuffer(); 2782 } 2783 } 2784 } 2785 catch(std::bad_alloc&) 2786 { 2787 return gl::error(GL_OUT_OF_MEMORY); 2788 } 2789 } 2790 2791 void __stdcall glGenTextures(GLsizei n, GLuint* textures) 2792 { 2793 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures); 2794 2795 try 2796 { 2797 if (n < 0) 2798 { 2799 return gl::error(GL_INVALID_VALUE); 2800 } 2801 2802 gl::Context *context = gl::getNonLostContext(); 2803 2804 if (context) 2805 { 2806 for (int i = 0; i < n; i++) 2807 { 2808 textures[i] = context->createTexture(); 2809 } 2810 } 2811 } 2812 catch(std::bad_alloc&) 2813 { 2814 return gl::error(GL_OUT_OF_MEMORY); 2815 } 2816 } 2817 2818 void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) 2819 { 2820 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, " 2821 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)", 2822 program, index, bufsize, length, size, type, name); 2823 2824 try 2825 { 2826 if (bufsize < 0) 2827 { 2828 return gl::error(GL_INVALID_VALUE); 2829 } 2830 2831 gl::Context *context = gl::getNonLostContext(); 2832 2833 if (context) 2834 { 2835 gl::Program *programObject = context->getProgram(program); 2836 2837 if (!programObject) 2838 { 2839 if (context->getShader(program)) 2840 { 2841 return gl::error(GL_INVALID_OPERATION); 2842 } 2843 else 2844 { 2845 return gl::error(GL_INVALID_VALUE); 2846 } 2847 } 2848 2849 if (index >= (GLuint)programObject->getActiveAttributeCount()) 2850 { 2851 return gl::error(GL_INVALID_VALUE); 2852 } 2853 2854 programObject->getActiveAttribute(index, bufsize, length, size, type, name); 2855 } 2856 } 2857 catch(std::bad_alloc&) 2858 { 2859 return gl::error(GL_OUT_OF_MEMORY); 2860 } 2861 } 2862 2863 void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) 2864 { 2865 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, " 2866 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", 2867 program, index, bufsize, length, size, type, name); 2868 2869 try 2870 { 2871 if (bufsize < 0) 2872 { 2873 return gl::error(GL_INVALID_VALUE); 2874 } 2875 2876 gl::Context *context = gl::getNonLostContext(); 2877 2878 if (context) 2879 { 2880 gl::Program *programObject = context->getProgram(program); 2881 2882 if (!programObject) 2883 { 2884 if (context->getShader(program)) 2885 { 2886 return gl::error(GL_INVALID_OPERATION); 2887 } 2888 else 2889 { 2890 return gl::error(GL_INVALID_VALUE); 2891 } 2892 } 2893 2894 if (index >= (GLuint)programObject->getActiveUniformCount()) 2895 { 2896 return gl::error(GL_INVALID_VALUE); 2897 } 2898 2899 programObject->getActiveUniform(index, bufsize, length, size, type, name); 2900 } 2901 } 2902 catch(std::bad_alloc&) 2903 { 2904 return gl::error(GL_OUT_OF_MEMORY); 2905 } 2906 } 2907 2908 void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) 2909 { 2910 EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)", 2911 program, maxcount, count, shaders); 2912 2913 try 2914 { 2915 if (maxcount < 0) 2916 { 2917 return gl::error(GL_INVALID_VALUE); 2918 } 2919 2920 gl::Context *context = gl::getNonLostContext(); 2921 2922 if (context) 2923 { 2924 gl::Program *programObject = context->getProgram(program); 2925 2926 if (!programObject) 2927 { 2928 if (context->getShader(program)) 2929 { 2930 return gl::error(GL_INVALID_OPERATION); 2931 } 2932 else 2933 { 2934 return gl::error(GL_INVALID_VALUE); 2935 } 2936 } 2937 2938 return programObject->getAttachedShaders(maxcount, count, shaders); 2939 } 2940 } 2941 catch(std::bad_alloc&) 2942 { 2943 return gl::error(GL_OUT_OF_MEMORY); 2944 } 2945 } 2946 2947 int __stdcall glGetAttribLocation(GLuint program, const GLchar* name) 2948 { 2949 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name); 2950 2951 try 2952 { 2953 gl::Context *context = gl::getNonLostContext(); 2954 2955 if (context) 2956 { 2957 2958 gl::Program *programObject = context->getProgram(program); 2959 2960 if (!programObject) 2961 { 2962 if (context->getShader(program)) 2963 { 2964 return gl::error(GL_INVALID_OPERATION, -1); 2965 } 2966 else 2967 { 2968 return gl::error(GL_INVALID_VALUE, -1); 2969 } 2970 } 2971 2972 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 2973 if (!programObject->isLinked() || !programBinary) 2974 { 2975 return gl::error(GL_INVALID_OPERATION, -1); 2976 } 2977 2978 return programBinary->getAttributeLocation(name); 2979 } 2980 } 2981 catch(std::bad_alloc&) 2982 { 2983 return gl::error(GL_OUT_OF_MEMORY, -1); 2984 } 2985 2986 return -1; 2987 } 2988 2989 void __stdcall glGetBooleanv(GLenum pname, GLboolean* params) 2990 { 2991 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params); 2992 2993 try 2994 { 2995 gl::Context *context = gl::getNonLostContext(); 2996 2997 if (context) 2998 { 2999 if (!(context->getBooleanv(pname, params))) 3000 { 3001 GLenum nativeType; 3002 unsigned int numParams = 0; 3003 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams)) 3004 return gl::error(GL_INVALID_ENUM); 3005 3006 if (numParams == 0) 3007 return; // it is known that the pname is valid, but there are no parameters to return 3008 3009 if (nativeType == GL_FLOAT) 3010 { 3011 GLfloat *floatParams = NULL; 3012 floatParams = new GLfloat[numParams]; 3013 3014 context->getFloatv(pname, floatParams); 3015 3016 for (unsigned int i = 0; i < numParams; ++i) 3017 { 3018 if (floatParams[i] == 0.0f) 3019 params[i] = GL_FALSE; 3020 else 3021 params[i] = GL_TRUE; 3022 } 3023 3024 delete [] floatParams; 3025 } 3026 else if (nativeType == GL_INT) 3027 { 3028 GLint *intParams = NULL; 3029 intParams = new GLint[numParams]; 3030 3031 context->getIntegerv(pname, intParams); 3032 3033 for (unsigned int i = 0; i < numParams; ++i) 3034 { 3035 if (intParams[i] == 0) 3036 params[i] = GL_FALSE; 3037 else 3038 params[i] = GL_TRUE; 3039 } 3040 3041 delete [] intParams; 3042 } 3043 } 3044 } 3045 } 3046 catch(std::bad_alloc&) 3047 { 3048 return gl::error(GL_OUT_OF_MEMORY); 3049 } 3050 } 3051 3052 void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) 3053 { 3054 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); 3055 3056 try 3057 { 3058 gl::Context *context = gl::getNonLostContext(); 3059 3060 if (context) 3061 { 3062 gl::Buffer *buffer; 3063 3064 switch (target) 3065 { 3066 case GL_ARRAY_BUFFER: 3067 buffer = context->getArrayBuffer(); 3068 break; 3069 case GL_ELEMENT_ARRAY_BUFFER: 3070 buffer = context->getElementArrayBuffer(); 3071 break; 3072 default: return gl::error(GL_INVALID_ENUM); 3073 } 3074 3075 if (!buffer) 3076 { 3077 // A null buffer means that "0" is bound to the requested buffer target 3078 return gl::error(GL_INVALID_OPERATION); 3079 } 3080 3081 switch (pname) 3082 { 3083 case GL_BUFFER_USAGE: 3084 *params = buffer->usage(); 3085 break; 3086 case GL_BUFFER_SIZE: 3087 *params = buffer->size(); 3088 break; 3089 default: return gl::error(GL_INVALID_ENUM); 3090 } 3091 } 3092 } 3093 catch(std::bad_alloc&) 3094 { 3095 return gl::error(GL_OUT_OF_MEMORY); 3096 } 3097 } 3098 3099 GLenum __stdcall glGetError(void) 3100 { 3101 EVENT("()"); 3102 3103 gl::Context *context = gl::getContext(); 3104 3105 if (context) 3106 { 3107 return context->getError(); 3108 } 3109 3110 return GL_NO_ERROR; 3111 } 3112 3113 void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) 3114 { 3115 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params); 3116 3117 try 3118 { 3119 3120 gl::Context *context = gl::getNonLostContext(); 3121 3122 if (context) 3123 { 3124 gl::Fence *fenceObject = context->getFence(fence); 3125 3126 if (fenceObject == NULL) 3127 { 3128 return gl::error(GL_INVALID_OPERATION); 3129 } 3130 3131 fenceObject->getFenceiv(pname, params); 3132 } 3133 } 3134 catch(std::bad_alloc&) 3135 { 3136 return gl::error(GL_OUT_OF_MEMORY); 3137 } 3138 } 3139 3140 void __stdcall glGetFloatv(GLenum pname, GLfloat* params) 3141 { 3142 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params); 3143 3144 try 3145 { 3146 gl::Context *context = gl::getNonLostContext(); 3147 3148 if (context) 3149 { 3150 if (!(context->getFloatv(pname, params))) 3151 { 3152 GLenum nativeType; 3153 unsigned int numParams = 0; 3154 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams)) 3155 return gl::error(GL_INVALID_ENUM); 3156 3157 if (numParams == 0) 3158 return; // it is known that the pname is valid, but that there are no parameters to return. 3159 3160 if (nativeType == GL_BOOL) 3161 { 3162 GLboolean *boolParams = NULL; 3163 boolParams = new GLboolean[numParams]; 3164 3165 context->getBooleanv(pname, boolParams); 3166 3167 for (unsigned int i = 0; i < numParams; ++i) 3168 { 3169 if (boolParams[i] == GL_FALSE) 3170 params[i] = 0.0f; 3171 else 3172 params[i] = 1.0f; 3173 } 3174 3175 delete [] boolParams; 3176 } 3177 else if (nativeType == GL_INT) 3178 { 3179 GLint *intParams = NULL; 3180 intParams = new GLint[numParams]; 3181 3182 context->getIntegerv(pname, intParams); 3183 3184 for (unsigned int i = 0; i < numParams; ++i) 3185 { 3186 params[i] = (GLfloat)intParams[i]; 3187 } 3188 3189 delete [] intParams; 3190 } 3191 } 3192 } 3193 } 3194 catch(std::bad_alloc&) 3195 { 3196 return gl::error(GL_OUT_OF_MEMORY); 3197 } 3198 } 3199 3200 void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) 3201 { 3202 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", 3203 target, attachment, pname, params); 3204 3205 try 3206 { 3207 gl::Context *context = gl::getNonLostContext(); 3208 3209 if (context) 3210 { 3211 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) 3212 { 3213 return gl::error(GL_INVALID_ENUM); 3214 } 3215 3216 gl::Framebuffer *framebuffer = NULL; 3217 if (target == GL_READ_FRAMEBUFFER_ANGLE) 3218 { 3219 if(context->getReadFramebufferHandle() == 0) 3220 { 3221 return gl::error(GL_INVALID_OPERATION); 3222 } 3223 3224 framebuffer = context->getReadFramebuffer(); 3225 } 3226 else 3227 { 3228 if (context->getDrawFramebufferHandle() == 0) 3229 { 3230 return gl::error(GL_INVALID_OPERATION); 3231 } 3232 3233 framebuffer = context->getDrawFramebuffer(); 3234 } 3235 3236 GLenum attachmentType; 3237 GLuint attachmentHandle; 3238 3239 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) 3240 { 3241 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); 3242 3243 if (colorAttachment >= context->getMaximumRenderTargets()) 3244 { 3245 return gl::error(GL_INVALID_ENUM); 3246 } 3247 3248 attachmentType = framebuffer->getColorbufferType(colorAttachment); 3249 attachmentHandle = framebuffer->getColorbufferHandle(colorAttachment); 3250 } 3251 else 3252 { 3253 switch (attachment) 3254 { 3255 case GL_DEPTH_ATTACHMENT: 3256 attachmentType = framebuffer->getDepthbufferType(); 3257 attachmentHandle = framebuffer->getDepthbufferHandle(); 3258 break; 3259 case GL_STENCIL_ATTACHMENT: 3260 attachmentType = framebuffer->getStencilbufferType(); 3261 attachmentHandle = framebuffer->getStencilbufferHandle(); 3262 break; 3263 default: return gl::error(GL_INVALID_ENUM); 3264 } 3265 } 3266 3267 GLenum attachmentObjectType; // Type category 3268 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER) 3269 { 3270 attachmentObjectType = attachmentType; 3271 } 3272 else if (gl::IsInternalTextureTarget(attachmentType)) 3273 { 3274 attachmentObjectType = GL_TEXTURE; 3275 } 3276 else 3277 { 3278 UNREACHABLE(); 3279 return; 3280 } 3281 3282 switch (pname) 3283 { 3284 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 3285 *params = attachmentObjectType; 3286 break; 3287 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 3288 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE) 3289 { 3290 *params = attachmentHandle; 3291 } 3292 else 3293 { 3294 return gl::error(GL_INVALID_ENUM); 3295 } 3296 break; 3297 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 3298 if (attachmentObjectType == GL_TEXTURE) 3299 { 3300 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0 3301 } 3302 else 3303 { 3304 return gl::error(GL_INVALID_ENUM); 3305 } 3306 break; 3307 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 3308 if (attachmentObjectType == GL_TEXTURE) 3309 { 3310 if (gl::IsCubemapTextureTarget(attachmentType)) 3311 { 3312 *params = attachmentType; 3313 } 3314 else 3315 { 3316 *params = 0; 3317 } 3318 } 3319 else 3320 { 3321 return gl::error(GL_INVALID_ENUM); 3322 } 3323 break; 3324 default: 3325 return gl::error(GL_INVALID_ENUM); 3326 } 3327 } 3328 } 3329 catch(std::bad_alloc&) 3330 { 3331 return gl::error(GL_OUT_OF_MEMORY); 3332 } 3333 } 3334 3335 GLenum __stdcall glGetGraphicsResetStatusEXT(void) 3336 { 3337 EVENT("()"); 3338 3339 try 3340 { 3341 gl::Context *context = gl::getContext(); 3342 3343 if (context) 3344 { 3345 return context->getResetStatus(); 3346 } 3347 3348 return GL_NO_ERROR; 3349 } 3350 catch(std::bad_alloc&) 3351 { 3352 return GL_OUT_OF_MEMORY; 3353 } 3354 } 3355 3356 void __stdcall glGetIntegerv(GLenum pname, GLint* params) 3357 { 3358 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params); 3359 3360 try 3361 { 3362 gl::Context *context = gl::getNonLostContext(); 3363 3364 if (context) 3365 { 3366 if (!(context->getIntegerv(pname, params))) 3367 { 3368 GLenum nativeType; 3369 unsigned int numParams = 0; 3370 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams)) 3371 return gl::error(GL_INVALID_ENUM); 3372 3373 if (numParams == 0) 3374 return; // it is known that pname is valid, but there are no parameters to return 3375 3376 if (nativeType == GL_BOOL) 3377 { 3378 GLboolean *boolParams = NULL; 3379 boolParams = new GLboolean[numParams]; 3380 3381 context->getBooleanv(pname, boolParams); 3382 3383 for (unsigned int i = 0; i < numParams; ++i) 3384 { 3385 if (boolParams[i] == GL_FALSE) 3386 params[i] = 0; 3387 else 3388 params[i] = 1; 3389 } 3390 3391 delete [] boolParams; 3392 } 3393 else if (nativeType == GL_FLOAT) 3394 { 3395 GLfloat *floatParams = NULL; 3396 floatParams = new GLfloat[numParams]; 3397 3398 context->getFloatv(pname, floatParams); 3399 3400 for (unsigned int i = 0; i < numParams; ++i) 3401 { 3402 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR) 3403 { 3404 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f); 3405 } 3406 else 3407 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5)); 3408 } 3409 3410 delete [] floatParams; 3411 } 3412 } 3413 } 3414 } 3415 catch(std::bad_alloc&) 3416 { 3417 return gl::error(GL_OUT_OF_MEMORY); 3418 } 3419 } 3420 3421 void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) 3422 { 3423 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params); 3424 3425 try 3426 { 3427 gl::Context *context = gl::getNonLostContext(); 3428 3429 if (context) 3430 { 3431 gl::Program *programObject = context->getProgram(program); 3432 3433 if (!programObject) 3434 { 3435 return gl::error(GL_INVALID_VALUE); 3436 } 3437 3438 switch (pname) 3439 { 3440 case GL_DELETE_STATUS: 3441 *params = programObject->isFlaggedForDeletion(); 3442 return; 3443 case GL_LINK_STATUS: 3444 *params = programObject->isLinked(); 3445 return; 3446 case GL_VALIDATE_STATUS: 3447 *params = programObject->isValidated(); 3448 return; 3449 case GL_INFO_LOG_LENGTH: 3450 *params = programObject->getInfoLogLength(); 3451 return; 3452 case GL_ATTACHED_SHADERS: 3453 *params = programObject->getAttachedShadersCount(); 3454 return; 3455 case GL_ACTIVE_ATTRIBUTES: 3456 *params = programObject->getActiveAttributeCount(); 3457 return; 3458 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: 3459 *params = programObject->getActiveAttributeMaxLength(); 3460 return; 3461 case GL_ACTIVE_UNIFORMS: 3462 *params = programObject->getActiveUniformCount(); 3463 return; 3464 case GL_ACTIVE_UNIFORM_MAX_LENGTH: 3465 *params = programObject->getActiveUniformMaxLength(); 3466 return; 3467 case GL_PROGRAM_BINARY_LENGTH_OES: 3468 *params = programObject->getProgramBinaryLength(); 3469 return; 3470 default: 3471 return gl::error(GL_INVALID_ENUM); 3472 } 3473 } 3474 } 3475 catch(std::bad_alloc&) 3476 { 3477 return gl::error(GL_OUT_OF_MEMORY); 3478 } 3479 } 3480 3481 void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) 3482 { 3483 EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", 3484 program, bufsize, length, infolog); 3485 3486 try 3487 { 3488 if (bufsize < 0) 3489 { 3490 return gl::error(GL_INVALID_VALUE); 3491 } 3492 3493 gl::Context *context = gl::getNonLostContext(); 3494 3495 if (context) 3496 { 3497 gl::Program *programObject = context->getProgram(program); 3498 3499 if (!programObject) 3500 { 3501 return gl::error(GL_INVALID_VALUE); 3502 } 3503 3504 programObject->getInfoLog(bufsize, length, infolog); 3505 } 3506 } 3507 catch(std::bad_alloc&) 3508 { 3509 return gl::error(GL_OUT_OF_MEMORY); 3510 } 3511 } 3512 3513 void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) 3514 { 3515 EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params); 3516 3517 try 3518 { 3519 switch (pname) 3520 { 3521 case GL_CURRENT_QUERY_EXT: 3522 break; 3523 default: 3524 return gl::error(GL_INVALID_ENUM); 3525 } 3526 3527 gl::Context *context = gl::getNonLostContext(); 3528 3529 if (context) 3530 { 3531 params[0] = context->getActiveQuery(target); 3532 } 3533 } 3534 catch(std::bad_alloc&) 3535 { 3536 return gl::error(GL_OUT_OF_MEMORY); 3537 } 3538 } 3539 3540 void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) 3541 { 3542 EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params); 3543 3544 try 3545 { 3546 switch (pname) 3547 { 3548 case GL_QUERY_RESULT_EXT: 3549 case GL_QUERY_RESULT_AVAILABLE_EXT: 3550 break; 3551 default: 3552 return gl::error(GL_INVALID_ENUM); 3553 } 3554 gl::Context *context = gl::getNonLostContext(); 3555 3556 if (context) 3557 { 3558 gl::Query *queryObject = context->getQuery(id, false, GL_NONE); 3559 3560 if (!queryObject) 3561 { 3562 return gl::error(GL_INVALID_OPERATION); 3563 } 3564 3565 if (context->getActiveQuery(queryObject->getType()) == id) 3566 { 3567 return gl::error(GL_INVALID_OPERATION); 3568 } 3569 3570 switch(pname) 3571 { 3572 case GL_QUERY_RESULT_EXT: 3573 params[0] = queryObject->getResult(); 3574 break; 3575 case GL_QUERY_RESULT_AVAILABLE_EXT: 3576 params[0] = queryObject->isResultAvailable(); 3577 break; 3578 default: 3579 ASSERT(false); 3580 } 3581 } 3582 } 3583 catch(std::bad_alloc&) 3584 { 3585 return gl::error(GL_OUT_OF_MEMORY); 3586 } 3587 } 3588 3589 void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) 3590 { 3591 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); 3592 3593 try 3594 { 3595 gl::Context *context = gl::getNonLostContext(); 3596 3597 if (context) 3598 { 3599 if (target != GL_RENDERBUFFER) 3600 { 3601 return gl::error(GL_INVALID_ENUM); 3602 } 3603 3604 if (context->getRenderbufferHandle() == 0) 3605 { 3606 return gl::error(GL_INVALID_OPERATION); 3607 } 3608 3609 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle()); 3610 3611 switch (pname) 3612 { 3613 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break; 3614 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break; 3615 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break; 3616 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break; 3617 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break; 3618 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break; 3619 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break; 3620 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break; 3621 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break; 3622 case GL_RENDERBUFFER_SAMPLES_ANGLE: 3623 if (context->getMaxSupportedSamples() != 0) 3624 { 3625 *params = renderbuffer->getSamples(); 3626 } 3627 else 3628 { 3629 return gl::error(GL_INVALID_ENUM); 3630 } 3631 break; 3632 default: 3633 return gl::error(GL_INVALID_ENUM); 3634 } 3635 } 3636 } 3637 catch(std::bad_alloc&) 3638 { 3639 return gl::error(GL_OUT_OF_MEMORY); 3640 } 3641 } 3642 3643 void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) 3644 { 3645 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params); 3646 3647 try 3648 { 3649 gl::Context *context = gl::getNonLostContext(); 3650 3651 if (context) 3652 { 3653 gl::Shader *shaderObject = context->getShader(shader); 3654 3655 if (!shaderObject) 3656 { 3657 return gl::error(GL_INVALID_VALUE); 3658 } 3659 3660 switch (pname) 3661 { 3662 case GL_SHADER_TYPE: 3663 *params = shaderObject->getType(); 3664 return; 3665 case GL_DELETE_STATUS: 3666 *params = shaderObject->isFlaggedForDeletion(); 3667 return; 3668 case GL_COMPILE_STATUS: 3669 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE; 3670 return; 3671 case GL_INFO_LOG_LENGTH: 3672 *params = shaderObject->getInfoLogLength(); 3673 return; 3674 case GL_SHADER_SOURCE_LENGTH: 3675 *params = shaderObject->getSourceLength(); 3676 return; 3677 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: 3678 *params = shaderObject->getTranslatedSourceLength(); 3679 return; 3680 default: 3681 return gl::error(GL_INVALID_ENUM); 3682 } 3683 } 3684 } 3685 catch(std::bad_alloc&) 3686 { 3687 return gl::error(GL_OUT_OF_MEMORY); 3688 } 3689 } 3690 3691 void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) 3692 { 3693 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", 3694 shader, bufsize, length, infolog); 3695 3696 try 3697 { 3698 if (bufsize < 0) 3699 { 3700 return gl::error(GL_INVALID_VALUE); 3701 } 3702 3703 gl::Context *context = gl::getNonLostContext(); 3704 3705 if (context) 3706 { 3707 gl::Shader *shaderObject = context->getShader(shader); 3708 3709 if (!shaderObject) 3710 { 3711 return gl::error(GL_INVALID_VALUE); 3712 } 3713 3714 shaderObject->getInfoLog(bufsize, length, infolog); 3715 } 3716 } 3717 catch(std::bad_alloc&) 3718 { 3719 return gl::error(GL_OUT_OF_MEMORY); 3720 } 3721 } 3722 3723 void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) 3724 { 3725 EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)", 3726 shadertype, precisiontype, range, precision); 3727 3728 try 3729 { 3730 switch (shadertype) 3731 { 3732 case GL_VERTEX_SHADER: 3733 case GL_FRAGMENT_SHADER: 3734 break; 3735 default: 3736 return gl::error(GL_INVALID_ENUM); 3737 } 3738 3739 switch (precisiontype) 3740 { 3741 case GL_LOW_FLOAT: 3742 case GL_MEDIUM_FLOAT: 3743 case GL_HIGH_FLOAT: 3744 // Assume IEEE 754 precision 3745 range[0] = 127; 3746 range[1] = 127; 3747 *precision = 23; 3748 break; 3749 case GL_LOW_INT: 3750 case GL_MEDIUM_INT: 3751 case GL_HIGH_INT: 3752 // Some (most) hardware only supports single-precision floating-point numbers, 3753 // which can accurately represent integers up to +/-16777216 3754 range[0] = 24; 3755 range[1] = 24; 3756 *precision = 0; 3757 break; 3758 default: 3759 return gl::error(GL_INVALID_ENUM); 3760 } 3761 } 3762 catch(std::bad_alloc&) 3763 { 3764 return gl::error(GL_OUT_OF_MEMORY); 3765 } 3766 } 3767 3768 void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) 3769 { 3770 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", 3771 shader, bufsize, length, source); 3772 3773 try 3774 { 3775 if (bufsize < 0) 3776 { 3777 return gl::error(GL_INVALID_VALUE); 3778 } 3779 3780 gl::Context *context = gl::getNonLostContext(); 3781 3782 if (context) 3783 { 3784 gl::Shader *shaderObject = context->getShader(shader); 3785 3786 if (!shaderObject) 3787 { 3788 return gl::error(GL_INVALID_OPERATION); 3789 } 3790 3791 shaderObject->getSource(bufsize, length, source); 3792 } 3793 } 3794 catch(std::bad_alloc&) 3795 { 3796 return gl::error(GL_OUT_OF_MEMORY); 3797 } 3798 } 3799 3800 void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) 3801 { 3802 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", 3803 shader, bufsize, length, source); 3804 3805 try 3806 { 3807 if (bufsize < 0) 3808 { 3809 return gl::error(GL_INVALID_VALUE); 3810 } 3811 3812 gl::Context *context = gl::getNonLostContext(); 3813 3814 if (context) 3815 { 3816 gl::Shader *shaderObject = context->getShader(shader); 3817 3818 if (!shaderObject) 3819 { 3820 return gl::error(GL_INVALID_OPERATION); 3821 } 3822 3823 shaderObject->getTranslatedSource(bufsize, length, source); 3824 } 3825 } 3826 catch(std::bad_alloc&) 3827 { 3828 return gl::error(GL_OUT_OF_MEMORY); 3829 } 3830 } 3831 3832 const GLubyte* __stdcall glGetString(GLenum name) 3833 { 3834 EVENT("(GLenum name = 0x%X)", name); 3835 3836 try 3837 { 3838 gl::Context *context = gl::getNonLostContext(); 3839 3840 switch (name) 3841 { 3842 case GL_VENDOR: 3843 return (GLubyte*)"Google Inc."; 3844 case GL_RENDERER: 3845 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE"); 3846 case GL_VERSION: 3847 return (GLubyte*)"OpenGL ES 2.0 (ANGLE " VERSION_STRING ")"; 3848 case GL_SHADING_LANGUAGE_VERSION: 3849 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " VERSION_STRING ")"; 3850 case GL_EXTENSIONS: 3851 return (GLubyte*)((context != NULL) ? context->getExtensionString() : ""); 3852 default: 3853 return gl::error(GL_INVALID_ENUM, (GLubyte*)NULL); 3854 } 3855 } 3856 catch(std::bad_alloc&) 3857 { 3858 return gl::error(GL_OUT_OF_MEMORY, (GLubyte*)NULL); 3859 } 3860 } 3861 3862 void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) 3863 { 3864 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params); 3865 3866 try 3867 { 3868 gl::Context *context = gl::getNonLostContext(); 3869 3870 if (context) 3871 { 3872 gl::Texture *texture; 3873 3874 switch (target) 3875 { 3876 case GL_TEXTURE_2D: 3877 texture = context->getTexture2D(); 3878 break; 3879 case GL_TEXTURE_CUBE_MAP: 3880 texture = context->getTextureCubeMap(); 3881 break; 3882 default: 3883 return gl::error(GL_INVALID_ENUM); 3884 } 3885 3886 switch (pname) 3887 { 3888 case GL_TEXTURE_MAG_FILTER: 3889 *params = (GLfloat)texture->getMagFilter(); 3890 break; 3891 case GL_TEXTURE_MIN_FILTER: 3892 *params = (GLfloat)texture->getMinFilter(); 3893 break; 3894 case GL_TEXTURE_WRAP_S: 3895 *params = (GLfloat)texture->getWrapS(); 3896 break; 3897 case GL_TEXTURE_WRAP_T: 3898 *params = (GLfloat)texture->getWrapT(); 3899 break; 3900 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT: 3901 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE); 3902 break; 3903 case GL_TEXTURE_USAGE_ANGLE: 3904 *params = (GLfloat)texture->getUsage(); 3905 break; 3906 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 3907 if (!context->supportsTextureFilterAnisotropy()) 3908 { 3909 return gl::error(GL_INVALID_ENUM); 3910 } 3911 *params = (GLfloat)texture->getMaxAnisotropy(); 3912 break; 3913 default: 3914 return gl::error(GL_INVALID_ENUM); 3915 } 3916 } 3917 } 3918 catch(std::bad_alloc&) 3919 { 3920 return gl::error(GL_OUT_OF_MEMORY); 3921 } 3922 } 3923 3924 void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) 3925 { 3926 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); 3927 3928 try 3929 { 3930 gl::Context *context = gl::getNonLostContext(); 3931 3932 if (context) 3933 { 3934 gl::Texture *texture; 3935 3936 switch (target) 3937 { 3938 case GL_TEXTURE_2D: 3939 texture = context->getTexture2D(); 3940 break; 3941 case GL_TEXTURE_CUBE_MAP: 3942 texture = context->getTextureCubeMap(); 3943 break; 3944 default: 3945 return gl::error(GL_INVALID_ENUM); 3946 } 3947 3948 switch (pname) 3949 { 3950 case GL_TEXTURE_MAG_FILTER: 3951 *params = texture->getMagFilter(); 3952 break; 3953 case GL_TEXTURE_MIN_FILTER: 3954 *params = texture->getMinFilter(); 3955 break; 3956 case GL_TEXTURE_WRAP_S: 3957 *params = texture->getWrapS(); 3958 break; 3959 case GL_TEXTURE_WRAP_T: 3960 *params = texture->getWrapT(); 3961 break; 3962 case GL_TEXTURE_IMMUTABLE_FORMAT_EXT: 3963 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE; 3964 break; 3965 case GL_TEXTURE_USAGE_ANGLE: 3966 *params = texture->getUsage(); 3967 break; 3968 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 3969 if (!context->supportsTextureFilterAnisotropy()) 3970 { 3971 return gl::error(GL_INVALID_ENUM); 3972 } 3973 *params = (GLint)texture->getMaxAnisotropy(); 3974 break; 3975 default: 3976 return gl::error(GL_INVALID_ENUM); 3977 } 3978 } 3979 } 3980 catch(std::bad_alloc&) 3981 { 3982 return gl::error(GL_OUT_OF_MEMORY); 3983 } 3984 } 3985 3986 void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) 3987 { 3988 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)", 3989 program, location, bufSize, params); 3990 3991 try 3992 { 3993 if (bufSize < 0) 3994 { 3995 return gl::error(GL_INVALID_VALUE); 3996 } 3997 3998 gl::Context *context = gl::getNonLostContext(); 3999 4000 if (context) 4001 { 4002 if (program == 0) 4003 { 4004 return gl::error(GL_INVALID_VALUE); 4005 } 4006 4007 gl::Program *programObject = context->getProgram(program); 4008 4009 if (!programObject || !programObject->isLinked()) 4010 { 4011 return gl::error(GL_INVALID_OPERATION); 4012 } 4013 4014 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 4015 if (!programBinary) 4016 { 4017 return gl::error(GL_INVALID_OPERATION); 4018 } 4019 4020 if (!programBinary->getUniformfv(location, &bufSize, params)) 4021 { 4022 return gl::error(GL_INVALID_OPERATION); 4023 } 4024 } 4025 } 4026 catch(std::bad_alloc&) 4027 { 4028 return gl::error(GL_OUT_OF_MEMORY); 4029 } 4030 } 4031 4032 void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) 4033 { 4034 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params); 4035 4036 try 4037 { 4038 gl::Context *context = gl::getNonLostContext(); 4039 4040 if (context) 4041 { 4042 if (program == 0) 4043 { 4044 return gl::error(GL_INVALID_VALUE); 4045 } 4046 4047 gl::Program *programObject = context->getProgram(program); 4048 4049 if (!programObject || !programObject->isLinked()) 4050 { 4051 return gl::error(GL_INVALID_OPERATION); 4052 } 4053 4054 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 4055 if (!programBinary) 4056 { 4057 return gl::error(GL_INVALID_OPERATION); 4058 } 4059 4060 if (!programBinary->getUniformfv(location, NULL, params)) 4061 { 4062 return gl::error(GL_INVALID_OPERATION); 4063 } 4064 } 4065 } 4066 catch(std::bad_alloc&) 4067 { 4068 return gl::error(GL_OUT_OF_MEMORY); 4069 } 4070 } 4071 4072 void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params) 4073 { 4074 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)", 4075 program, location, bufSize, params); 4076 4077 try 4078 { 4079 if (bufSize < 0) 4080 { 4081 return gl::error(GL_INVALID_VALUE); 4082 } 4083 4084 gl::Context *context = gl::getNonLostContext(); 4085 4086 if (context) 4087 { 4088 if (program == 0) 4089 { 4090 return gl::error(GL_INVALID_VALUE); 4091 } 4092 4093 gl::Program *programObject = context->getProgram(program); 4094 4095 if (!programObject || !programObject->isLinked()) 4096 { 4097 return gl::error(GL_INVALID_OPERATION); 4098 } 4099 4100 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 4101 if (!programBinary) 4102 { 4103 return gl::error(GL_INVALID_OPERATION); 4104 } 4105 4106 if (!programBinary->getUniformiv(location, &bufSize, params)) 4107 { 4108 return gl::error(GL_INVALID_OPERATION); 4109 } 4110 } 4111 } 4112 catch(std::bad_alloc&) 4113 { 4114 return gl::error(GL_OUT_OF_MEMORY); 4115 } 4116 } 4117 4118 void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) 4119 { 4120 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params); 4121 4122 try 4123 { 4124 gl::Context *context = gl::getNonLostContext(); 4125 4126 if (context) 4127 { 4128 if (program == 0) 4129 { 4130 return gl::error(GL_INVALID_VALUE); 4131 } 4132 4133 gl::Program *programObject = context->getProgram(program); 4134 4135 if (!programObject || !programObject->isLinked()) 4136 { 4137 return gl::error(GL_INVALID_OPERATION); 4138 } 4139 4140 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 4141 if (!programBinary) 4142 { 4143 return gl::error(GL_INVALID_OPERATION); 4144 } 4145 4146 if (!programBinary->getUniformiv(location, NULL, params)) 4147 { 4148 return gl::error(GL_INVALID_OPERATION); 4149 } 4150 } 4151 } 4152 catch(std::bad_alloc&) 4153 { 4154 return gl::error(GL_OUT_OF_MEMORY); 4155 } 4156 } 4157 4158 int __stdcall glGetUniformLocation(GLuint program, const GLchar* name) 4159 { 4160 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name); 4161 4162 try 4163 { 4164 gl::Context *context = gl::getNonLostContext(); 4165 4166 if (strstr(name, "gl_") == name) 4167 { 4168 return -1; 4169 } 4170 4171 if (context) 4172 { 4173 gl::Program *programObject = context->getProgram(program); 4174 4175 if (!programObject) 4176 { 4177 if (context->getShader(program)) 4178 { 4179 return gl::error(GL_INVALID_OPERATION, -1); 4180 } 4181 else 4182 { 4183 return gl::error(GL_INVALID_VALUE, -1); 4184 } 4185 } 4186 4187 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 4188 if (!programObject->isLinked() || !programBinary) 4189 { 4190 return gl::error(GL_INVALID_OPERATION, -1); 4191 } 4192 4193 return programBinary->getUniformLocation(name); 4194 } 4195 } 4196 catch(std::bad_alloc&) 4197 { 4198 return gl::error(GL_OUT_OF_MEMORY, -1); 4199 } 4200 4201 return -1; 4202 } 4203 4204 void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) 4205 { 4206 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params); 4207 4208 try 4209 { 4210 gl::Context *context = gl::getNonLostContext(); 4211 4212 if (context) 4213 { 4214 if (index >= gl::MAX_VERTEX_ATTRIBS) 4215 { 4216 return gl::error(GL_INVALID_VALUE); 4217 } 4218 4219 const gl::VertexAttribute &attribState = context->getVertexAttribState(index); 4220 4221 switch (pname) 4222 { 4223 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 4224 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE); 4225 break; 4226 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 4227 *params = (GLfloat)attribState.mSize; 4228 break; 4229 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 4230 *params = (GLfloat)attribState.mStride; 4231 break; 4232 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 4233 *params = (GLfloat)attribState.mType; 4234 break; 4235 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 4236 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE); 4237 break; 4238 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 4239 *params = (GLfloat)attribState.mBoundBuffer.id(); 4240 break; 4241 case GL_CURRENT_VERTEX_ATTRIB: 4242 for (int i = 0; i < 4; ++i) 4243 { 4244 params[i] = attribState.mCurrentValue[i]; 4245 } 4246 break; 4247 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: 4248 *params = (GLfloat)attribState.mDivisor; 4249 break; 4250 default: return gl::error(GL_INVALID_ENUM); 4251 } 4252 } 4253 } 4254 catch(std::bad_alloc&) 4255 { 4256 return gl::error(GL_OUT_OF_MEMORY); 4257 } 4258 } 4259 4260 void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) 4261 { 4262 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params); 4263 4264 try 4265 { 4266 gl::Context *context = gl::getNonLostContext(); 4267 4268 if (context) 4269 { 4270 if (index >= gl::MAX_VERTEX_ATTRIBS) 4271 { 4272 return gl::error(GL_INVALID_VALUE); 4273 } 4274 4275 const gl::VertexAttribute &attribState = context->getVertexAttribState(index); 4276 4277 switch (pname) 4278 { 4279 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 4280 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE); 4281 break; 4282 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 4283 *params = attribState.mSize; 4284 break; 4285 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 4286 *params = attribState.mStride; 4287 break; 4288 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 4289 *params = attribState.mType; 4290 break; 4291 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 4292 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE); 4293 break; 4294 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 4295 *params = attribState.mBoundBuffer.id(); 4296 break; 4297 case GL_CURRENT_VERTEX_ATTRIB: 4298 for (int i = 0; i < 4; ++i) 4299 { 4300 float currentValue = attribState.mCurrentValue[i]; 4301 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f)); 4302 } 4303 break; 4304 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: 4305 *params = (GLint)attribState.mDivisor; 4306 break; 4307 default: return gl::error(GL_INVALID_ENUM); 4308 } 4309 } 4310 } 4311 catch(std::bad_alloc&) 4312 { 4313 return gl::error(GL_OUT_OF_MEMORY); 4314 } 4315 } 4316 4317 void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) 4318 { 4319 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer); 4320 4321 try 4322 { 4323 gl::Context *context = gl::getNonLostContext(); 4324 4325 if (context) 4326 { 4327 if (index >= gl::MAX_VERTEX_ATTRIBS) 4328 { 4329 return gl::error(GL_INVALID_VALUE); 4330 } 4331 4332 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) 4333 { 4334 return gl::error(GL_INVALID_ENUM); 4335 } 4336 4337 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index)); 4338 } 4339 } 4340 catch(std::bad_alloc&) 4341 { 4342 return gl::error(GL_OUT_OF_MEMORY); 4343 } 4344 } 4345 4346 void __stdcall glHint(GLenum target, GLenum mode) 4347 { 4348 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); 4349 4350 try 4351 { 4352 switch (mode) 4353 { 4354 case GL_FASTEST: 4355 case GL_NICEST: 4356 case GL_DONT_CARE: 4357 break; 4358 default: 4359 return gl::error(GL_INVALID_ENUM); 4360 } 4361 4362 gl::Context *context = gl::getNonLostContext(); 4363 switch (target) 4364 { 4365 case GL_GENERATE_MIPMAP_HINT: 4366 if (context) context->setGenerateMipmapHint(mode); 4367 break; 4368 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 4369 if (context) context->setFragmentShaderDerivativeHint(mode); 4370 break; 4371 default: 4372 return gl::error(GL_INVALID_ENUM); 4373 } 4374 } 4375 catch(std::bad_alloc&) 4376 { 4377 return gl::error(GL_OUT_OF_MEMORY); 4378 } 4379 } 4380 4381 GLboolean __stdcall glIsBuffer(GLuint buffer) 4382 { 4383 EVENT("(GLuint buffer = %d)", buffer); 4384 4385 try 4386 { 4387 gl::Context *context = gl::getNonLostContext(); 4388 4389 if (context && buffer) 4390 { 4391 gl::Buffer *bufferObject = context->getBuffer(buffer); 4392 4393 if (bufferObject) 4394 { 4395 return GL_TRUE; 4396 } 4397 } 4398 } 4399 catch(std::bad_alloc&) 4400 { 4401 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4402 } 4403 4404 return GL_FALSE; 4405 } 4406 4407 GLboolean __stdcall glIsEnabled(GLenum cap) 4408 { 4409 EVENT("(GLenum cap = 0x%X)", cap); 4410 4411 try 4412 { 4413 gl::Context *context = gl::getNonLostContext(); 4414 4415 if (context) 4416 { 4417 switch (cap) 4418 { 4419 case GL_CULL_FACE: return context->isCullFaceEnabled(); 4420 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled(); 4421 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); 4422 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled(); 4423 case GL_SCISSOR_TEST: return context->isScissorTestEnabled(); 4424 case GL_STENCIL_TEST: return context->isStencilTestEnabled(); 4425 case GL_DEPTH_TEST: return context->isDepthTestEnabled(); 4426 case GL_BLEND: return context->isBlendEnabled(); 4427 case GL_DITHER: return context->isDitherEnabled(); 4428 default: 4429 return gl::error(GL_INVALID_ENUM, false); 4430 } 4431 } 4432 } 4433 catch(std::bad_alloc&) 4434 { 4435 return gl::error(GL_OUT_OF_MEMORY, false); 4436 } 4437 4438 return false; 4439 } 4440 4441 GLboolean __stdcall glIsFenceNV(GLuint fence) 4442 { 4443 EVENT("(GLuint fence = %d)", fence); 4444 4445 try 4446 { 4447 gl::Context *context = gl::getNonLostContext(); 4448 4449 if (context) 4450 { 4451 gl::Fence *fenceObject = context->getFence(fence); 4452 4453 if (fenceObject == NULL) 4454 { 4455 return GL_FALSE; 4456 } 4457 4458 return fenceObject->isFence(); 4459 } 4460 } 4461 catch(std::bad_alloc&) 4462 { 4463 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4464 } 4465 4466 return GL_FALSE; 4467 } 4468 4469 GLboolean __stdcall glIsFramebuffer(GLuint framebuffer) 4470 { 4471 EVENT("(GLuint framebuffer = %d)", framebuffer); 4472 4473 try 4474 { 4475 gl::Context *context = gl::getNonLostContext(); 4476 4477 if (context && framebuffer) 4478 { 4479 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer); 4480 4481 if (framebufferObject) 4482 { 4483 return GL_TRUE; 4484 } 4485 } 4486 } 4487 catch(std::bad_alloc&) 4488 { 4489 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4490 } 4491 4492 return GL_FALSE; 4493 } 4494 4495 GLboolean __stdcall glIsProgram(GLuint program) 4496 { 4497 EVENT("(GLuint program = %d)", program); 4498 4499 try 4500 { 4501 gl::Context *context = gl::getNonLostContext(); 4502 4503 if (context && program) 4504 { 4505 gl::Program *programObject = context->getProgram(program); 4506 4507 if (programObject) 4508 { 4509 return GL_TRUE; 4510 } 4511 } 4512 } 4513 catch(std::bad_alloc&) 4514 { 4515 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4516 } 4517 4518 return GL_FALSE; 4519 } 4520 4521 GLboolean __stdcall glIsQueryEXT(GLuint id) 4522 { 4523 EVENT("(GLuint id = %d)", id); 4524 4525 try 4526 { 4527 if (id == 0) 4528 { 4529 return GL_FALSE; 4530 } 4531 4532 gl::Context *context = gl::getNonLostContext(); 4533 4534 if (context) 4535 { 4536 gl::Query *queryObject = context->getQuery(id, false, GL_NONE); 4537 4538 if (queryObject) 4539 { 4540 return GL_TRUE; 4541 } 4542 } 4543 } 4544 catch(std::bad_alloc&) 4545 { 4546 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4547 } 4548 4549 return GL_FALSE; 4550 } 4551 4552 GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer) 4553 { 4554 EVENT("(GLuint renderbuffer = %d)", renderbuffer); 4555 4556 try 4557 { 4558 gl::Context *context = gl::getNonLostContext(); 4559 4560 if (context && renderbuffer) 4561 { 4562 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer); 4563 4564 if (renderbufferObject) 4565 { 4566 return GL_TRUE; 4567 } 4568 } 4569 } 4570 catch(std::bad_alloc&) 4571 { 4572 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4573 } 4574 4575 return GL_FALSE; 4576 } 4577 4578 GLboolean __stdcall glIsShader(GLuint shader) 4579 { 4580 EVENT("(GLuint shader = %d)", shader); 4581 4582 try 4583 { 4584 gl::Context *context = gl::getNonLostContext(); 4585 4586 if (context && shader) 4587 { 4588 gl::Shader *shaderObject = context->getShader(shader); 4589 4590 if (shaderObject) 4591 { 4592 return GL_TRUE; 4593 } 4594 } 4595 } 4596 catch(std::bad_alloc&) 4597 { 4598 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4599 } 4600 4601 return GL_FALSE; 4602 } 4603 4604 GLboolean __stdcall glIsTexture(GLuint texture) 4605 { 4606 EVENT("(GLuint texture = %d)", texture); 4607 4608 try 4609 { 4610 gl::Context *context = gl::getNonLostContext(); 4611 4612 if (context && texture) 4613 { 4614 gl::Texture *textureObject = context->getTexture(texture); 4615 4616 if (textureObject) 4617 { 4618 return GL_TRUE; 4619 } 4620 } 4621 } 4622 catch(std::bad_alloc&) 4623 { 4624 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4625 } 4626 4627 return GL_FALSE; 4628 } 4629 4630 void __stdcall glLineWidth(GLfloat width) 4631 { 4632 EVENT("(GLfloat width = %f)", width); 4633 4634 try 4635 { 4636 if (width <= 0.0f) 4637 { 4638 return gl::error(GL_INVALID_VALUE); 4639 } 4640 4641 gl::Context *context = gl::getNonLostContext(); 4642 4643 if (context) 4644 { 4645 context->setLineWidth(width); 4646 } 4647 } 4648 catch(std::bad_alloc&) 4649 { 4650 return gl::error(GL_OUT_OF_MEMORY); 4651 } 4652 } 4653 4654 void __stdcall glLinkProgram(GLuint program) 4655 { 4656 EVENT("(GLuint program = %d)", program); 4657 4658 try 4659 { 4660 gl::Context *context = gl::getNonLostContext(); 4661 4662 if (context) 4663 { 4664 gl::Program *programObject = context->getProgram(program); 4665 4666 if (!programObject) 4667 { 4668 if (context->getShader(program)) 4669 { 4670 return gl::error(GL_INVALID_OPERATION); 4671 } 4672 else 4673 { 4674 return gl::error(GL_INVALID_VALUE); 4675 } 4676 } 4677 4678 context->linkProgram(program); 4679 } 4680 } 4681 catch(std::bad_alloc&) 4682 { 4683 return gl::error(GL_OUT_OF_MEMORY); 4684 } 4685 } 4686 4687 void __stdcall glPixelStorei(GLenum pname, GLint param) 4688 { 4689 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param); 4690 4691 try 4692 { 4693 gl::Context *context = gl::getNonLostContext(); 4694 4695 if (context) 4696 { 4697 switch (pname) 4698 { 4699 case GL_UNPACK_ALIGNMENT: 4700 if (param != 1 && param != 2 && param != 4 && param != 8) 4701 { 4702 return gl::error(GL_INVALID_VALUE); 4703 } 4704 4705 context->setUnpackAlignment(param); 4706 break; 4707 4708 case GL_PACK_ALIGNMENT: 4709 if (param != 1 && param != 2 && param != 4 && param != 8) 4710 { 4711 return gl::error(GL_INVALID_VALUE); 4712 } 4713 4714 context->setPackAlignment(param); 4715 break; 4716 4717 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: 4718 context->setPackReverseRowOrder(param != 0); 4719 break; 4720 4721 default: 4722 return gl::error(GL_INVALID_ENUM); 4723 } 4724 } 4725 } 4726 catch(std::bad_alloc&) 4727 { 4728 return gl::error(GL_OUT_OF_MEMORY); 4729 } 4730 } 4731 4732 void __stdcall glPolygonOffset(GLfloat factor, GLfloat units) 4733 { 4734 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units); 4735 4736 try 4737 { 4738 gl::Context *context = gl::getNonLostContext(); 4739 4740 if (context) 4741 { 4742 context->setPolygonOffsetParams(factor, units); 4743 } 4744 } 4745 catch(std::bad_alloc&) 4746 { 4747 return gl::error(GL_OUT_OF_MEMORY); 4748 } 4749 } 4750 4751 void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, 4752 GLenum format, GLenum type, GLsizei bufSize, 4753 GLvoid *data) 4754 { 4755 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " 4756 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)", 4757 x, y, width, height, format, type, bufSize, data); 4758 4759 try 4760 { 4761 if (width < 0 || height < 0 || bufSize < 0) 4762 { 4763 return gl::error(GL_INVALID_VALUE); 4764 } 4765 4766 gl::Context *context = gl::getNonLostContext(); 4767 4768 if (context) 4769 { 4770 GLenum currentFormat, currentType; 4771 4772 // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound, 4773 // and attempting to read back if that's the case is an error. The error will be registered 4774 // by getCurrentReadFormat. 4775 if (!context->getCurrentReadFormatType(¤tFormat, ¤tType)) 4776 return; 4777 4778 if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type)) 4779 { 4780 return gl::error(GL_INVALID_OPERATION); 4781 } 4782 4783 context->readPixels(x, y, width, height, format, type, &bufSize, data); 4784 } 4785 } 4786 catch(std::bad_alloc&) 4787 { 4788 return gl::error(GL_OUT_OF_MEMORY); 4789 } 4790 } 4791 4792 void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, 4793 GLenum format, GLenum type, GLvoid* pixels) 4794 { 4795 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " 4796 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)", 4797 x, y, width, height, format, type, pixels); 4798 4799 try 4800 { 4801 if (width < 0 || height < 0) 4802 { 4803 return gl::error(GL_INVALID_VALUE); 4804 } 4805 4806 gl::Context *context = gl::getNonLostContext(); 4807 4808 if (context) 4809 { 4810 GLenum currentFormat, currentType; 4811 4812 // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound, 4813 // and attempting to read back if that's the case is an error. The error will be registered 4814 // by getCurrentReadFormat. 4815 if (!context->getCurrentReadFormatType(¤tFormat, ¤tType)) 4816 return; 4817 4818 if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type)) 4819 { 4820 return gl::error(GL_INVALID_OPERATION); 4821 } 4822 4823 context->readPixels(x, y, width, height, format, type, NULL, pixels); 4824 } 4825 } 4826 catch(std::bad_alloc&) 4827 { 4828 return gl::error(GL_OUT_OF_MEMORY); 4829 } 4830 } 4831 4832 void __stdcall glReleaseShaderCompiler(void) 4833 { 4834 EVENT("()"); 4835 4836 try 4837 { 4838 gl::Shader::releaseCompiler(); 4839 } 4840 catch(std::bad_alloc&) 4841 { 4842 return gl::error(GL_OUT_OF_MEMORY); 4843 } 4844 } 4845 4846 void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) 4847 { 4848 EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", 4849 target, samples, internalformat, width, height); 4850 4851 try 4852 { 4853 switch (target) 4854 { 4855 case GL_RENDERBUFFER: 4856 break; 4857 default: 4858 return gl::error(GL_INVALID_ENUM); 4859 } 4860 4861 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat)) 4862 { 4863 return gl::error(GL_INVALID_ENUM); 4864 } 4865 4866 if (width < 0 || height < 0 || samples < 0) 4867 { 4868 return gl::error(GL_INVALID_VALUE); 4869 } 4870 4871 gl::Context *context = gl::getNonLostContext(); 4872 4873 if (context) 4874 { 4875 if (width > context->getMaximumRenderbufferDimension() || 4876 height > context->getMaximumRenderbufferDimension() || 4877 samples > context->getMaxSupportedSamples()) 4878 { 4879 return gl::error(GL_INVALID_VALUE); 4880 } 4881 4882 GLuint handle = context->getRenderbufferHandle(); 4883 if (handle == 0) 4884 { 4885 return gl::error(GL_INVALID_OPERATION); 4886 } 4887 4888 switch (internalformat) 4889 { 4890 case GL_DEPTH_COMPONENT16: 4891 case GL_RGBA4: 4892 case GL_RGB5_A1: 4893 case GL_RGB565: 4894 case GL_RGB8_OES: 4895 case GL_RGBA8_OES: 4896 case GL_STENCIL_INDEX8: 4897 case GL_DEPTH24_STENCIL8_OES: 4898 context->setRenderbufferStorage(width, height, internalformat, samples); 4899 break; 4900 default: 4901 return gl::error(GL_INVALID_ENUM); 4902 } 4903 } 4904 } 4905 catch(std::bad_alloc&) 4906 { 4907 return gl::error(GL_OUT_OF_MEMORY); 4908 } 4909 } 4910 4911 void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) 4912 { 4913 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height); 4914 } 4915 4916 void __stdcall glSampleCoverage(GLclampf value, GLboolean invert) 4917 { 4918 EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert); 4919 4920 try 4921 { 4922 gl::Context* context = gl::getNonLostContext(); 4923 4924 if (context) 4925 { 4926 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE); 4927 } 4928 } 4929 catch(std::bad_alloc&) 4930 { 4931 return gl::error(GL_OUT_OF_MEMORY); 4932 } 4933 } 4934 4935 void __stdcall glSetFenceNV(GLuint fence, GLenum condition) 4936 { 4937 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition); 4938 4939 try 4940 { 4941 if (condition != GL_ALL_COMPLETED_NV) 4942 { 4943 return gl::error(GL_INVALID_ENUM); 4944 } 4945 4946 gl::Context *context = gl::getNonLostContext(); 4947 4948 if (context) 4949 { 4950 gl::Fence *fenceObject = context->getFence(fence); 4951 4952 if (fenceObject == NULL) 4953 { 4954 return gl::error(GL_INVALID_OPERATION); 4955 } 4956 4957 fenceObject->setFence(condition); 4958 } 4959 } 4960 catch(std::bad_alloc&) 4961 { 4962 return gl::error(GL_OUT_OF_MEMORY); 4963 } 4964 } 4965 4966 void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height) 4967 { 4968 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); 4969 4970 try 4971 { 4972 if (width < 0 || height < 0) 4973 { 4974 return gl::error(GL_INVALID_VALUE); 4975 } 4976 4977 gl::Context* context = gl::getNonLostContext(); 4978 4979 if (context) 4980 { 4981 context->setScissorParams(x, y, width, height); 4982 } 4983 } 4984 catch(std::bad_alloc&) 4985 { 4986 return gl::error(GL_OUT_OF_MEMORY); 4987 } 4988 } 4989 4990 void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) 4991 { 4992 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, " 4993 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", 4994 n, shaders, binaryformat, binary, length); 4995 4996 try 4997 { 4998 // No binary shader formats are supported. 4999 return gl::error(GL_INVALID_ENUM); 5000 } 5001 catch(std::bad_alloc&) 5002 { 5003 return gl::error(GL_OUT_OF_MEMORY); 5004 } 5005 } 5006 5007 void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) 5008 { 5009 EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)", 5010 shader, count, string, length); 5011 5012 try 5013 { 5014 if (count < 0) 5015 { 5016 return gl::error(GL_INVALID_VALUE); 5017 } 5018 5019 gl::Context *context = gl::getNonLostContext(); 5020 5021 if (context) 5022 { 5023 gl::Shader *shaderObject = context->getShader(shader); 5024 5025 if (!shaderObject) 5026 { 5027 if (context->getProgram(shader)) 5028 { 5029 return gl::error(GL_INVALID_OPERATION); 5030 } 5031 else 5032 { 5033 return gl::error(GL_INVALID_VALUE); 5034 } 5035 } 5036 5037 shaderObject->setSource(count, string, length); 5038 } 5039 } 5040 catch(std::bad_alloc&) 5041 { 5042 return gl::error(GL_OUT_OF_MEMORY); 5043 } 5044 } 5045 5046 void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask) 5047 { 5048 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); 5049 } 5050 5051 void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) 5052 { 5053 EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask); 5054 5055 try 5056 { 5057 switch (face) 5058 { 5059 case GL_FRONT: 5060 case GL_BACK: 5061 case GL_FRONT_AND_BACK: 5062 break; 5063 default: 5064 return gl::error(GL_INVALID_ENUM); 5065 } 5066 5067 switch (func) 5068 { 5069 case GL_NEVER: 5070 case GL_ALWAYS: 5071 case GL_LESS: 5072 case GL_LEQUAL: 5073 case GL_EQUAL: 5074 case GL_GEQUAL: 5075 case GL_GREATER: 5076 case GL_NOTEQUAL: 5077 break; 5078 default: 5079 return gl::error(GL_INVALID_ENUM); 5080 } 5081 5082 gl::Context *context = gl::getNonLostContext(); 5083 5084 if (context) 5085 { 5086 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) 5087 { 5088 context->setStencilParams(func, ref, mask); 5089 } 5090 5091 if (face == GL_BACK || face == GL_FRONT_AND_BACK) 5092 { 5093 context->setStencilBackParams(func, ref, mask); 5094 } 5095 } 5096 } 5097 catch(std::bad_alloc&) 5098 { 5099 return gl::error(GL_OUT_OF_MEMORY); 5100 } 5101 } 5102 5103 void __stdcall glStencilMask(GLuint mask) 5104 { 5105 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask); 5106 } 5107 5108 void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask) 5109 { 5110 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask); 5111 5112 try 5113 { 5114 switch (face) 5115 { 5116 case GL_FRONT: 5117 case GL_BACK: 5118 case GL_FRONT_AND_BACK: 5119 break; 5120 default: 5121 return gl::error(GL_INVALID_ENUM); 5122 } 5123 5124 gl::Context *context = gl::getNonLostContext(); 5125 5126 if (context) 5127 { 5128 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) 5129 { 5130 context->setStencilWritemask(mask); 5131 } 5132 5133 if (face == GL_BACK || face == GL_FRONT_AND_BACK) 5134 { 5135 context->setStencilBackWritemask(mask); 5136 } 5137 } 5138 } 5139 catch(std::bad_alloc&) 5140 { 5141 return gl::error(GL_OUT_OF_MEMORY); 5142 } 5143 } 5144 5145 void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) 5146 { 5147 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass); 5148 } 5149 5150 void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) 5151 { 5152 EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", 5153 face, fail, zfail, zpass); 5154 5155 try 5156 { 5157 switch (face) 5158 { 5159 case GL_FRONT: 5160 case GL_BACK: 5161 case GL_FRONT_AND_BACK: 5162 break; 5163 default: 5164 return gl::error(GL_INVALID_ENUM); 5165 } 5166 5167 switch (fail) 5168 { 5169 case GL_ZERO: 5170 case GL_KEEP: 5171 case GL_REPLACE: 5172 case GL_INCR: 5173 case GL_DECR: 5174 case GL_INVERT: 5175 case GL_INCR_WRAP: 5176 case GL_DECR_WRAP: 5177 break; 5178 default: 5179 return gl::error(GL_INVALID_ENUM); 5180 } 5181 5182 switch (zfail) 5183 { 5184 case GL_ZERO: 5185 case GL_KEEP: 5186 case GL_REPLACE: 5187 case GL_INCR: 5188 case GL_DECR: 5189 case GL_INVERT: 5190 case GL_INCR_WRAP: 5191 case GL_DECR_WRAP: 5192 break; 5193 default: 5194 return gl::error(GL_INVALID_ENUM); 5195 } 5196 5197 switch (zpass) 5198 { 5199 case GL_ZERO: 5200 case GL_KEEP: 5201 case GL_REPLACE: 5202 case GL_INCR: 5203 case GL_DECR: 5204 case GL_INVERT: 5205 case GL_INCR_WRAP: 5206 case GL_DECR_WRAP: 5207 break; 5208 default: 5209 return gl::error(GL_INVALID_ENUM); 5210 } 5211 5212 gl::Context *context = gl::getNonLostContext(); 5213 5214 if (context) 5215 { 5216 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) 5217 { 5218 context->setStencilOperations(fail, zfail, zpass); 5219 } 5220 5221 if (face == GL_BACK || face == GL_FRONT_AND_BACK) 5222 { 5223 context->setStencilBackOperations(fail, zfail, zpass); 5224 } 5225 } 5226 } 5227 catch(std::bad_alloc&) 5228 { 5229 return gl::error(GL_OUT_OF_MEMORY); 5230 } 5231 } 5232 5233 GLboolean __stdcall glTestFenceNV(GLuint fence) 5234 { 5235 EVENT("(GLuint fence = %d)", fence); 5236 5237 try 5238 { 5239 gl::Context *context = gl::getNonLostContext(); 5240 5241 if (context) 5242 { 5243 gl::Fence *fenceObject = context->getFence(fence); 5244 5245 if (fenceObject == NULL) 5246 { 5247 return gl::error(GL_INVALID_OPERATION, GL_TRUE); 5248 } 5249 5250 return fenceObject->testFence(); 5251 } 5252 } 5253 catch(std::bad_alloc&) 5254 { 5255 gl::error(GL_OUT_OF_MEMORY); 5256 } 5257 5258 return GL_TRUE; 5259 } 5260 5261 void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, 5262 GLint border, GLenum format, GLenum type, const GLvoid* pixels) 5263 { 5264 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " 5265 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", 5266 target, level, internalformat, width, height, border, format, type, pixels); 5267 5268 try 5269 { 5270 if (!validImageSize(level, width, height)) 5271 { 5272 return gl::error(GL_INVALID_VALUE); 5273 } 5274 5275 if (internalformat != GLint(format)) 5276 { 5277 return gl::error(GL_INVALID_OPERATION); 5278 } 5279 5280 // validate <type> by itself (used as secondary key below) 5281 switch (type) 5282 { 5283 case GL_UNSIGNED_BYTE: 5284 case GL_UNSIGNED_SHORT_5_6_5: 5285 case GL_UNSIGNED_SHORT_4_4_4_4: 5286 case GL_UNSIGNED_SHORT_5_5_5_1: 5287 case GL_UNSIGNED_SHORT: 5288 case GL_UNSIGNED_INT: 5289 case GL_UNSIGNED_INT_24_8_OES: 5290 case GL_HALF_FLOAT_OES: 5291 case GL_FLOAT: 5292 break; 5293 default: 5294 return gl::error(GL_INVALID_ENUM); 5295 } 5296 5297 // validate <format> + <type> combinations 5298 // - invalid <format> -> sets INVALID_ENUM 5299 // - invalid <format>+<type> combination -> sets INVALID_OPERATION 5300 switch (format) 5301 { 5302 case GL_ALPHA: 5303 case GL_LUMINANCE: 5304 case GL_LUMINANCE_ALPHA: 5305 switch (type) 5306 { 5307 case GL_UNSIGNED_BYTE: 5308 case GL_FLOAT: 5309 case GL_HALF_FLOAT_OES: 5310 break; 5311 default: 5312 return gl::error(GL_INVALID_OPERATION); 5313 } 5314 break; 5315 case GL_RGB: 5316 switch (type) 5317 { 5318 case GL_UNSIGNED_BYTE: 5319 case GL_UNSIGNED_SHORT_5_6_5: 5320 case GL_FLOAT: 5321 case GL_HALF_FLOAT_OES: 5322 break; 5323 default: 5324 return gl::error(GL_INVALID_OPERATION); 5325 } 5326 break; 5327 case GL_RGBA: 5328 switch (type) 5329 { 5330 case GL_UNSIGNED_BYTE: 5331 case GL_UNSIGNED_SHORT_4_4_4_4: 5332 case GL_UNSIGNED_SHORT_5_5_5_1: 5333 case GL_FLOAT: 5334 case GL_HALF_FLOAT_OES: 5335 break; 5336 default: 5337 return gl::error(GL_INVALID_OPERATION); 5338 } 5339 break; 5340 case GL_BGRA_EXT: 5341 switch (type) 5342 { 5343 case GL_UNSIGNED_BYTE: 5344 break; 5345 default: 5346 return gl::error(GL_INVALID_OPERATION); 5347 } 5348 break; 5349 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below 5350 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 5351 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: 5352 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: 5353 break; 5354 case GL_DEPTH_COMPONENT: 5355 switch (type) 5356 { 5357 case GL_UNSIGNED_SHORT: 5358 case GL_UNSIGNED_INT: 5359 break; 5360 default: 5361 return gl::error(GL_INVALID_OPERATION); 5362 } 5363 break; 5364 case GL_DEPTH_STENCIL_OES: 5365 switch (type) 5366 { 5367 case GL_UNSIGNED_INT_24_8_OES: 5368 break; 5369 default: 5370 return gl::error(GL_INVALID_OPERATION); 5371 } 5372 break; 5373 default: 5374 return gl::error(GL_INVALID_ENUM); 5375 } 5376 5377 if (border != 0) 5378 { 5379 return gl::error(GL_INVALID_VALUE); 5380 } 5381 5382 gl::Context *context = gl::getNonLostContext(); 5383 5384 if (context) 5385 { 5386 if (level > context->getMaximumTextureLevel()) 5387 { 5388 return gl::error(GL_INVALID_VALUE); 5389 } 5390 5391 switch (target) 5392 { 5393 case GL_TEXTURE_2D: 5394 if (width > (context->getMaximumTextureDimension() >> level) || 5395 height > (context->getMaximumTextureDimension() >> level)) 5396 { 5397 return gl::error(GL_INVALID_VALUE); 5398 } 5399 break; 5400 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 5401 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 5402 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 5403 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 5404 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 5405 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 5406 if (width != height) 5407 { 5408 return gl::error(GL_INVALID_VALUE); 5409 } 5410 5411 if (width > (context->getMaximumCubeTextureDimension() >> level) || 5412 height > (context->getMaximumCubeTextureDimension() >> level)) 5413 { 5414 return gl::error(GL_INVALID_VALUE); 5415 } 5416 break; 5417 default: 5418 return gl::error(GL_INVALID_ENUM); 5419 } 5420 5421 switch (format) { 5422 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 5423 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 5424 if (context->supportsDXT1Textures()) 5425 { 5426 return gl::error(GL_INVALID_OPERATION); 5427 } 5428 else 5429 { 5430 return gl::error(GL_INVALID_ENUM); 5431 } 5432 break; 5433 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: 5434 if (context->supportsDXT3Textures()) 5435 { 5436 return gl::error(GL_INVALID_OPERATION); 5437 } 5438 else 5439 { 5440 return gl::error(GL_INVALID_ENUM); 5441 } 5442 break; 5443 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: 5444 if (context->supportsDXT5Textures()) 5445 { 5446 return gl::error(GL_INVALID_OPERATION); 5447 } 5448 else 5449 { 5450 return gl::error(GL_INVALID_ENUM); 5451 } 5452 break; 5453 case GL_DEPTH_COMPONENT: 5454 case GL_DEPTH_STENCIL_OES: 5455 if (!context->supportsDepthTextures()) 5456 { 5457 return gl::error(GL_INVALID_VALUE); 5458 } 5459 if (target != GL_TEXTURE_2D) 5460 { 5461 return gl::error(GL_INVALID_OPERATION); 5462 } 5463 // OES_depth_texture supports loading depth data and multiple levels, 5464 // but ANGLE_depth_texture does not 5465 if (pixels != NULL || level != 0) 5466 { 5467 return gl::error(GL_INVALID_OPERATION); 5468 } 5469 break; 5470 default: 5471 break; 5472 } 5473 5474 if (type == GL_FLOAT) 5475 { 5476 if (!context->supportsFloat32Textures()) 5477 { 5478 return gl::error(GL_INVALID_ENUM); 5479 } 5480 } 5481 else if (type == GL_HALF_FLOAT_OES) 5482 { 5483 if (!context->supportsFloat16Textures()) 5484 { 5485 return gl::error(GL_INVALID_ENUM); 5486 } 5487 } 5488 5489 if (target == GL_TEXTURE_2D) 5490 { 5491 gl::Texture2D *texture = context->getTexture2D(); 5492 5493 if (!texture) 5494 { 5495 return gl::error(GL_INVALID_OPERATION); 5496 } 5497 5498 if (texture->isImmutable()) 5499 { 5500 return gl::error(GL_INVALID_OPERATION); 5501 } 5502 5503 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels); 5504 } 5505 else 5506 { 5507 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 5508 5509 if (!texture) 5510 { 5511 return gl::error(GL_INVALID_OPERATION); 5512 } 5513 5514 if (texture->isImmutable()) 5515 { 5516 return gl::error(GL_INVALID_OPERATION); 5517 } 5518 5519 switch (target) 5520 { 5521 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 5522 texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels); 5523 break; 5524 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 5525 texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels); 5526 break; 5527 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 5528 texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels); 5529 break; 5530 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 5531 texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels); 5532 break; 5533 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 5534 texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels); 5535 break; 5536 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 5537 texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels); 5538 break; 5539 default: UNREACHABLE(); 5540 } 5541 } 5542 } 5543 } 5544 catch(std::bad_alloc&) 5545 { 5546 return gl::error(GL_OUT_OF_MEMORY); 5547 } 5548 } 5549 5550 void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param) 5551 { 5552 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param); 5553 5554 try 5555 { 5556 gl::Context *context = gl::getNonLostContext(); 5557 5558 if (context) 5559 { 5560 gl::Texture *texture; 5561 5562 switch (target) 5563 { 5564 case GL_TEXTURE_2D: 5565 texture = context->getTexture2D(); 5566 break; 5567 case GL_TEXTURE_CUBE_MAP: 5568 texture = context->getTextureCubeMap(); 5569 break; 5570 default: 5571 return gl::error(GL_INVALID_ENUM); 5572 } 5573 5574 switch (pname) 5575 { 5576 case GL_TEXTURE_WRAP_S: 5577 if (!texture->setWrapS((GLenum)param)) 5578 { 5579 return gl::error(GL_INVALID_ENUM); 5580 } 5581 break; 5582 case GL_TEXTURE_WRAP_T: 5583 if (!texture->setWrapT((GLenum)param)) 5584 { 5585 return gl::error(GL_INVALID_ENUM); 5586 } 5587 break; 5588 case GL_TEXTURE_MIN_FILTER: 5589 if (!texture->setMinFilter((GLenum)param)) 5590 { 5591 return gl::error(GL_INVALID_ENUM); 5592 } 5593 break; 5594 case GL_TEXTURE_MAG_FILTER: 5595 if (!texture->setMagFilter((GLenum)param)) 5596 { 5597 return gl::error(GL_INVALID_ENUM); 5598 } 5599 break; 5600 case GL_TEXTURE_USAGE_ANGLE: 5601 if (!texture->setUsage((GLenum)param)) 5602 { 5603 return gl::error(GL_INVALID_ENUM); 5604 } 5605 break; 5606 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 5607 if (!context->supportsTextureFilterAnisotropy()) 5608 { 5609 return gl::error(GL_INVALID_ENUM); 5610 } 5611 if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy())) 5612 { 5613 return gl::error(GL_INVALID_VALUE); 5614 } 5615 break; 5616 default: 5617 return gl::error(GL_INVALID_ENUM); 5618 } 5619 } 5620 } 5621 catch(std::bad_alloc&) 5622 { 5623 return gl::error(GL_OUT_OF_MEMORY); 5624 } 5625 } 5626 5627 void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) 5628 { 5629 glTexParameterf(target, pname, (GLfloat)*params); 5630 } 5631 5632 void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) 5633 { 5634 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); 5635 5636 try 5637 { 5638 gl::Context *context = gl::getNonLostContext(); 5639 5640 if (context) 5641 { 5642 gl::Texture *texture; 5643 5644 switch (target) 5645 { 5646 case GL_TEXTURE_2D: 5647 texture = context->getTexture2D(); 5648 break; 5649 case GL_TEXTURE_CUBE_MAP: 5650 texture = context->getTextureCubeMap(); 5651 break; 5652 default: 5653 return gl::error(GL_INVALID_ENUM); 5654 } 5655 5656 switch (pname) 5657 { 5658 case GL_TEXTURE_WRAP_S: 5659 if (!texture->setWrapS((GLenum)param)) 5660 { 5661 return gl::error(GL_INVALID_ENUM); 5662 } 5663 break; 5664 case GL_TEXTURE_WRAP_T: 5665 if (!texture->setWrapT((GLenum)param)) 5666 { 5667 return gl::error(GL_INVALID_ENUM); 5668 } 5669 break; 5670 case GL_TEXTURE_MIN_FILTER: 5671 if (!texture->setMinFilter((GLenum)param)) 5672 { 5673 return gl::error(GL_INVALID_ENUM); 5674 } 5675 break; 5676 case GL_TEXTURE_MAG_FILTER: 5677 if (!texture->setMagFilter((GLenum)param)) 5678 { 5679 return gl::error(GL_INVALID_ENUM); 5680 } 5681 break; 5682 case GL_TEXTURE_USAGE_ANGLE: 5683 if (!texture->setUsage((GLenum)param)) 5684 { 5685 return gl::error(GL_INVALID_ENUM); 5686 } 5687 break; 5688 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 5689 if (!context->supportsTextureFilterAnisotropy()) 5690 { 5691 return gl::error(GL_INVALID_ENUM); 5692 } 5693 if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy())) 5694 { 5695 return gl::error(GL_INVALID_VALUE); 5696 } 5697 break; 5698 default: 5699 return gl::error(GL_INVALID_ENUM); 5700 } 5701 } 5702 } 5703 catch(std::bad_alloc&) 5704 { 5705 return gl::error(GL_OUT_OF_MEMORY); 5706 } 5707 } 5708 5709 void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params) 5710 { 5711 glTexParameteri(target, pname, *params); 5712 } 5713 5714 void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) 5715 { 5716 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", 5717 target, levels, internalformat, width, height); 5718 5719 try 5720 { 5721 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) 5722 { 5723 return gl::error(GL_INVALID_ENUM); 5724 } 5725 5726 if (width < 1 || height < 1 || levels < 1) 5727 { 5728 return gl::error(GL_INVALID_VALUE); 5729 } 5730 5731 if (target == GL_TEXTURE_CUBE_MAP && width != height) 5732 { 5733 return gl::error(GL_INVALID_VALUE); 5734 } 5735 5736 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1) 5737 { 5738 return gl::error(GL_INVALID_OPERATION); 5739 } 5740 5741 GLenum format = gl::ExtractFormat(internalformat); 5742 GLenum type = gl::ExtractType(internalformat); 5743 5744 if (format == GL_NONE || type == GL_NONE) 5745 { 5746 return gl::error(GL_INVALID_ENUM); 5747 } 5748 5749 gl::Context *context = gl::getNonLostContext(); 5750 5751 if (context) 5752 { 5753 switch (target) 5754 { 5755 case GL_TEXTURE_2D: 5756 if (width > context->getMaximumTextureDimension() || 5757 height > context->getMaximumTextureDimension()) 5758 { 5759 return gl::error(GL_INVALID_VALUE); 5760 } 5761 break; 5762 case GL_TEXTURE_CUBE_MAP: 5763 if (width > context->getMaximumCubeTextureDimension() || 5764 height > context->getMaximumCubeTextureDimension()) 5765 { 5766 return gl::error(GL_INVALID_VALUE); 5767 } 5768 break; 5769 default: 5770 return gl::error(GL_INVALID_ENUM); 5771 } 5772 5773 if (levels != 1 && !context->supportsNonPower2Texture()) 5774 { 5775 if (!gl::isPow2(width) || !gl::isPow2(height)) 5776 { 5777 return gl::error(GL_INVALID_OPERATION); 5778 } 5779 } 5780 5781 switch (internalformat) 5782 { 5783 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 5784 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 5785 if (!context->supportsDXT1Textures()) 5786 { 5787 return gl::error(GL_INVALID_ENUM); 5788 } 5789 break; 5790 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: 5791 if (!context->supportsDXT3Textures()) 5792 { 5793 return gl::error(GL_INVALID_ENUM); 5794 } 5795 break; 5796 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: 5797 if (!context->supportsDXT5Textures()) 5798 { 5799 return gl::error(GL_INVALID_ENUM); 5800 } 5801 break; 5802 case GL_RGBA32F_EXT: 5803 case GL_RGB32F_EXT: 5804 case GL_ALPHA32F_EXT: 5805 case GL_LUMINANCE32F_EXT: 5806 case GL_LUMINANCE_ALPHA32F_EXT: 5807 if (!context->supportsFloat32Textures()) 5808 { 5809 return gl::error(GL_INVALID_ENUM); 5810 } 5811 break; 5812 case GL_RGBA16F_EXT: 5813 case GL_RGB16F_EXT: 5814 case GL_ALPHA16F_EXT: 5815 case GL_LUMINANCE16F_EXT: 5816 case GL_LUMINANCE_ALPHA16F_EXT: 5817 if (!context->supportsFloat16Textures()) 5818 { 5819 return gl::error(GL_INVALID_ENUM); 5820 } 5821 break; 5822 case GL_DEPTH_COMPONENT16: 5823 case GL_DEPTH_COMPONENT32_OES: 5824 case GL_DEPTH24_STENCIL8_OES: 5825 if (!context->supportsDepthTextures()) 5826 { 5827 return gl::error(GL_INVALID_ENUM); 5828 } 5829 if (target != GL_TEXTURE_2D) 5830 { 5831 return gl::error(GL_INVALID_OPERATION); 5832 } 5833 // ANGLE_depth_texture only supports 1-level textures 5834 if (levels != 1) 5835 { 5836 return gl::error(GL_INVALID_OPERATION); 5837 } 5838 break; 5839 default: 5840 break; 5841 } 5842 5843 if (target == GL_TEXTURE_2D) 5844 { 5845 gl::Texture2D *texture = context->getTexture2D(); 5846 5847 if (!texture || texture->id() == 0) 5848 { 5849 return gl::error(GL_INVALID_OPERATION); 5850 } 5851 5852 if (texture->isImmutable()) 5853 { 5854 return gl::error(GL_INVALID_OPERATION); 5855 } 5856 5857 texture->storage(levels, internalformat, width, height); 5858 } 5859 else if (target == GL_TEXTURE_CUBE_MAP) 5860 { 5861 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 5862 5863 if (!texture || texture->id() == 0) 5864 { 5865 return gl::error(GL_INVALID_OPERATION); 5866 } 5867 5868 if (texture->isImmutable()) 5869 { 5870 return gl::error(GL_INVALID_OPERATION); 5871 } 5872 5873 texture->storage(levels, internalformat, width); 5874 } 5875 else UNREACHABLE(); 5876 } 5877 } 5878 catch(std::bad_alloc&) 5879 { 5880 return gl::error(GL_OUT_OF_MEMORY); 5881 } 5882 } 5883 5884 void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, 5885 GLenum format, GLenum type, const GLvoid* pixels) 5886 { 5887 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 5888 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " 5889 "const GLvoid* pixels = 0x%0.8p)", 5890 target, level, xoffset, yoffset, width, height, format, type, pixels); 5891 5892 try 5893 { 5894 if (!gl::IsInternalTextureTarget(target)) 5895 { 5896 return gl::error(GL_INVALID_ENUM); 5897 } 5898 5899 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0) 5900 { 5901 return gl::error(GL_INVALID_VALUE); 5902 } 5903 5904 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) 5905 { 5906 return gl::error(GL_INVALID_VALUE); 5907 } 5908 5909 if (!checkTextureFormatType(format, type)) 5910 { 5911 return; // error is set by helper function 5912 } 5913 5914 gl::Context *context = gl::getNonLostContext(); 5915 5916 if (context) 5917 { 5918 if (level > context->getMaximumTextureLevel()) 5919 { 5920 return gl::error(GL_INVALID_VALUE); 5921 } 5922 5923 if (format == GL_FLOAT) 5924 { 5925 if (!context->supportsFloat32Textures()) 5926 { 5927 return gl::error(GL_INVALID_ENUM); 5928 } 5929 } 5930 else if (format == GL_HALF_FLOAT_OES) 5931 { 5932 if (!context->supportsFloat16Textures()) 5933 { 5934 return gl::error(GL_INVALID_ENUM); 5935 } 5936 } 5937 else if (gl::IsDepthTexture(format)) 5938 { 5939 if (!context->supportsDepthTextures()) 5940 { 5941 return gl::error(GL_INVALID_ENUM); 5942 } 5943 if (target != GL_TEXTURE_2D) 5944 { 5945 return gl::error(GL_INVALID_OPERATION); 5946 } 5947 // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not 5948 return gl::error(GL_INVALID_OPERATION); 5949 } 5950 5951 if (width == 0 || height == 0 || pixels == NULL) 5952 { 5953 return; 5954 } 5955 5956 if (target == GL_TEXTURE_2D) 5957 { 5958 gl::Texture2D *texture = context->getTexture2D(); 5959 if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, type, texture)) 5960 { 5961 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); 5962 } 5963 } 5964 else if (gl::IsCubemapTextureTarget(target)) 5965 { 5966 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 5967 if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, type, texture)) 5968 { 5969 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); 5970 } 5971 } 5972 else 5973 { 5974 UNREACHABLE(); 5975 } 5976 } 5977 } 5978 catch(std::bad_alloc&) 5979 { 5980 return gl::error(GL_OUT_OF_MEMORY); 5981 } 5982 } 5983 5984 void __stdcall glUniform1f(GLint location, GLfloat x) 5985 { 5986 glUniform1fv(location, 1, &x); 5987 } 5988 5989 void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) 5990 { 5991 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); 5992 5993 try 5994 { 5995 if (count < 0) 5996 { 5997 return gl::error(GL_INVALID_VALUE); 5998 } 5999 6000 if (location == -1) 6001 { 6002 return; 6003 } 6004 6005 gl::Context *context = gl::getNonLostContext(); 6006 6007 if (context) 6008 { 6009 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6010 if (!programBinary) 6011 { 6012 return gl::error(GL_INVALID_OPERATION); 6013 } 6014 6015 if (!programBinary->setUniform1fv(location, count, v)) 6016 { 6017 return gl::error(GL_INVALID_OPERATION); 6018 } 6019 } 6020 } 6021 catch(std::bad_alloc&) 6022 { 6023 return gl::error(GL_OUT_OF_MEMORY); 6024 } 6025 } 6026 6027 void __stdcall glUniform1i(GLint location, GLint x) 6028 { 6029 glUniform1iv(location, 1, &x); 6030 } 6031 6032 void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) 6033 { 6034 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); 6035 6036 try 6037 { 6038 if (count < 0) 6039 { 6040 return gl::error(GL_INVALID_VALUE); 6041 } 6042 6043 if (location == -1) 6044 { 6045 return; 6046 } 6047 6048 gl::Context *context = gl::getNonLostContext(); 6049 6050 if (context) 6051 { 6052 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6053 if (!programBinary) 6054 { 6055 return gl::error(GL_INVALID_OPERATION); 6056 } 6057 6058 if (!programBinary->setUniform1iv(location, count, v)) 6059 { 6060 return gl::error(GL_INVALID_OPERATION); 6061 } 6062 } 6063 } 6064 catch(std::bad_alloc&) 6065 { 6066 return gl::error(GL_OUT_OF_MEMORY); 6067 } 6068 } 6069 6070 void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y) 6071 { 6072 GLfloat xy[2] = {x, y}; 6073 6074 glUniform2fv(location, 1, (GLfloat*)&xy); 6075 } 6076 6077 void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) 6078 { 6079 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); 6080 6081 try 6082 { 6083 if (count < 0) 6084 { 6085 return gl::error(GL_INVALID_VALUE); 6086 } 6087 6088 if (location == -1) 6089 { 6090 return; 6091 } 6092 6093 gl::Context *context = gl::getNonLostContext(); 6094 6095 if (context) 6096 { 6097 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6098 if (!programBinary) 6099 { 6100 return gl::error(GL_INVALID_OPERATION); 6101 } 6102 6103 if (!programBinary->setUniform2fv(location, count, v)) 6104 { 6105 return gl::error(GL_INVALID_OPERATION); 6106 } 6107 } 6108 } 6109 catch(std::bad_alloc&) 6110 { 6111 return gl::error(GL_OUT_OF_MEMORY); 6112 } 6113 } 6114 6115 void __stdcall glUniform2i(GLint location, GLint x, GLint y) 6116 { 6117 GLint xy[4] = {x, y}; 6118 6119 glUniform2iv(location, 1, (GLint*)&xy); 6120 } 6121 6122 void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) 6123 { 6124 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); 6125 6126 try 6127 { 6128 if (count < 0) 6129 { 6130 return gl::error(GL_INVALID_VALUE); 6131 } 6132 6133 if (location == -1) 6134 { 6135 return; 6136 } 6137 6138 gl::Context *context = gl::getNonLostContext(); 6139 6140 if (context) 6141 { 6142 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6143 if (!programBinary) 6144 { 6145 return gl::error(GL_INVALID_OPERATION); 6146 } 6147 6148 if (!programBinary->setUniform2iv(location, count, v)) 6149 { 6150 return gl::error(GL_INVALID_OPERATION); 6151 } 6152 } 6153 } 6154 catch(std::bad_alloc&) 6155 { 6156 return gl::error(GL_OUT_OF_MEMORY); 6157 } 6158 } 6159 6160 void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) 6161 { 6162 GLfloat xyz[3] = {x, y, z}; 6163 6164 glUniform3fv(location, 1, (GLfloat*)&xyz); 6165 } 6166 6167 void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) 6168 { 6169 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); 6170 6171 try 6172 { 6173 if (count < 0) 6174 { 6175 return gl::error(GL_INVALID_VALUE); 6176 } 6177 6178 if (location == -1) 6179 { 6180 return; 6181 } 6182 6183 gl::Context *context = gl::getNonLostContext(); 6184 6185 if (context) 6186 { 6187 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6188 if (!programBinary) 6189 { 6190 return gl::error(GL_INVALID_OPERATION); 6191 } 6192 6193 if (!programBinary->setUniform3fv(location, count, v)) 6194 { 6195 return gl::error(GL_INVALID_OPERATION); 6196 } 6197 } 6198 } 6199 catch(std::bad_alloc&) 6200 { 6201 return gl::error(GL_OUT_OF_MEMORY); 6202 } 6203 } 6204 6205 void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z) 6206 { 6207 GLint xyz[3] = {x, y, z}; 6208 6209 glUniform3iv(location, 1, (GLint*)&xyz); 6210 } 6211 6212 void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) 6213 { 6214 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); 6215 6216 try 6217 { 6218 if (count < 0) 6219 { 6220 return gl::error(GL_INVALID_VALUE); 6221 } 6222 6223 if (location == -1) 6224 { 6225 return; 6226 } 6227 6228 gl::Context *context = gl::getNonLostContext(); 6229 6230 if (context) 6231 { 6232 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6233 if (!programBinary) 6234 { 6235 return gl::error(GL_INVALID_OPERATION); 6236 } 6237 6238 if (!programBinary->setUniform3iv(location, count, v)) 6239 { 6240 return gl::error(GL_INVALID_OPERATION); 6241 } 6242 } 6243 } 6244 catch(std::bad_alloc&) 6245 { 6246 return gl::error(GL_OUT_OF_MEMORY); 6247 } 6248 } 6249 6250 void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 6251 { 6252 GLfloat xyzw[4] = {x, y, z, w}; 6253 6254 glUniform4fv(location, 1, (GLfloat*)&xyzw); 6255 } 6256 6257 void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) 6258 { 6259 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); 6260 6261 try 6262 { 6263 if (count < 0) 6264 { 6265 return gl::error(GL_INVALID_VALUE); 6266 } 6267 6268 if (location == -1) 6269 { 6270 return; 6271 } 6272 6273 gl::Context *context = gl::getNonLostContext(); 6274 6275 if (context) 6276 { 6277 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6278 if (!programBinary) 6279 { 6280 return gl::error(GL_INVALID_OPERATION); 6281 } 6282 6283 if (!programBinary->setUniform4fv(location, count, v)) 6284 { 6285 return gl::error(GL_INVALID_OPERATION); 6286 } 6287 } 6288 } 6289 catch(std::bad_alloc&) 6290 { 6291 return gl::error(GL_OUT_OF_MEMORY); 6292 } 6293 } 6294 6295 void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) 6296 { 6297 GLint xyzw[4] = {x, y, z, w}; 6298 6299 glUniform4iv(location, 1, (GLint*)&xyzw); 6300 } 6301 6302 void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) 6303 { 6304 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); 6305 6306 try 6307 { 6308 if (count < 0) 6309 { 6310 return gl::error(GL_INVALID_VALUE); 6311 } 6312 6313 if (location == -1) 6314 { 6315 return; 6316 } 6317 6318 gl::Context *context = gl::getNonLostContext(); 6319 6320 if (context) 6321 { 6322 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6323 if (!programBinary) 6324 { 6325 return gl::error(GL_INVALID_OPERATION); 6326 } 6327 6328 if (!programBinary->setUniform4iv(location, count, v)) 6329 { 6330 return gl::error(GL_INVALID_OPERATION); 6331 } 6332 } 6333 } 6334 catch(std::bad_alloc&) 6335 { 6336 return gl::error(GL_OUT_OF_MEMORY); 6337 } 6338 } 6339 6340 void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 6341 { 6342 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", 6343 location, count, transpose, value); 6344 6345 try 6346 { 6347 if (count < 0 || transpose != GL_FALSE) 6348 { 6349 return gl::error(GL_INVALID_VALUE); 6350 } 6351 6352 if (location == -1) 6353 { 6354 return; 6355 } 6356 6357 gl::Context *context = gl::getNonLostContext(); 6358 6359 if (context) 6360 { 6361 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6362 if (!programBinary) 6363 { 6364 return gl::error(GL_INVALID_OPERATION); 6365 } 6366 6367 if (!programBinary->setUniformMatrix2fv(location, count, value)) 6368 { 6369 return gl::error(GL_INVALID_OPERATION); 6370 } 6371 } 6372 } 6373 catch(std::bad_alloc&) 6374 { 6375 return gl::error(GL_OUT_OF_MEMORY); 6376 } 6377 } 6378 6379 void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 6380 { 6381 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", 6382 location, count, transpose, value); 6383 6384 try 6385 { 6386 if (count < 0 || transpose != GL_FALSE) 6387 { 6388 return gl::error(GL_INVALID_VALUE); 6389 } 6390 6391 if (location == -1) 6392 { 6393 return; 6394 } 6395 6396 gl::Context *context = gl::getNonLostContext(); 6397 6398 if (context) 6399 { 6400 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6401 if (!programBinary) 6402 { 6403 return gl::error(GL_INVALID_OPERATION); 6404 } 6405 6406 if (!programBinary->setUniformMatrix3fv(location, count, value)) 6407 { 6408 return gl::error(GL_INVALID_OPERATION); 6409 } 6410 } 6411 } 6412 catch(std::bad_alloc&) 6413 { 6414 return gl::error(GL_OUT_OF_MEMORY); 6415 } 6416 } 6417 6418 void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 6419 { 6420 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", 6421 location, count, transpose, value); 6422 6423 try 6424 { 6425 if (count < 0 || transpose != GL_FALSE) 6426 { 6427 return gl::error(GL_INVALID_VALUE); 6428 } 6429 6430 if (location == -1) 6431 { 6432 return; 6433 } 6434 6435 gl::Context *context = gl::getNonLostContext(); 6436 6437 if (context) 6438 { 6439 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6440 if (!programBinary) 6441 { 6442 return gl::error(GL_INVALID_OPERATION); 6443 } 6444 6445 if (!programBinary->setUniformMatrix4fv(location, count, value)) 6446 { 6447 return gl::error(GL_INVALID_OPERATION); 6448 } 6449 } 6450 } 6451 catch(std::bad_alloc&) 6452 { 6453 return gl::error(GL_OUT_OF_MEMORY); 6454 } 6455 } 6456 6457 void __stdcall glUseProgram(GLuint program) 6458 { 6459 EVENT("(GLuint program = %d)", program); 6460 6461 try 6462 { 6463 gl::Context *context = gl::getNonLostContext(); 6464 6465 if (context) 6466 { 6467 gl::Program *programObject = context->getProgram(program); 6468 6469 if (!programObject && program != 0) 6470 { 6471 if (context->getShader(program)) 6472 { 6473 return gl::error(GL_INVALID_OPERATION); 6474 } 6475 else 6476 { 6477 return gl::error(GL_INVALID_VALUE); 6478 } 6479 } 6480 6481 if (program != 0 && !programObject->isLinked()) 6482 { 6483 return gl::error(GL_INVALID_OPERATION); 6484 } 6485 6486 context->useProgram(program); 6487 } 6488 } 6489 catch(std::bad_alloc&) 6490 { 6491 return gl::error(GL_OUT_OF_MEMORY); 6492 } 6493 } 6494 6495 void __stdcall glValidateProgram(GLuint program) 6496 { 6497 EVENT("(GLuint program = %d)", program); 6498 6499 try 6500 { 6501 gl::Context *context = gl::getNonLostContext(); 6502 6503 if (context) 6504 { 6505 gl::Program *programObject = context->getProgram(program); 6506 6507 if (!programObject) 6508 { 6509 if (context->getShader(program)) 6510 { 6511 return gl::error(GL_INVALID_OPERATION); 6512 } 6513 else 6514 { 6515 return gl::error(GL_INVALID_VALUE); 6516 } 6517 } 6518 6519 programObject->validate(); 6520 } 6521 } 6522 catch(std::bad_alloc&) 6523 { 6524 return gl::error(GL_OUT_OF_MEMORY); 6525 } 6526 } 6527 6528 void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) 6529 { 6530 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x); 6531 6532 try 6533 { 6534 if (index >= gl::MAX_VERTEX_ATTRIBS) 6535 { 6536 return gl::error(GL_INVALID_VALUE); 6537 } 6538 6539 gl::Context *context = gl::getNonLostContext(); 6540 6541 if (context) 6542 { 6543 GLfloat vals[4] = { x, 0, 0, 1 }; 6544 context->setVertexAttrib(index, vals); 6545 } 6546 } 6547 catch(std::bad_alloc&) 6548 { 6549 return gl::error(GL_OUT_OF_MEMORY); 6550 } 6551 } 6552 6553 void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) 6554 { 6555 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); 6556 6557 try 6558 { 6559 if (index >= gl::MAX_VERTEX_ATTRIBS) 6560 { 6561 return gl::error(GL_INVALID_VALUE); 6562 } 6563 6564 gl::Context *context = gl::getNonLostContext(); 6565 6566 if (context) 6567 { 6568 GLfloat vals[4] = { values[0], 0, 0, 1 }; 6569 context->setVertexAttrib(index, vals); 6570 } 6571 } 6572 catch(std::bad_alloc&) 6573 { 6574 return gl::error(GL_OUT_OF_MEMORY); 6575 } 6576 } 6577 6578 void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) 6579 { 6580 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y); 6581 6582 try 6583 { 6584 if (index >= gl::MAX_VERTEX_ATTRIBS) 6585 { 6586 return gl::error(GL_INVALID_VALUE); 6587 } 6588 6589 gl::Context *context = gl::getNonLostContext(); 6590 6591 if (context) 6592 { 6593 GLfloat vals[4] = { x, y, 0, 1 }; 6594 context->setVertexAttrib(index, vals); 6595 } 6596 } 6597 catch(std::bad_alloc&) 6598 { 6599 return gl::error(GL_OUT_OF_MEMORY); 6600 } 6601 } 6602 6603 void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) 6604 { 6605 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); 6606 6607 try 6608 { 6609 if (index >= gl::MAX_VERTEX_ATTRIBS) 6610 { 6611 return gl::error(GL_INVALID_VALUE); 6612 } 6613 6614 gl::Context *context = gl::getNonLostContext(); 6615 6616 if (context) 6617 { 6618 GLfloat vals[4] = { values[0], values[1], 0, 1 }; 6619 context->setVertexAttrib(index, vals); 6620 } 6621 } 6622 catch(std::bad_alloc&) 6623 { 6624 return gl::error(GL_OUT_OF_MEMORY); 6625 } 6626 } 6627 6628 void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) 6629 { 6630 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); 6631 6632 try 6633 { 6634 if (index >= gl::MAX_VERTEX_ATTRIBS) 6635 { 6636 return gl::error(GL_INVALID_VALUE); 6637 } 6638 6639 gl::Context *context = gl::getNonLostContext(); 6640 6641 if (context) 6642 { 6643 GLfloat vals[4] = { x, y, z, 1 }; 6644 context->setVertexAttrib(index, vals); 6645 } 6646 } 6647 catch(std::bad_alloc&) 6648 { 6649 return gl::error(GL_OUT_OF_MEMORY); 6650 } 6651 } 6652 6653 void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) 6654 { 6655 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); 6656 6657 try 6658 { 6659 if (index >= gl::MAX_VERTEX_ATTRIBS) 6660 { 6661 return gl::error(GL_INVALID_VALUE); 6662 } 6663 6664 gl::Context *context = gl::getNonLostContext(); 6665 6666 if (context) 6667 { 6668 GLfloat vals[4] = { values[0], values[1], values[2], 1 }; 6669 context->setVertexAttrib(index, vals); 6670 } 6671 } 6672 catch(std::bad_alloc&) 6673 { 6674 return gl::error(GL_OUT_OF_MEMORY); 6675 } 6676 } 6677 6678 void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 6679 { 6680 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w); 6681 6682 try 6683 { 6684 if (index >= gl::MAX_VERTEX_ATTRIBS) 6685 { 6686 return gl::error(GL_INVALID_VALUE); 6687 } 6688 6689 gl::Context *context = gl::getNonLostContext(); 6690 6691 if (context) 6692 { 6693 GLfloat vals[4] = { x, y, z, w }; 6694 context->setVertexAttrib(index, vals); 6695 } 6696 } 6697 catch(std::bad_alloc&) 6698 { 6699 return gl::error(GL_OUT_OF_MEMORY); 6700 } 6701 } 6702 6703 void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) 6704 { 6705 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); 6706 6707 try 6708 { 6709 if (index >= gl::MAX_VERTEX_ATTRIBS) 6710 { 6711 return gl::error(GL_INVALID_VALUE); 6712 } 6713 6714 gl::Context *context = gl::getNonLostContext(); 6715 6716 if (context) 6717 { 6718 context->setVertexAttrib(index, values); 6719 } 6720 } 6721 catch(std::bad_alloc&) 6722 { 6723 return gl::error(GL_OUT_OF_MEMORY); 6724 } 6725 } 6726 6727 void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) 6728 { 6729 EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor); 6730 6731 try 6732 { 6733 if (index >= gl::MAX_VERTEX_ATTRIBS) 6734 { 6735 return gl::error(GL_INVALID_VALUE); 6736 } 6737 6738 gl::Context *context = gl::getNonLostContext(); 6739 6740 if (context) 6741 { 6742 context->setVertexAttribDivisor(index, divisor); 6743 } 6744 } 6745 catch(std::bad_alloc&) 6746 { 6747 return gl::error(GL_OUT_OF_MEMORY); 6748 } 6749 } 6750 6751 void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) 6752 { 6753 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " 6754 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)", 6755 index, size, type, normalized, stride, ptr); 6756 6757 try 6758 { 6759 if (index >= gl::MAX_VERTEX_ATTRIBS) 6760 { 6761 return gl::error(GL_INVALID_VALUE); 6762 } 6763 6764 if (size < 1 || size > 4) 6765 { 6766 return gl::error(GL_INVALID_VALUE); 6767 } 6768 6769 switch (type) 6770 { 6771 case GL_BYTE: 6772 case GL_UNSIGNED_BYTE: 6773 case GL_SHORT: 6774 case GL_UNSIGNED_SHORT: 6775 case GL_FIXED: 6776 case GL_FLOAT: 6777 break; 6778 default: 6779 return gl::error(GL_INVALID_ENUM); 6780 } 6781 6782 if (stride < 0) 6783 { 6784 return gl::error(GL_INVALID_VALUE); 6785 } 6786 6787 gl::Context *context = gl::getNonLostContext(); 6788 6789 if (context) 6790 { 6791 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr); 6792 } 6793 } 6794 catch(std::bad_alloc&) 6795 { 6796 return gl::error(GL_OUT_OF_MEMORY); 6797 } 6798 } 6799 6800 void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height) 6801 { 6802 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); 6803 6804 try 6805 { 6806 if (width < 0 || height < 0) 6807 { 6808 return gl::error(GL_INVALID_VALUE); 6809 } 6810 6811 gl::Context *context = gl::getNonLostContext(); 6812 6813 if (context) 6814 { 6815 context->setViewportParams(x, y, width, height); 6816 } 6817 } 6818 catch(std::bad_alloc&) 6819 { 6820 return gl::error(GL_OUT_OF_MEMORY); 6821 } 6822 } 6823 6824 void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 6825 GLbitfield mask, GLenum filter) 6826 { 6827 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " 6828 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, " 6829 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)", 6830 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter); 6831 6832 try 6833 { 6834 switch (filter) 6835 { 6836 case GL_NEAREST: 6837 break; 6838 default: 6839 return gl::error(GL_INVALID_ENUM); 6840 } 6841 6842 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0) 6843 { 6844 return gl::error(GL_INVALID_VALUE); 6845 } 6846 6847 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0) 6848 { 6849 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation"); 6850 return gl::error(GL_INVALID_OPERATION); 6851 } 6852 6853 gl::Context *context = gl::getNonLostContext(); 6854 6855 if (context) 6856 { 6857 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle()) 6858 { 6859 ERR("Blits with the same source and destination framebuffer are not supported by this implementation."); 6860 return gl::error(GL_INVALID_OPERATION); 6861 } 6862 6863 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask); 6864 } 6865 } 6866 catch(std::bad_alloc&) 6867 { 6868 return gl::error(GL_OUT_OF_MEMORY); 6869 } 6870 } 6871 6872 void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, 6873 GLint border, GLenum format, GLenum type, const GLvoid* pixels) 6874 { 6875 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " 6876 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, " 6877 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)", 6878 target, level, internalformat, width, height, depth, border, format, type, pixels); 6879 6880 try 6881 { 6882 UNIMPLEMENTED(); // FIXME 6883 } 6884 catch(std::bad_alloc&) 6885 { 6886 return gl::error(GL_OUT_OF_MEMORY); 6887 } 6888 } 6889 6890 void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, 6891 GLenum *binaryFormat, void *binary) 6892 { 6893 EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)", 6894 program, bufSize, length, binaryFormat, binary); 6895 6896 try 6897 { 6898 gl::Context *context = gl::getNonLostContext(); 6899 6900 if (context) 6901 { 6902 gl::Program *programObject = context->getProgram(program); 6903 6904 if (!programObject || !programObject->isLinked()) 6905 { 6906 return gl::error(GL_INVALID_OPERATION); 6907 } 6908 6909 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 6910 6911 if (!programBinary) 6912 { 6913 return gl::error(GL_INVALID_OPERATION); 6914 } 6915 6916 if (!programBinary->save(binary, bufSize, length)) 6917 { 6918 return gl::error(GL_INVALID_OPERATION); 6919 } 6920 6921 *binaryFormat = GL_PROGRAM_BINARY_ANGLE; 6922 } 6923 } 6924 catch(std::bad_alloc&) 6925 { 6926 return gl::error(GL_OUT_OF_MEMORY); 6927 } 6928 } 6929 6930 void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat, 6931 const void *binary, GLint length) 6932 { 6933 EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)", 6934 program, binaryFormat, binary, length); 6935 6936 try 6937 { 6938 gl::Context *context = gl::getNonLostContext(); 6939 6940 if (context) 6941 { 6942 if (binaryFormat != GL_PROGRAM_BINARY_ANGLE) 6943 { 6944 return gl::error(GL_INVALID_ENUM); 6945 } 6946 6947 gl::Program *programObject = context->getProgram(program); 6948 6949 if (!programObject) 6950 { 6951 return gl::error(GL_INVALID_OPERATION); 6952 } 6953 6954 context->setProgramBinary(program, binary, length); 6955 } 6956 } 6957 catch(std::bad_alloc&) 6958 { 6959 return gl::error(GL_OUT_OF_MEMORY); 6960 } 6961 } 6962 6963 void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) 6964 { 6965 EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs); 6966 6967 try 6968 { 6969 gl::Context *context = gl::getNonLostContext(); 6970 6971 if (context) 6972 { 6973 if (n < 0 || (unsigned int)n > context->getMaximumRenderTargets()) 6974 { 6975 return gl::error(GL_INVALID_VALUE); 6976 } 6977 6978 if (context->getDrawFramebufferHandle() == 0) 6979 { 6980 if (n != 1) 6981 { 6982 return gl::error(GL_INVALID_OPERATION); 6983 } 6984 6985 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK) 6986 { 6987 return gl::error(GL_INVALID_OPERATION); 6988 } 6989 } 6990 else 6991 { 6992 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++) 6993 { 6994 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment; 6995 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment) 6996 { 6997 return gl::error(GL_INVALID_OPERATION); 6998 } 6999 } 7000 } 7001 7002 gl::Framebuffer *framebuffer = context->getDrawFramebuffer(); 7003 7004 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++) 7005 { 7006 framebuffer->setDrawBufferState(colorAttachment, bufs[colorAttachment]); 7007 } 7008 7009 for (int colorAttachment = n; colorAttachment < (int)context->getMaximumRenderTargets(); colorAttachment++) 7010 { 7011 framebuffer->setDrawBufferState(colorAttachment, GL_NONE); 7012 } 7013 } 7014 } 7015 catch (std::bad_alloc&) 7016 { 7017 return gl::error(GL_OUT_OF_MEMORY); 7018 } 7019 } 7020 7021 __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname) 7022 { 7023 struct Extension 7024 { 7025 const char *name; 7026 __eglMustCastToProperFunctionPointerType address; 7027 }; 7028 7029 static const Extension glExtensions[] = 7030 { 7031 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES}, 7032 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE}, 7033 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE}, 7034 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV}, 7035 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV}, 7036 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV}, 7037 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV}, 7038 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV}, 7039 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV}, 7040 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV}, 7041 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE}, 7042 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT}, 7043 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT}, 7044 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT}, 7045 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT}, 7046 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT}, 7047 {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT}, 7048 {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT}, 7049 {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT}, 7050 {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT}, 7051 {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT}, 7052 {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT}, 7053 {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT}, 7054 {"glDrawBuffersEXT", (__eglMustCastToProperFunctionPointerType)glDrawBuffersEXT}, 7055 {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE}, 7056 {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE}, 7057 {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE}, 7058 {"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES}, 7059 {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES}, }; 7060 7061 for (unsigned int ext = 0; ext < ArraySize(glExtensions); ext++) 7062 { 7063 if (strcmp(procname, glExtensions[ext].name) == 0) 7064 { 7065 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address; 7066 } 7067 } 7068 7069 return NULL; 7070 } 7071 7072 // Non-public functions used by EGL 7073 7074 bool __stdcall glBindTexImage(egl::Surface *surface) 7075 { 7076 EVENT("(egl::Surface* surface = 0x%0.8p)", 7077 surface); 7078 7079 try 7080 { 7081 gl::Context *context = gl::getNonLostContext(); 7082 7083 if (context) 7084 { 7085 gl::Texture2D *textureObject = context->getTexture2D(); 7086 7087 if (textureObject->isImmutable()) 7088 { 7089 return false; 7090 } 7091 7092 if (textureObject) 7093 { 7094 textureObject->bindTexImage(surface); 7095 } 7096 } 7097 } 7098 catch(std::bad_alloc&) 7099 { 7100 return gl::error(GL_OUT_OF_MEMORY, false); 7101 } 7102 7103 return true; 7104 } 7105 7106 } 7107