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