1// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// libGLES_CM.cpp: Implements the exported OpenGL ES 1.1 functions. 16 17#include "main.h" 18#include "mathutil.h" 19#include "utilities.h" 20#include "Buffer.h" 21#include "Context.h" 22#include "Framebuffer.h" 23#include "Renderbuffer.h" 24#include "Texture.h" 25#include "common/debug.h" 26#include "Common/SharedLibrary.hpp" 27#include "Common/Version.h" 28 29#include <EGL/egl.h> 30#include <EGL/eglext.h> 31 32#include <GLES/gl.h> 33#include <GLES/glext.h> 34 35#include <algorithm> 36#include <limits> 37 38namespace es1 39{ 40 41static bool validImageSize(GLint level, GLsizei width, GLsizei height) 42{ 43 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0) 44 { 45 return false; 46 } 47 48 return true; 49} 50 51void ActiveTexture(GLenum texture) 52{ 53 TRACE("(GLenum texture = 0x%X)", texture); 54 55 es1::Context *context = es1::getContext(); 56 57 if(context) 58 { 59 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es1::MAX_TEXTURE_UNITS - 1) 60 { 61 return error(GL_INVALID_ENUM); 62 } 63 64 context->setActiveSampler(texture - GL_TEXTURE0); 65 } 66} 67 68void AlphaFunc(GLenum func, GLclampf ref) 69{ 70 TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref); 71 72 switch(func) 73 { 74 case GL_NEVER: 75 case GL_ALWAYS: 76 case GL_LESS: 77 case GL_LEQUAL: 78 case GL_EQUAL: 79 case GL_GEQUAL: 80 case GL_GREATER: 81 case GL_NOTEQUAL: 82 break; 83 default: 84 return error(GL_INVALID_ENUM); 85 } 86 87 es1::Context *context = es1::getContext(); 88 89 if(context) 90 { 91 context->setAlphaFunc(func, clamp01(ref)); 92 } 93} 94 95void AlphaFuncx(GLenum func, GLclampx ref) 96{ 97 AlphaFunc(func, (float)ref / 0x10000); 98} 99 100void BindBuffer(GLenum target, GLuint buffer) 101{ 102 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer); 103 104 es1::Context *context = es1::getContext(); 105 106 if(context) 107 { 108 switch(target) 109 { 110 case GL_ARRAY_BUFFER: 111 context->bindArrayBuffer(buffer); 112 return; 113 case GL_ELEMENT_ARRAY_BUFFER: 114 context->bindElementArrayBuffer(buffer); 115 return; 116 default: 117 return error(GL_INVALID_ENUM); 118 } 119 } 120} 121 122void BindFramebuffer(GLenum target, GLuint framebuffer) 123{ 124 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); 125 126 if(target != GL_FRAMEBUFFER_OES) 127 { 128 return error(GL_INVALID_ENUM); 129 } 130 131 es1::Context *context = es1::getContext(); 132 133 if(context) 134 { 135 context->bindFramebuffer(framebuffer); 136 } 137} 138 139void BindFramebufferOES(GLenum target, GLuint framebuffer) 140{ 141 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); 142 143 if(target != GL_FRAMEBUFFER_OES) 144 { 145 return error(GL_INVALID_ENUM); 146 } 147 148 es1::Context *context = es1::getContext(); 149 150 if(context) 151 { 152 context->bindFramebuffer(framebuffer); 153 } 154} 155 156void BindRenderbufferOES(GLenum target, GLuint renderbuffer) 157{ 158 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer); 159 160 if(target != GL_RENDERBUFFER_OES) 161 { 162 return error(GL_INVALID_ENUM); 163 } 164 165 es1::Context *context = es1::getContext(); 166 167 if(context) 168 { 169 // [GL_EXT_framebuffer_object] 170 // If <renderbuffer> is not zero, then the resulting renderbuffer object 171 // is a new state vector, initialized with a zero-sized memory buffer 172 context->bindRenderbuffer(renderbuffer); 173 } 174} 175 176void BindTexture(GLenum target, GLuint texture) 177{ 178 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture); 179 180 es1::Context *context = es1::getContext(); 181 182 if(context) 183 { 184 es1::Texture *textureObject = context->getTexture(texture); 185 186 if(textureObject && textureObject->getTarget() != target && texture != 0) 187 { 188 return error(GL_INVALID_OPERATION); 189 } 190 191 switch(target) 192 { 193 case GL_TEXTURE_2D: 194 context->bindTexture(TEXTURE_2D, texture); 195 break; 196 case GL_TEXTURE_EXTERNAL_OES: 197 context->bindTexture(TEXTURE_EXTERNAL, texture); 198 break; 199 default: 200 return error(GL_INVALID_ENUM); 201 } 202 } 203} 204 205void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha); 206 207void BlendEquationOES(GLenum mode) 208{ 209 BlendEquationSeparateOES(mode, mode); 210} 211 212void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha) 213{ 214 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); 215 216 switch(modeRGB) 217 { 218 case GL_FUNC_ADD_OES: 219 case GL_FUNC_SUBTRACT_OES: 220 case GL_FUNC_REVERSE_SUBTRACT_OES: 221 case GL_MIN_EXT: 222 case GL_MAX_EXT: 223 break; 224 default: 225 return error(GL_INVALID_ENUM); 226 } 227 228 switch(modeAlpha) 229 { 230 case GL_FUNC_ADD_OES: 231 case GL_FUNC_SUBTRACT_OES: 232 case GL_FUNC_REVERSE_SUBTRACT_OES: 233 case GL_MIN_EXT: 234 case GL_MAX_EXT: 235 break; 236 default: 237 return error(GL_INVALID_ENUM); 238 } 239 240 es1::Context *context = es1::getContext(); 241 242 if(context) 243 { 244 context->setBlendEquation(modeRGB, modeAlpha); 245 } 246} 247 248void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); 249 250void BlendFunc(GLenum sfactor, GLenum dfactor) 251{ 252 BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor); 253} 254 255void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) 256{ 257 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)", 258 srcRGB, dstRGB, srcAlpha, dstAlpha); 259 260 switch(srcRGB) 261 { 262 case GL_ZERO: 263 case GL_ONE: 264 case GL_SRC_COLOR: 265 case GL_ONE_MINUS_SRC_COLOR: 266 case GL_DST_COLOR: 267 case GL_ONE_MINUS_DST_COLOR: 268 case GL_SRC_ALPHA: 269 case GL_ONE_MINUS_SRC_ALPHA: 270 case GL_DST_ALPHA: 271 case GL_ONE_MINUS_DST_ALPHA: 272 case GL_SRC_ALPHA_SATURATE: 273 break; 274 default: 275 return error(GL_INVALID_ENUM); 276 } 277 278 switch(dstRGB) 279 { 280 case GL_ZERO: 281 case GL_ONE: 282 case GL_SRC_COLOR: 283 case GL_ONE_MINUS_SRC_COLOR: 284 case GL_DST_COLOR: 285 case GL_ONE_MINUS_DST_COLOR: 286 case GL_SRC_ALPHA: 287 case GL_ONE_MINUS_SRC_ALPHA: 288 case GL_DST_ALPHA: 289 case GL_ONE_MINUS_DST_ALPHA: 290 break; 291 default: 292 return error(GL_INVALID_ENUM); 293 } 294 295 switch(srcAlpha) 296 { 297 case GL_ZERO: 298 case GL_ONE: 299 case GL_SRC_COLOR: 300 case GL_ONE_MINUS_SRC_COLOR: 301 case GL_DST_COLOR: 302 case GL_ONE_MINUS_DST_COLOR: 303 case GL_SRC_ALPHA: 304 case GL_ONE_MINUS_SRC_ALPHA: 305 case GL_DST_ALPHA: 306 case GL_ONE_MINUS_DST_ALPHA: 307 case GL_SRC_ALPHA_SATURATE: 308 break; 309 default: 310 return error(GL_INVALID_ENUM); 311 } 312 313 switch(dstAlpha) 314 { 315 case GL_ZERO: 316 case GL_ONE: 317 case GL_SRC_COLOR: 318 case GL_ONE_MINUS_SRC_COLOR: 319 case GL_DST_COLOR: 320 case GL_ONE_MINUS_DST_COLOR: 321 case GL_SRC_ALPHA: 322 case GL_ONE_MINUS_SRC_ALPHA: 323 case GL_DST_ALPHA: 324 case GL_ONE_MINUS_DST_ALPHA: 325 break; 326 default: 327 return error(GL_INVALID_ENUM); 328 } 329 330 es1::Context *context = es1::getContext(); 331 332 if(context) 333 { 334 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha); 335 } 336} 337 338void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) 339{ 340 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications 341 342 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)", 343 target, size, data, usage); 344 345 if(size < 0) 346 { 347 return error(GL_INVALID_VALUE); 348 } 349 350 switch(usage) 351 { 352 case GL_STATIC_DRAW: 353 case GL_DYNAMIC_DRAW: 354 break; 355 default: 356 return error(GL_INVALID_ENUM); 357 } 358 359 es1::Context *context = es1::getContext(); 360 361 if(context) 362 { 363 es1::Buffer *buffer; 364 365 switch(target) 366 { 367 case GL_ARRAY_BUFFER: 368 buffer = context->getArrayBuffer(); 369 break; 370 case GL_ELEMENT_ARRAY_BUFFER: 371 buffer = context->getElementArrayBuffer(); 372 break; 373 default: 374 return error(GL_INVALID_ENUM); 375 } 376 377 if(!buffer) 378 { 379 return error(GL_INVALID_OPERATION); 380 } 381 382 buffer->bufferData(data, size, usage); 383 } 384} 385 386void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) 387{ 388 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications 389 offset = static_cast<GLint>(offset); 390 391 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)", 392 target, offset, size, data); 393 394 if(size < 0 || offset < 0) 395 { 396 return error(GL_INVALID_VALUE); 397 } 398 399 if(!data) 400 { 401 return; 402 } 403 404 es1::Context *context = es1::getContext(); 405 406 if(context) 407 { 408 es1::Buffer *buffer; 409 410 switch(target) 411 { 412 case GL_ARRAY_BUFFER: 413 buffer = context->getArrayBuffer(); 414 break; 415 case GL_ELEMENT_ARRAY_BUFFER: 416 buffer = context->getElementArrayBuffer(); 417 break; 418 default: 419 return error(GL_INVALID_ENUM); 420 } 421 422 if(!buffer) 423 { 424 return error(GL_INVALID_OPERATION); 425 } 426 427 if((size_t)size + offset > buffer->size()) 428 { 429 return error(GL_INVALID_VALUE); 430 } 431 432 buffer->bufferSubData(data, size, offset); 433 } 434} 435 436GLenum CheckFramebufferStatusOES(GLenum target) 437{ 438 TRACE("(GLenum target = 0x%X)", target); 439 440 if(target != GL_FRAMEBUFFER_OES) 441 { 442 return error(GL_INVALID_ENUM, 0); 443 } 444 445 es1::Context *context = es1::getContext(); 446 447 if(context) 448 { 449 es1::Framebuffer *framebuffer = context->getFramebuffer(); 450 451 if(!framebuffer) 452 { 453 return GL_FRAMEBUFFER_UNDEFINED_OES; 454 } 455 456 return framebuffer->completeness(); 457 } 458 459 return 0; 460} 461 462void Clear(GLbitfield mask) 463{ 464 TRACE("(GLbitfield mask = %X)", mask); 465 466 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) 467 { 468 return error(GL_INVALID_VALUE); 469 } 470 471 es1::Context *context = es1::getContext(); 472 473 if(context) 474 { 475 context->clear(mask); 476 } 477} 478 479void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) 480{ 481 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", 482 red, green, blue, alpha); 483 484 es1::Context *context = es1::getContext(); 485 486 if(context) 487 { 488 context->setClearColor(red, green, blue, alpha); 489 } 490} 491 492void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) 493{ 494 ClearColor((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000); 495} 496 497void ClearDepthf(GLclampf depth) 498{ 499 TRACE("(GLclampf depth = %f)", depth); 500 501 es1::Context *context = es1::getContext(); 502 503 if(context) 504 { 505 context->setClearDepth(depth); 506 } 507} 508 509void ClearDepthx(GLclampx depth) 510{ 511 ClearDepthf((float)depth / 0x10000); 512} 513 514void ClearStencil(GLint s) 515{ 516 TRACE("(GLint s = %d)", s); 517 518 es1::Context *context = es1::getContext(); 519 520 if(context) 521 { 522 context->setClearStencil(s); 523 } 524} 525 526void ClientActiveTexture(GLenum texture) 527{ 528 TRACE("(GLenum texture = 0x%X)", texture); 529 530 switch(texture) 531 { 532 case GL_TEXTURE0: 533 case GL_TEXTURE1: 534 break; 535 default: 536 return error(GL_INVALID_ENUM); 537 } 538 539 es1::Context *context = es1::getContext(); 540 541 if(context) 542 { 543 context->clientActiveTexture(texture); 544 } 545} 546 547void ClipPlanef(GLenum plane, const GLfloat *equation) 548{ 549 TRACE("(GLenum plane = 0x%X, const GLfloat *equation)", plane); 550 551 int index = plane - GL_CLIP_PLANE0; 552 553 if(index < 0 || index >= MAX_CLIP_PLANES) 554 { 555 return error(GL_INVALID_ENUM); 556 } 557 558 es1::Context *context = es1::getContext(); 559 560 if(context) 561 { 562 context->setClipPlane(index, equation); 563 } 564} 565 566void ClipPlanex(GLenum plane, const GLfixed *equation) 567{ 568 GLfloat equationf[4] = 569 { 570 (float)equation[0] / 0x10000, 571 (float)equation[1] / 0x10000, 572 (float)equation[2] / 0x10000, 573 (float)equation[3] / 0x10000, 574 }; 575 576 ClipPlanef(plane, equationf); 577} 578 579void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) 580{ 581 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha); 582 583 es1::Context *context = es1::getContext(); 584 585 if(context) 586 { 587 context->setVertexAttrib(sw::Color0, red, green, blue, alpha); 588 } 589} 590 591void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) 592{ 593 Color4f((float)red / 0xFF, (float)green / 0xFF, (float)blue / 0xFF, (float)alpha / 0xFF); 594} 595 596void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) 597{ 598 Color4f((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000); 599} 600 601void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) 602{ 603 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)", 604 red, green, blue, alpha); 605 606 es1::Context *context = es1::getContext(); 607 608 if(context) 609 { 610 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE); 611 } 612} 613 614void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) 615{ 616 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " 617 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)", 618 index, size, type, normalized, stride, ptr); 619 620 if(index >= es1::MAX_VERTEX_ATTRIBS) 621 { 622 return error(GL_INVALID_VALUE); 623 } 624 625 if(size < 1 || size > 4) 626 { 627 return error(GL_INVALID_VALUE); 628 } 629 630 switch(type) 631 { 632 case GL_BYTE: 633 case GL_UNSIGNED_BYTE: 634 case GL_SHORT: 635 case GL_UNSIGNED_SHORT: 636 case GL_FIXED: 637 case GL_FLOAT: 638 break; 639 default: 640 return error(GL_INVALID_ENUM); 641 } 642 643 if(stride < 0) 644 { 645 return error(GL_INVALID_VALUE); 646 } 647 648 es1::Context *context = es1::getContext(); 649 650 if(context) 651 { 652 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr); 653 } 654} 655 656void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) 657{ 658 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer); 659 660 if(size != 4) 661 { 662 return error(GL_INVALID_VALUE); 663 } 664 665 VertexAttribPointer(sw::Color0, size, type, true, stride, pointer); 666} 667 668void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, 669 GLint border, GLsizei imageSize, const GLvoid* data) 670{ 671 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " 672 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)", 673 target, level, internalformat, width, height, border, imageSize, data); 674 675 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 676 { 677 return error(GL_INVALID_VALUE); 678 } 679 680 if(!validImageSize(level, width, height) || imageSize < 0) 681 { 682 return error(GL_INVALID_VALUE); 683 } 684 685 switch(internalformat) 686 { 687 case GL_ETC1_RGB8_OES: 688 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 689 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 690 break; 691 case GL_DEPTH_COMPONENT16_OES: 692 case GL_DEPTH_STENCIL_OES: 693 case GL_DEPTH24_STENCIL8_OES: 694 return error(GL_INVALID_OPERATION); 695 default: 696 return error(GL_INVALID_ENUM); 697 } 698 699 if(border != 0) 700 { 701 return error(GL_INVALID_VALUE); 702 } 703 704 es1::Context *context = es1::getContext(); 705 706 if(context) 707 { 708 switch(target) 709 { 710 case GL_TEXTURE_2D: 711 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || 712 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) 713 { 714 return error(GL_INVALID_VALUE); 715 } 716 break; 717 default: 718 return error(GL_INVALID_ENUM); 719 } 720 721 if(imageSize != gl::ComputeCompressedSize(width, height, internalformat)) 722 { 723 return error(GL_INVALID_VALUE); 724 } 725 726 if(target == GL_TEXTURE_2D) 727 { 728 es1::Texture2D *texture = context->getTexture2D(); 729 730 if(!texture) 731 { 732 return error(GL_INVALID_OPERATION); 733 } 734 735 texture->setCompressedImage(level, internalformat, width, height, imageSize, data); 736 } 737 else UNREACHABLE(target); 738 } 739} 740 741void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, 742 GLenum format, GLsizei imageSize, const GLvoid* data) 743{ 744 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 745 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, " 746 "GLsizei imageSize = %d, const GLvoid* data = %p)", 747 target, level, xoffset, yoffset, width, height, format, imageSize, data); 748 749 if(!es1::IsTextureTarget(target)) 750 { 751 return error(GL_INVALID_ENUM); 752 } 753 754 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 755 { 756 return error(GL_INVALID_VALUE); 757 } 758 759 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0) 760 { 761 return error(GL_INVALID_VALUE); 762 } 763 764 switch(format) 765 { 766 case GL_ETC1_RGB8_OES: 767 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 768 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 769 break; 770 default: 771 return error(GL_INVALID_ENUM); 772 } 773 774 if(width == 0 || height == 0 || !data) 775 { 776 return; 777 } 778 779 es1::Context *context = es1::getContext(); 780 781 if(context) 782 { 783 if(imageSize != gl::ComputeCompressedSize(width, height, format)) 784 { 785 return error(GL_INVALID_VALUE); 786 } 787 788 if(xoffset % 4 != 0 || yoffset % 4 != 0) 789 { 790 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported 791 return error(GL_INVALID_OPERATION); 792 } 793 794 if(target == GL_TEXTURE_2D) 795 { 796 es1::Texture2D *texture = context->getTexture2D(); 797 798 GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE_OES, texture); 799 if(validationError != GL_NO_ERROR) 800 { 801 return error(validationError); 802 } 803 804 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); 805 } 806 else UNREACHABLE(target); 807 } 808} 809 810void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) 811{ 812 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " 813 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)", 814 target, level, internalformat, x, y, width, height, border); 815 816 if(!validImageSize(level, width, height)) 817 { 818 return error(GL_INVALID_VALUE); 819 } 820 821 if(border != 0) 822 { 823 return error(GL_INVALID_VALUE); 824 } 825 826 es1::Context *context = es1::getContext(); 827 828 if(context) 829 { 830 switch(target) 831 { 832 case GL_TEXTURE_2D: 833 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || 834 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) 835 { 836 return error(GL_INVALID_VALUE); 837 } 838 break; 839 default: 840 return error(GL_INVALID_ENUM); 841 } 842 843 es1::Framebuffer *framebuffer = context->getFramebuffer(); 844 845 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)) 846 { 847 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES); 848 } 849 850 es1::Renderbuffer *source = framebuffer->getColorbuffer(); 851 852 if(!source || source->getSamples() > 1) 853 { 854 return error(GL_INVALID_OPERATION); 855 } 856 857 GLenum colorbufferFormat = source->getFormat(); 858 859 // [OpenGL ES 1.1.12] table 3.9 860 switch(internalformat) 861 { 862 case GL_ALPHA: 863 if(colorbufferFormat != GL_ALPHA && 864 colorbufferFormat != GL_RGBA && 865 colorbufferFormat != GL_RGBA4_OES && 866 colorbufferFormat != GL_RGB5_A1_OES && 867 colorbufferFormat != GL_RGBA8_OES) 868 { 869 return error(GL_INVALID_OPERATION); 870 } 871 break; 872 case GL_LUMINANCE: 873 case GL_RGB: 874 if(colorbufferFormat != GL_RGB && 875 colorbufferFormat != GL_RGB565_OES && 876 colorbufferFormat != GL_RGB8_OES && 877 colorbufferFormat != GL_RGBA && 878 colorbufferFormat != GL_RGBA4_OES && 879 colorbufferFormat != GL_RGB5_A1_OES && 880 colorbufferFormat != GL_RGBA8_OES) 881 { 882 return error(GL_INVALID_OPERATION); 883 } 884 break; 885 case GL_LUMINANCE_ALPHA: 886 case GL_RGBA: 887 if(colorbufferFormat != GL_RGBA && 888 colorbufferFormat != GL_RGBA4_OES && 889 colorbufferFormat != GL_RGB5_A1_OES && 890 colorbufferFormat != GL_RGBA8_OES && 891 colorbufferFormat != GL_BGRA_EXT && // GL_EXT_texture_format_BGRA8888 892 colorbufferFormat != GL_BGRA8_EXT) // GL_EXT_texture_format_BGRA8888 893 { 894 return error(GL_INVALID_OPERATION); 895 } 896 break; 897 case GL_ETC1_RGB8_OES: 898 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 899 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 900 return error(GL_INVALID_OPERATION); 901 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888 doesn't mention the format to be accepted by glCopyTexImage2D. 902 default: 903 return error(GL_INVALID_ENUM); 904 } 905 906 // Determine the sized internal format. 907 if(gl::GetBaseInternalFormat(colorbufferFormat) == internalformat) 908 { 909 internalformat = colorbufferFormat; 910 } 911 else if(GetRedSize(colorbufferFormat) <= 8) 912 { 913 internalformat = gl::GetSizedInternalFormat(internalformat, GL_UNSIGNED_BYTE); 914 } 915 else 916 { 917 UNIMPLEMENTED(); 918 919 return error(GL_INVALID_OPERATION); 920 } 921 922 if(target == GL_TEXTURE_2D) 923 { 924 es1::Texture2D *texture = context->getTexture2D(); 925 926 if(!texture) 927 { 928 return error(GL_INVALID_OPERATION); 929 } 930 931 texture->copyImage(level, internalformat, x, y, width, height, framebuffer); 932 } 933 else UNREACHABLE(target); 934 } 935} 936 937void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) 938{ 939 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 940 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", 941 target, level, xoffset, yoffset, x, y, width, height); 942 943 if(!es1::IsTextureTarget(target)) 944 { 945 return error(GL_INVALID_ENUM); 946 } 947 948 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 949 { 950 return error(GL_INVALID_VALUE); 951 } 952 953 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0) 954 { 955 return error(GL_INVALID_VALUE); 956 } 957 958 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) 959 { 960 return error(GL_INVALID_VALUE); 961 } 962 963 if(width == 0 || height == 0) 964 { 965 return; 966 } 967 968 es1::Context *context = es1::getContext(); 969 970 if(context) 971 { 972 es1::Framebuffer *framebuffer = context->getFramebuffer(); 973 974 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)) 975 { 976 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES); 977 } 978 979 es1::Renderbuffer *source = framebuffer->getColorbuffer(); 980 981 if(context->getFramebufferName() != 0 && (!source || source->getSamples() > 1)) 982 { 983 return error(GL_INVALID_OPERATION); 984 } 985 986 es1::Texture *texture = nullptr; 987 988 if(target == GL_TEXTURE_2D) 989 { 990 texture = context->getTexture2D(); 991 } 992 else UNREACHABLE(target); 993 994 GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, width, height, GL_NONE_OES, GL_NONE_OES, texture); 995 if(validationError != GL_NO_ERROR) 996 { 997 return error(validationError); 998 } 999 1000 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer); 1001 } 1002} 1003 1004void CullFace(GLenum mode) 1005{ 1006 TRACE("(GLenum mode = 0x%X)", mode); 1007 1008 switch(mode) 1009 { 1010 case GL_FRONT: 1011 case GL_BACK: 1012 case GL_FRONT_AND_BACK: 1013 { 1014 es1::Context *context = es1::getContext(); 1015 1016 if(context) 1017 { 1018 context->setCullMode(mode); 1019 } 1020 } 1021 break; 1022 default: 1023 return error(GL_INVALID_ENUM); 1024 } 1025} 1026 1027void DeleteBuffers(GLsizei n, const GLuint* buffers) 1028{ 1029 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers); 1030 1031 if(n < 0) 1032 { 1033 return error(GL_INVALID_VALUE); 1034 } 1035 1036 es1::Context *context = es1::getContext(); 1037 1038 if(context) 1039 { 1040 for(int i = 0; i < n; i++) 1041 { 1042 context->deleteBuffer(buffers[i]); 1043 } 1044 } 1045} 1046 1047void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers) 1048{ 1049 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers); 1050 1051 if(n < 0) 1052 { 1053 return error(GL_INVALID_VALUE); 1054 } 1055 1056 es1::Context *context = es1::getContext(); 1057 1058 if(context) 1059 { 1060 for(int i = 0; i < n; i++) 1061 { 1062 if(framebuffers[i] != 0) 1063 { 1064 context->deleteFramebuffer(framebuffers[i]); 1065 } 1066 } 1067 } 1068} 1069 1070void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers) 1071{ 1072 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers); 1073 1074 if(n < 0) 1075 { 1076 return error(GL_INVALID_VALUE); 1077 } 1078 1079 es1::Context *context = es1::getContext(); 1080 1081 if(context) 1082 { 1083 for(int i = 0; i < n; i++) 1084 { 1085 context->deleteRenderbuffer(renderbuffers[i]); 1086 } 1087 } 1088} 1089 1090void DeleteTextures(GLsizei n, const GLuint* textures) 1091{ 1092 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures); 1093 1094 if(n < 0) 1095 { 1096 return error(GL_INVALID_VALUE); 1097 } 1098 1099 es1::Context *context = es1::getContext(); 1100 1101 if(context) 1102 { 1103 for(int i = 0; i < n; i++) 1104 { 1105 if(textures[i] != 0) 1106 { 1107 context->deleteTexture(textures[i]); 1108 } 1109 } 1110 } 1111} 1112 1113void DepthFunc(GLenum func) 1114{ 1115 TRACE("(GLenum func = 0x%X)", func); 1116 1117 switch(func) 1118 { 1119 case GL_NEVER: 1120 case GL_ALWAYS: 1121 case GL_LESS: 1122 case GL_LEQUAL: 1123 case GL_EQUAL: 1124 case GL_GREATER: 1125 case GL_GEQUAL: 1126 case GL_NOTEQUAL: 1127 break; 1128 default: 1129 return error(GL_INVALID_ENUM); 1130 } 1131 1132 es1::Context *context = es1::getContext(); 1133 1134 if(context) 1135 { 1136 context->setDepthFunc(func); 1137 } 1138} 1139 1140void DepthMask(GLboolean flag) 1141{ 1142 TRACE("(GLboolean flag = %d)", flag); 1143 1144 es1::Context *context = es1::getContext(); 1145 1146 if(context) 1147 { 1148 context->setDepthMask(flag != GL_FALSE); 1149 } 1150} 1151 1152void DepthRangef(GLclampf zNear, GLclampf zFar) 1153{ 1154 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar); 1155 1156 es1::Context *context = es1::getContext(); 1157 1158 if(context) 1159 { 1160 context->setDepthRange(zNear, zFar); 1161 } 1162} 1163 1164void DepthRangex(GLclampx zNear, GLclampx zFar) 1165{ 1166 DepthRangef((float)zNear / 0x10000, (float)zFar / 0x10000); 1167} 1168 1169void Disable(GLenum cap) 1170{ 1171 TRACE("(GLenum cap = 0x%X)", cap); 1172 1173 es1::Context *context = es1::getContext(); 1174 1175 if(context) 1176 { 1177 switch(cap) 1178 { 1179 case GL_CULL_FACE: context->setCullFaceEnabled(false); break; 1180 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(false); break; 1181 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break; 1182 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(false); break; 1183 case GL_SCISSOR_TEST: context->setScissorTestEnabled(false); break; 1184 case GL_STENCIL_TEST: context->setStencilTestEnabled(false); break; 1185 case GL_DEPTH_TEST: context->setDepthTestEnabled(false); break; 1186 case GL_BLEND: context->setBlendEnabled(false); break; 1187 case GL_DITHER: context->setDitherEnabled(false); break; 1188 case GL_LIGHTING: context->setLightingEnabled(false); break; 1189 case GL_LIGHT0: context->setLightEnabled(0, false); break; 1190 case GL_LIGHT1: context->setLightEnabled(1, false); break; 1191 case GL_LIGHT2: context->setLightEnabled(2, false); break; 1192 case GL_LIGHT3: context->setLightEnabled(3, false); break; 1193 case GL_LIGHT4: context->setLightEnabled(4, false); break; 1194 case GL_LIGHT5: context->setLightEnabled(5, false); break; 1195 case GL_LIGHT6: context->setLightEnabled(6, false); break; 1196 case GL_LIGHT7: context->setLightEnabled(7, false); break; 1197 case GL_FOG: context->setFogEnabled(false); break; 1198 case GL_TEXTURE_2D: context->setTexture2Denabled(false); break; 1199 case GL_TEXTURE_EXTERNAL_OES: context->setTextureExternalEnabled(false); break; 1200 case GL_ALPHA_TEST: context->setAlphaTestEnabled(false); break; 1201 case GL_COLOR_LOGIC_OP: context->setColorLogicOpEnabled(false); break; 1202 case GL_POINT_SMOOTH: context->setPointSmoothEnabled(false); break; 1203 case GL_LINE_SMOOTH: context->setLineSmoothEnabled(false); break; 1204 case GL_COLOR_MATERIAL: context->setColorMaterialEnabled(false); break; 1205 case GL_NORMALIZE: context->setNormalizeEnabled(false); break; 1206 case GL_RESCALE_NORMAL: context->setRescaleNormalEnabled(false); break; 1207 case GL_VERTEX_ARRAY: context->setVertexArrayEnabled(false); break; 1208 case GL_NORMAL_ARRAY: context->setNormalArrayEnabled(false); break; 1209 case GL_COLOR_ARRAY: context->setColorArrayEnabled(false); break; 1210 case GL_POINT_SIZE_ARRAY_OES: context->setPointSizeArrayEnabled(false); break; 1211 case GL_TEXTURE_COORD_ARRAY: context->setTextureCoordArrayEnabled(false); break; 1212 case GL_MULTISAMPLE: context->setMultisampleEnabled(false); break; 1213 case GL_SAMPLE_ALPHA_TO_ONE: context->setSampleAlphaToOneEnabled(false); break; 1214 case GL_CLIP_PLANE0: context->setClipPlaneEnabled(0, false); break; 1215 case GL_CLIP_PLANE1: context->setClipPlaneEnabled(1, false); break; 1216 case GL_CLIP_PLANE2: context->setClipPlaneEnabled(2, false); break; 1217 case GL_CLIP_PLANE3: context->setClipPlaneEnabled(3, false); break; 1218 case GL_CLIP_PLANE4: context->setClipPlaneEnabled(4, false); break; 1219 case GL_CLIP_PLANE5: context->setClipPlaneEnabled(5, false); break; 1220 case GL_POINT_SPRITE_OES: context->setPointSpriteEnabled(false); break; 1221 default: 1222 return error(GL_INVALID_ENUM); 1223 } 1224 } 1225} 1226 1227void DisableClientState(GLenum array) 1228{ 1229 TRACE("(GLenum array = 0x%X)", array); 1230 1231 switch(array) 1232 { 1233 case GL_VERTEX_ARRAY: 1234 case GL_NORMAL_ARRAY: 1235 case GL_COLOR_ARRAY: 1236 case GL_POINT_SIZE_ARRAY_OES: 1237 case GL_TEXTURE_COORD_ARRAY: 1238 break; 1239 default: 1240 return error(GL_INVALID_ENUM); 1241 } 1242 1243 es1::Context *context = es1::getContext(); 1244 1245 if(context) 1246 { 1247 GLenum texture = context->getClientActiveTexture(); 1248 1249 switch(array) 1250 { 1251 case GL_VERTEX_ARRAY: context->setVertexAttribArrayEnabled(sw::Position, false); break; 1252 case GL_NORMAL_ARRAY: context->setVertexAttribArrayEnabled(sw::Normal, false); break; 1253 case GL_COLOR_ARRAY: context->setVertexAttribArrayEnabled(sw::Color0, false); break; 1254 case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, false); break; 1255 case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break; 1256 default: UNREACHABLE(array); 1257 } 1258 } 1259} 1260 1261void DrawArrays(GLenum mode, GLint first, GLsizei count) 1262{ 1263 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); 1264 1265 if(count < 0 || first < 0) 1266 { 1267 return error(GL_INVALID_VALUE); 1268 } 1269 1270 es1::Context *context = es1::getContext(); 1271 1272 if(context) 1273 { 1274 context->drawArrays(mode, first, count); 1275 } 1276} 1277 1278void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) 1279{ 1280 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)", 1281 mode, count, type, indices); 1282 1283 if(count < 0) 1284 { 1285 return error(GL_INVALID_VALUE); 1286 } 1287 1288 es1::Context *context = es1::getContext(); 1289 1290 if(context) 1291 { 1292 switch(type) 1293 { 1294 case GL_UNSIGNED_BYTE: 1295 case GL_UNSIGNED_SHORT: 1296 case GL_UNSIGNED_INT: 1297 break; 1298 default: 1299 return error(GL_INVALID_ENUM); 1300 } 1301 1302 context->drawElements(mode, count, type, indices); 1303 } 1304} 1305 1306void Enable(GLenum cap) 1307{ 1308 TRACE("(GLenum cap = 0x%X)", cap); 1309 1310 es1::Context *context = es1::getContext(); 1311 1312 if(context) 1313 { 1314 switch(cap) 1315 { 1316 case GL_CULL_FACE: context->setCullFaceEnabled(true); break; 1317 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(true); break; 1318 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break; 1319 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(true); break; 1320 case GL_SCISSOR_TEST: context->setScissorTestEnabled(true); break; 1321 case GL_STENCIL_TEST: context->setStencilTestEnabled(true); break; 1322 case GL_DEPTH_TEST: context->setDepthTestEnabled(true); break; 1323 case GL_BLEND: context->setBlendEnabled(true); break; 1324 case GL_DITHER: context->setDitherEnabled(true); break; 1325 case GL_LIGHTING: context->setLightingEnabled(true); break; 1326 case GL_LIGHT0: context->setLightEnabled(0, true); break; 1327 case GL_LIGHT1: context->setLightEnabled(1, true); break; 1328 case GL_LIGHT2: context->setLightEnabled(2, true); break; 1329 case GL_LIGHT3: context->setLightEnabled(3, true); break; 1330 case GL_LIGHT4: context->setLightEnabled(4, true); break; 1331 case GL_LIGHT5: context->setLightEnabled(5, true); break; 1332 case GL_LIGHT6: context->setLightEnabled(6, true); break; 1333 case GL_LIGHT7: context->setLightEnabled(7, true); break; 1334 case GL_FOG: context->setFogEnabled(true); break; 1335 case GL_TEXTURE_2D: context->setTexture2Denabled(true); break; 1336 case GL_TEXTURE_EXTERNAL_OES: context->setTextureExternalEnabled(true); break; 1337 case GL_ALPHA_TEST: context->setAlphaTestEnabled(true); break; 1338 case GL_COLOR_LOGIC_OP: context->setColorLogicOpEnabled(true); break; 1339 case GL_POINT_SMOOTH: context->setPointSmoothEnabled(true); break; 1340 case GL_LINE_SMOOTH: context->setLineSmoothEnabled(true); break; 1341 case GL_COLOR_MATERIAL: context->setColorMaterialEnabled(true); break; 1342 case GL_NORMALIZE: context->setNormalizeEnabled(true); break; 1343 case GL_RESCALE_NORMAL: context->setRescaleNormalEnabled(true); break; 1344 case GL_VERTEX_ARRAY: context->setVertexArrayEnabled(true); break; 1345 case GL_NORMAL_ARRAY: context->setNormalArrayEnabled(true); break; 1346 case GL_COLOR_ARRAY: context->setColorArrayEnabled(true); break; 1347 case GL_POINT_SIZE_ARRAY_OES: context->setPointSizeArrayEnabled(true); break; 1348 case GL_TEXTURE_COORD_ARRAY: context->setTextureCoordArrayEnabled(true); break; 1349 case GL_MULTISAMPLE: context->setMultisampleEnabled(true); break; 1350 case GL_SAMPLE_ALPHA_TO_ONE: context->setSampleAlphaToOneEnabled(true); break; 1351 case GL_CLIP_PLANE0: context->setClipPlaneEnabled(0, true); break; 1352 case GL_CLIP_PLANE1: context->setClipPlaneEnabled(1, true); break; 1353 case GL_CLIP_PLANE2: context->setClipPlaneEnabled(2, true); break; 1354 case GL_CLIP_PLANE3: context->setClipPlaneEnabled(3, true); break; 1355 case GL_CLIP_PLANE4: context->setClipPlaneEnabled(4, true); break; 1356 case GL_CLIP_PLANE5: context->setClipPlaneEnabled(5, true); break; 1357 case GL_POINT_SPRITE_OES: context->setPointSpriteEnabled(true); break; 1358 default: 1359 return error(GL_INVALID_ENUM); 1360 } 1361 } 1362} 1363 1364void EnableClientState(GLenum array) 1365{ 1366 TRACE("(GLenum array = 0x%X)", array); 1367 1368 switch(array) 1369 { 1370 case GL_VERTEX_ARRAY: 1371 case GL_NORMAL_ARRAY: 1372 case GL_COLOR_ARRAY: 1373 case GL_POINT_SIZE_ARRAY_OES: 1374 case GL_TEXTURE_COORD_ARRAY: 1375 break; 1376 default: 1377 return error(GL_INVALID_ENUM); 1378 } 1379 1380 es1::Context *context = es1::getContext(); 1381 1382 if(context) 1383 { 1384 GLenum texture = context->getClientActiveTexture(); 1385 1386 switch(array) 1387 { 1388 case GL_VERTEX_ARRAY: context->setVertexAttribArrayEnabled(sw::Position, true); break; 1389 case GL_NORMAL_ARRAY: context->setVertexAttribArrayEnabled(sw::Normal, true); break; 1390 case GL_COLOR_ARRAY: context->setVertexAttribArrayEnabled(sw::Color0, true); break; 1391 case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, true); break; 1392 case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break; 1393 default: UNREACHABLE(array); 1394 } 1395 } 1396} 1397 1398void Finish(void) 1399{ 1400 TRACE("()"); 1401 1402 es1::Context *context = es1::getContext(); 1403 1404 if(context) 1405 { 1406 context->finish(); 1407 } 1408} 1409 1410void Flush(void) 1411{ 1412 TRACE("()"); 1413 1414 es1::Context *context = es1::getContext(); 1415 1416 if(context) 1417 { 1418 context->flush(); 1419 } 1420} 1421 1422void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) 1423{ 1424 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, " 1425 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer); 1426 1427 if(target != GL_FRAMEBUFFER_OES || (renderbuffertarget != GL_RENDERBUFFER_OES && renderbuffer != 0)) 1428 { 1429 return error(GL_INVALID_ENUM); 1430 } 1431 1432 es1::Context *context = es1::getContext(); 1433 1434 if(context) 1435 { 1436 es1::Framebuffer *framebuffer = context->getFramebuffer(); 1437 GLuint framebufferName = context->getFramebufferName(); 1438 1439 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0)) 1440 { 1441 return error(GL_INVALID_OPERATION); 1442 } 1443 1444 switch(attachment) 1445 { 1446 case GL_COLOR_ATTACHMENT0_OES: 1447 framebuffer->setColorbuffer(GL_RENDERBUFFER_OES, renderbuffer); 1448 break; 1449 case GL_DEPTH_ATTACHMENT_OES: 1450 framebuffer->setDepthbuffer(GL_RENDERBUFFER_OES, renderbuffer); 1451 break; 1452 case GL_STENCIL_ATTACHMENT_OES: 1453 framebuffer->setStencilbuffer(GL_RENDERBUFFER_OES, renderbuffer); 1454 break; 1455 default: 1456 return error(GL_INVALID_ENUM); 1457 } 1458 } 1459} 1460 1461void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) 1462{ 1463 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " 1464 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level); 1465 1466 if(target != GL_FRAMEBUFFER_OES) 1467 { 1468 return error(GL_INVALID_ENUM); 1469 } 1470 1471 switch(attachment) 1472 { 1473 case GL_COLOR_ATTACHMENT0_OES: 1474 case GL_DEPTH_ATTACHMENT_OES: 1475 case GL_STENCIL_ATTACHMENT_OES: 1476 break; 1477 default: 1478 return error(GL_INVALID_ENUM); 1479 } 1480 1481 es1::Context *context = es1::getContext(); 1482 1483 if(context) 1484 { 1485 if(texture == 0) 1486 { 1487 textarget = GL_NONE_OES; 1488 } 1489 else 1490 { 1491 es1::Texture *tex = context->getTexture(texture); 1492 1493 if(!tex) 1494 { 1495 return error(GL_INVALID_OPERATION); 1496 } 1497 1498 switch(textarget) 1499 { 1500 case GL_TEXTURE_2D: 1501 if(tex->getTarget() != GL_TEXTURE_2D) 1502 { 1503 return error(GL_INVALID_OPERATION); 1504 } 1505 break; 1506 default: 1507 return error(GL_INVALID_ENUM); 1508 } 1509 1510 if(level != 0) 1511 { 1512 return error(GL_INVALID_VALUE); 1513 } 1514 1515 if(tex->isCompressed(textarget, level)) 1516 { 1517 return error(GL_INVALID_OPERATION); 1518 } 1519 } 1520 1521 es1::Framebuffer *framebuffer = context->getFramebuffer(); 1522 GLuint framebufferName = context->getFramebufferName(); 1523 1524 if(framebufferName == 0 || !framebuffer) 1525 { 1526 return error(GL_INVALID_OPERATION); 1527 } 1528 1529 switch(attachment) 1530 { 1531 case GL_COLOR_ATTACHMENT0_OES: framebuffer->setColorbuffer(textarget, texture); break; 1532 case GL_DEPTH_ATTACHMENT_OES: framebuffer->setDepthbuffer(textarget, texture); break; 1533 case GL_STENCIL_ATTACHMENT_OES: framebuffer->setStencilbuffer(textarget, texture); break; 1534 } 1535 } 1536} 1537 1538void Fogf(GLenum pname, GLfloat param) 1539{ 1540 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param); 1541 1542 es1::Context *context = es1::getContext(); 1543 1544 if(context) 1545 { 1546 switch(pname) 1547 { 1548 case GL_FOG_MODE: 1549 switch((GLenum)param) 1550 { 1551 case GL_LINEAR: 1552 case GL_EXP: 1553 case GL_EXP2: 1554 context->setFogMode((GLenum)param); 1555 break; 1556 default: 1557 return error(GL_INVALID_ENUM); 1558 } 1559 break; 1560 case GL_FOG_DENSITY: 1561 if(param < 0) 1562 { 1563 return error(GL_INVALID_VALUE); 1564 } 1565 context->setFogDensity(param); 1566 break; 1567 case GL_FOG_START: 1568 context->setFogStart(param); 1569 break; 1570 case GL_FOG_END: 1571 context->setFogEnd(param); 1572 break; 1573 case GL_FOG_COLOR: 1574 return error(GL_INVALID_ENUM); // Need four values, should call glFogfv() instead 1575 default: 1576 return error(GL_INVALID_ENUM); 1577 } 1578 } 1579} 1580 1581void Fogfv(GLenum pname, const GLfloat *params) 1582{ 1583 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname); 1584 1585 es1::Context *context = es1::getContext(); 1586 1587 if(context) 1588 { 1589 switch(pname) 1590 { 1591 case GL_FOG_MODE: 1592 switch((GLenum)params[0]) 1593 { 1594 case GL_LINEAR: 1595 case GL_EXP: 1596 case GL_EXP2: 1597 context->setFogMode((GLenum)params[0]); 1598 break; 1599 default: 1600 return error(GL_INVALID_ENUM); 1601 } 1602 break; 1603 case GL_FOG_DENSITY: 1604 if(params[0] < 0) 1605 { 1606 return error(GL_INVALID_VALUE); 1607 } 1608 context->setFogDensity(params[0]); 1609 break; 1610 case GL_FOG_START: 1611 context->setFogStart(params[0]); 1612 break; 1613 case GL_FOG_END: 1614 context->setFogEnd(params[0]); 1615 break; 1616 case GL_FOG_COLOR: 1617 context->setFogColor(params[0], params[1], params[2], params[3]); 1618 break; 1619 default: 1620 return error(GL_INVALID_ENUM); 1621 } 1622 } 1623} 1624 1625void Fogx(GLenum pname, GLfixed param) 1626{ 1627 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param); 1628 1629 es1::Context *context = es1::getContext(); 1630 1631 if(context) 1632 { 1633 switch(pname) 1634 { 1635 case GL_FOG_MODE: 1636 switch((GLenum)param) 1637 { 1638 case GL_LINEAR: 1639 case GL_EXP: 1640 case GL_EXP2: 1641 context->setFogMode((GLenum)param); 1642 break; 1643 default: 1644 return error(GL_INVALID_ENUM); 1645 } 1646 break; 1647 case GL_FOG_DENSITY: 1648 if(param < 0) 1649 { 1650 return error(GL_INVALID_VALUE); 1651 } 1652 context->setFogDensity((float)param / 0x10000); 1653 break; 1654 case GL_FOG_START: 1655 context->setFogStart((float)param / 0x10000); 1656 break; 1657 case GL_FOG_END: 1658 context->setFogEnd((float)param / 0x10000); 1659 break; 1660 case GL_FOG_COLOR: 1661 return error(GL_INVALID_ENUM); // Need four values, should call glFogxv() instead 1662 default: 1663 return error(GL_INVALID_ENUM); 1664 } 1665 } 1666} 1667 1668void Fogxv(GLenum pname, const GLfixed *params) 1669{ 1670 UNIMPLEMENTED(); 1671} 1672 1673void FrontFace(GLenum mode) 1674{ 1675 TRACE("(GLenum mode = 0x%X)", mode); 1676 1677 switch(mode) 1678 { 1679 case GL_CW: 1680 case GL_CCW: 1681 { 1682 es1::Context *context = es1::getContext(); 1683 1684 if(context) 1685 { 1686 context->setFrontFace(mode); 1687 } 1688 } 1689 break; 1690 default: 1691 return error(GL_INVALID_ENUM); 1692 } 1693} 1694 1695void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) 1696{ 1697 TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar); 1698 1699 if(zNear <= 0.0f || zFar <= 0.0f || left == right || bottom == top || zNear == zFar) 1700 { 1701 return error(GL_INVALID_VALUE); 1702 } 1703 1704 es1::Context *context = es1::getContext(); 1705 1706 if(context) 1707 { 1708 context->frustum(left, right, bottom, top, zNear, zFar); 1709 } 1710} 1711 1712void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) 1713{ 1714 Frustumf((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000); 1715} 1716 1717void GenerateMipmapOES(GLenum target) 1718{ 1719 TRACE("(GLenum target = 0x%X)", target); 1720 1721 es1::Context *context = es1::getContext(); 1722 1723 if(context) 1724 { 1725 es1::Texture *texture; 1726 1727 switch(target) 1728 { 1729 case GL_TEXTURE_2D: 1730 texture = context->getTexture2D(); 1731 break; 1732 default: 1733 return error(GL_INVALID_ENUM); 1734 } 1735 1736 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0)) 1737 { 1738 return error(GL_INVALID_OPERATION); 1739 } 1740 1741 texture->generateMipmaps(); 1742 } 1743} 1744 1745void GenBuffers(GLsizei n, GLuint* buffers) 1746{ 1747 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers); 1748 1749 if(n < 0) 1750 { 1751 return error(GL_INVALID_VALUE); 1752 } 1753 1754 es1::Context *context = es1::getContext(); 1755 1756 if(context) 1757 { 1758 for(int i = 0; i < n; i++) 1759 { 1760 buffers[i] = context->createBuffer(); 1761 } 1762 } 1763} 1764 1765void GenFramebuffersOES(GLsizei n, GLuint* framebuffers) 1766{ 1767 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers); 1768 1769 if(n < 0) 1770 { 1771 return error(GL_INVALID_VALUE); 1772 } 1773 1774 es1::Context *context = es1::getContext(); 1775 1776 if(context) 1777 { 1778 for(int i = 0; i < n; i++) 1779 { 1780 framebuffers[i] = context->createFramebuffer(); 1781 } 1782 } 1783} 1784 1785void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers) 1786{ 1787 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers); 1788 1789 if(n < 0) 1790 { 1791 return error(GL_INVALID_VALUE); 1792 } 1793 1794 es1::Context *context = es1::getContext(); 1795 1796 if(context) 1797 { 1798 for(int i = 0; i < n; i++) 1799 { 1800 renderbuffers[i] = context->createRenderbuffer(); 1801 } 1802 } 1803} 1804 1805void GenTextures(GLsizei n, GLuint* textures) 1806{ 1807 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures); 1808 1809 if(n < 0) 1810 { 1811 return error(GL_INVALID_VALUE); 1812 } 1813 1814 es1::Context *context = es1::getContext(); 1815 1816 if(context) 1817 { 1818 for(int i = 0; i < n; i++) 1819 { 1820 textures[i] = context->createTexture(); 1821 } 1822 } 1823} 1824 1825void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params) 1826{ 1827 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params); 1828 1829 es1::Context *context = es1::getContext(); 1830 1831 if(context) 1832 { 1833 if(target != GL_RENDERBUFFER_OES) 1834 { 1835 return error(GL_INVALID_ENUM); 1836 } 1837 1838 if(context->getRenderbufferName() == 0) 1839 { 1840 return error(GL_INVALID_OPERATION); 1841 } 1842 1843 es1::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName()); 1844 1845 switch(pname) 1846 { 1847 case GL_RENDERBUFFER_WIDTH_OES: *params = renderbuffer->getWidth(); break; 1848 case GL_RENDERBUFFER_HEIGHT_OES: *params = renderbuffer->getHeight(); break; 1849 case GL_RENDERBUFFER_INTERNAL_FORMAT_OES: 1850 { 1851 GLint internalformat = renderbuffer->getFormat(); 1852 *params = (internalformat == GL_NONE_OES) ? GL_RGBA4_OES : internalformat; 1853 } 1854 break; 1855 case GL_RENDERBUFFER_RED_SIZE_OES: *params = renderbuffer->getRedSize(); break; 1856 case GL_RENDERBUFFER_GREEN_SIZE_OES: *params = renderbuffer->getGreenSize(); break; 1857 case GL_RENDERBUFFER_BLUE_SIZE_OES: *params = renderbuffer->getBlueSize(); break; 1858 case GL_RENDERBUFFER_ALPHA_SIZE_OES: *params = renderbuffer->getAlphaSize(); break; 1859 case GL_RENDERBUFFER_DEPTH_SIZE_OES: *params = renderbuffer->getDepthSize(); break; 1860 case GL_RENDERBUFFER_STENCIL_SIZE_OES: *params = renderbuffer->getStencilSize(); break; 1861 default: 1862 return error(GL_INVALID_ENUM); 1863 } 1864 } 1865} 1866 1867void GetBooleanv(GLenum pname, GLboolean* params) 1868{ 1869 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params); 1870 1871 es1::Context *context = es1::getContext(); 1872 1873 if(context) 1874 { 1875 if(!(context->getBooleanv(pname, params))) 1876 { 1877 int numParams = context->getQueryParameterNum(pname); 1878 1879 if(numParams < 0) 1880 { 1881 return error(GL_INVALID_ENUM); 1882 } 1883 1884 if(numParams == 0) 1885 { 1886 return; 1887 } 1888 1889 if(context->isQueryParameterFloat(pname)) 1890 { 1891 GLfloat *floatParams = nullptr; 1892 floatParams = new GLfloat[numParams]; 1893 1894 context->getFloatv(pname, floatParams); 1895 1896 for(int i = 0; i < numParams; ++i) 1897 { 1898 if(floatParams[i] == 0.0f) 1899 params[i] = GL_FALSE; 1900 else 1901 params[i] = GL_TRUE; 1902 } 1903 1904 delete [] floatParams; 1905 } 1906 else if(context->isQueryParameterInt(pname)) 1907 { 1908 GLint *intParams = nullptr; 1909 intParams = new GLint[numParams]; 1910 1911 context->getIntegerv(pname, intParams); 1912 1913 for(int i = 0; i < numParams; ++i) 1914 { 1915 if(intParams[i] == 0) 1916 params[i] = GL_FALSE; 1917 else 1918 params[i] = GL_TRUE; 1919 } 1920 1921 delete [] intParams; 1922 } 1923 else UNREACHABLE(pname); 1924 } 1925 } 1926} 1927 1928void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) 1929{ 1930 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params); 1931 1932 es1::Context *context = es1::getContext(); 1933 1934 if(context) 1935 { 1936 es1::Buffer *buffer; 1937 1938 switch(target) 1939 { 1940 case GL_ARRAY_BUFFER: 1941 buffer = context->getArrayBuffer(); 1942 break; 1943 case GL_ELEMENT_ARRAY_BUFFER: 1944 buffer = context->getElementArrayBuffer(); 1945 break; 1946 default: 1947 return error(GL_INVALID_ENUM); 1948 } 1949 1950 if(!buffer) 1951 { 1952 // A null buffer means that "0" is bound to the requested buffer target 1953 return error(GL_INVALID_OPERATION); 1954 } 1955 1956 switch(pname) 1957 { 1958 case GL_BUFFER_USAGE: 1959 *params = buffer->usage(); 1960 break; 1961 case GL_BUFFER_SIZE: 1962 *params = (GLint)buffer->size(); 1963 break; 1964 default: 1965 return error(GL_INVALID_ENUM); 1966 } 1967 } 1968} 1969 1970void GetClipPlanef(GLenum pname, GLfloat eqn[4]) 1971{ 1972 UNIMPLEMENTED(); 1973} 1974 1975void GetClipPlanex(GLenum pname, GLfixed eqn[4]) 1976{ 1977 UNIMPLEMENTED(); 1978} 1979 1980GLenum GetError(void) 1981{ 1982 TRACE("()"); 1983 1984 es1::Context *context = es1::getContext(); 1985 1986 if(context) 1987 { 1988 return context->getError(); 1989 } 1990 1991 return GL_NO_ERROR; 1992} 1993 1994void GetFixedv(GLenum pname, GLfixed *params) 1995{ 1996 UNIMPLEMENTED(); 1997} 1998 1999void GetFloatv(GLenum pname, GLfloat* params) 2000{ 2001 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params); 2002 2003 es1::Context *context = es1::getContext(); 2004 2005 if(context) 2006 { 2007 if(!(context->getFloatv(pname, params))) 2008 { 2009 int numParams = context->getQueryParameterNum(pname); 2010 2011 if(numParams < 0) 2012 { 2013 return error(GL_INVALID_ENUM); 2014 } 2015 2016 if(numParams == 0) 2017 { 2018 return; 2019 } 2020 2021 if(context->isQueryParameterBool(pname)) 2022 { 2023 GLboolean *boolParams = nullptr; 2024 boolParams = new GLboolean[numParams]; 2025 2026 context->getBooleanv(pname, boolParams); 2027 2028 for(int i = 0; i < numParams; ++i) 2029 { 2030 if(boolParams[i] == GL_FALSE) 2031 params[i] = 0.0f; 2032 else 2033 params[i] = 1.0f; 2034 } 2035 2036 delete [] boolParams; 2037 } 2038 else if(context->isQueryParameterInt(pname)) 2039 { 2040 GLint *intParams = nullptr; 2041 intParams = new GLint[numParams]; 2042 2043 context->getIntegerv(pname, intParams); 2044 2045 for(int i = 0; i < numParams; ++i) 2046 { 2047 params[i] = (GLfloat)intParams[i]; 2048 } 2049 2050 delete [] intParams; 2051 } 2052 else UNREACHABLE(pname); 2053 } 2054 } 2055} 2056 2057void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params) 2058{ 2059 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", 2060 target, attachment, pname, params); 2061 2062 es1::Context *context = es1::getContext(); 2063 2064 if(context) 2065 { 2066 if(target != GL_FRAMEBUFFER_OES) 2067 { 2068 return error(GL_INVALID_ENUM); 2069 } 2070 2071 if(context->getFramebufferName() == 0) 2072 { 2073 return error(GL_INVALID_OPERATION); 2074 } 2075 2076 es1::Framebuffer *framebuffer = context->getFramebuffer(); 2077 2078 if(!framebuffer) 2079 { 2080 return error(GL_INVALID_OPERATION); 2081 } 2082 2083 GLenum attachmentType; 2084 GLuint attachmentHandle; 2085 switch(attachment) 2086 { 2087 case GL_COLOR_ATTACHMENT0_OES: 2088 attachmentType = framebuffer->getColorbufferType(); 2089 attachmentHandle = framebuffer->getColorbufferName(); 2090 break; 2091 case GL_DEPTH_ATTACHMENT_OES: 2092 attachmentType = framebuffer->getDepthbufferType(); 2093 attachmentHandle = framebuffer->getDepthbufferName(); 2094 break; 2095 case GL_STENCIL_ATTACHMENT_OES: 2096 attachmentType = framebuffer->getStencilbufferType(); 2097 attachmentHandle = framebuffer->getStencilbufferName(); 2098 break; 2099 default: 2100 return error(GL_INVALID_ENUM); 2101 } 2102 2103 GLenum attachmentObjectType; // Type category 2104 if(attachmentType == GL_NONE_OES || attachmentType == GL_RENDERBUFFER_OES) 2105 { 2106 attachmentObjectType = attachmentType; 2107 } 2108 else if(es1::IsTextureTarget(attachmentType)) 2109 { 2110 attachmentObjectType = GL_TEXTURE; 2111 } 2112 else UNREACHABLE(attachmentType); 2113 2114 switch(pname) 2115 { 2116 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES: 2117 *params = attachmentObjectType; 2118 break; 2119 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES: 2120 if(attachmentObjectType == GL_RENDERBUFFER_OES || attachmentObjectType == GL_TEXTURE) 2121 { 2122 *params = attachmentHandle; 2123 } 2124 else 2125 { 2126 return error(GL_INVALID_ENUM); 2127 } 2128 break; 2129 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES: 2130 if(attachmentObjectType == GL_TEXTURE) 2131 { 2132 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0 2133 } 2134 else 2135 { 2136 return error(GL_INVALID_ENUM); 2137 } 2138 break; 2139 default: 2140 return error(GL_INVALID_ENUM); 2141 } 2142 } 2143} 2144 2145void GetIntegerv(GLenum pname, GLint* params) 2146{ 2147 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params); 2148 2149 es1::Context *context = es1::getContext(); 2150 2151 if(context) 2152 { 2153 if(!(context->getIntegerv(pname, params))) 2154 { 2155 int numParams = context->getQueryParameterNum(pname); 2156 2157 if(numParams < 0) 2158 { 2159 return error(GL_INVALID_ENUM); 2160 } 2161 2162 if(numParams == 0) 2163 { 2164 return; 2165 } 2166 2167 if(context->isQueryParameterBool(pname)) 2168 { 2169 GLboolean *boolParams = nullptr; 2170 boolParams = new GLboolean[numParams]; 2171 2172 context->getBooleanv(pname, boolParams); 2173 2174 for(int i = 0; i < numParams; ++i) 2175 { 2176 if(boolParams[i] == GL_FALSE) 2177 params[i] = 0; 2178 else 2179 params[i] = 1; 2180 } 2181 2182 delete [] boolParams; 2183 } 2184 else if(context->isQueryParameterFloat(pname)) 2185 { 2186 GLfloat *floatParams = nullptr; 2187 floatParams = new GLfloat[numParams]; 2188 2189 context->getFloatv(pname, floatParams); 2190 2191 for(int i = 0; i < numParams; ++i) 2192 { 2193 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE) 2194 { 2195 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f); 2196 } 2197 else 2198 { 2199 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5)); 2200 } 2201 } 2202 2203 delete [] floatParams; 2204 } 2205 else UNREACHABLE(pname); 2206 } 2207 } 2208} 2209 2210void GetLightfv(GLenum light, GLenum pname, GLfloat *params) 2211{ 2212 UNIMPLEMENTED(); 2213} 2214 2215void GetLightxv(GLenum light, GLenum pname, GLfixed *params) 2216{ 2217 UNIMPLEMENTED(); 2218} 2219 2220void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params) 2221{ 2222 UNIMPLEMENTED(); 2223} 2224 2225void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params) 2226{ 2227 UNIMPLEMENTED(); 2228} 2229 2230void GetPointerv(GLenum pname, GLvoid **params) 2231{ 2232 TRACE("(GLenum pname = 0x%X, GLvoid **params = %p)", pname, params); 2233 2234 es1::Context *context = es1::getContext(); 2235 2236 if(context) 2237 { 2238 if(!(context->getPointerv(pname, const_cast<const GLvoid**>(params)))) 2239 { 2240 return error(GL_INVALID_ENUM); 2241 } 2242 } 2243} 2244 2245const GLubyte* GetString(GLenum name) 2246{ 2247 TRACE("(GLenum name = 0x%X)", name); 2248 2249 switch(name) 2250 { 2251 case GL_VENDOR: 2252 return (GLubyte*)"Google Inc."; 2253 case GL_RENDERER: 2254 return (GLubyte*)"Google SwiftShader " VERSION_STRING; 2255 case GL_VERSION: 2256 return (GLubyte*)"OpenGL ES-CM 1.1"; 2257 case GL_EXTENSIONS: 2258 // Keep list sorted in following order: 2259 // OES extensions 2260 // EXT extensions 2261 // Vendor extensions 2262 return (GLubyte*) 2263 "GL_OES_blend_equation_separate " 2264 "GL_OES_blend_func_separate " 2265 "GL_OES_blend_subtract " 2266 "GL_OES_compressed_ETC1_RGB8_texture " 2267 "GL_OES_EGL_image " 2268 "GL_OES_EGL_image_external " 2269 "GL_OES_EGL_sync " 2270 "GL_OES_element_index_uint " 2271 "GL_OES_framebuffer_object " 2272 "GL_OES_packed_depth_stencil " 2273 "GL_OES_read_format " 2274 "GL_OES_rgb8_rgba8 " 2275 "GL_OES_stencil8 " 2276 "GL_OES_stencil_wrap " 2277 "GL_OES_surfaceless_context " 2278 "GL_OES_texture_mirrored_repeat " 2279 "GL_OES_texture_npot " 2280 "GL_EXT_blend_minmax " 2281 "GL_EXT_read_format_bgra " 2282 "GL_EXT_texture_compression_dxt1 " 2283 "GL_ANGLE_texture_compression_dxt3 " 2284 "GL_ANGLE_texture_compression_dxt5 " 2285 "GL_EXT_texture_filter_anisotropic " 2286 "GL_EXT_texture_format_BGRA8888"; 2287 default: 2288 return error(GL_INVALID_ENUM, (GLubyte*)nullptr); 2289 } 2290} 2291 2292void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) 2293{ 2294 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params); 2295 2296 es1::Context *context = es1::getContext(); 2297 2298 if(context) 2299 { 2300 es1::Texture *texture; 2301 2302 switch(target) 2303 { 2304 case GL_TEXTURE_2D: 2305 texture = context->getTexture2D(); 2306 break; 2307 case GL_TEXTURE_EXTERNAL_OES: 2308 texture = context->getTextureExternal(); 2309 break; 2310 default: 2311 return error(GL_INVALID_ENUM); 2312 } 2313 2314 switch(pname) 2315 { 2316 case GL_TEXTURE_MAG_FILTER: 2317 *params = (GLfloat)texture->getMagFilter(); 2318 break; 2319 case GL_TEXTURE_MIN_FILTER: 2320 *params = (GLfloat)texture->getMinFilter(); 2321 break; 2322 case GL_TEXTURE_WRAP_S: 2323 *params = (GLfloat)texture->getWrapS(); 2324 break; 2325 case GL_TEXTURE_WRAP_T: 2326 *params = (GLfloat)texture->getWrapT(); 2327 break; 2328 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 2329 *params = texture->getMaxAnisotropy(); 2330 break; 2331 case GL_GENERATE_MIPMAP: 2332 *params = (GLfloat)texture->getGenerateMipmap(); 2333 break; 2334 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 2335 *params = (GLfloat)1; 2336 break; 2337 default: 2338 return error(GL_INVALID_ENUM); 2339 } 2340 } 2341} 2342 2343void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) 2344{ 2345 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params); 2346 2347 es1::Context *context = es1::getContext(); 2348 2349 if(context) 2350 { 2351 es1::Texture *texture; 2352 2353 switch(target) 2354 { 2355 case GL_TEXTURE_2D: 2356 texture = context->getTexture2D(); 2357 break; 2358 case GL_TEXTURE_EXTERNAL_OES: 2359 texture = context->getTextureExternal(); 2360 break; 2361 default: 2362 return error(GL_INVALID_ENUM); 2363 } 2364 2365 switch(pname) 2366 { 2367 case GL_TEXTURE_MAG_FILTER: 2368 *params = texture->getMagFilter(); 2369 break; 2370 case GL_TEXTURE_MIN_FILTER: 2371 *params = texture->getMinFilter(); 2372 break; 2373 case GL_TEXTURE_WRAP_S: 2374 *params = texture->getWrapS(); 2375 break; 2376 case GL_TEXTURE_WRAP_T: 2377 *params = texture->getWrapT(); 2378 break; 2379 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 2380 *params = (GLint)texture->getMaxAnisotropy(); 2381 break; 2382 case GL_GENERATE_MIPMAP: 2383 *params = (GLint)texture->getGenerateMipmap(); 2384 break; 2385 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 2386 *params = 1; 2387 break; 2388 default: 2389 return error(GL_INVALID_ENUM); 2390 } 2391 } 2392} 2393 2394void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params) 2395{ 2396 UNIMPLEMENTED(); 2397} 2398 2399void GetTexEnviv(GLenum env, GLenum pname, GLint *params) 2400{ 2401 UNIMPLEMENTED(); 2402} 2403 2404void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params) 2405{ 2406 UNIMPLEMENTED(); 2407} 2408 2409void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params) 2410{ 2411 UNIMPLEMENTED(); 2412} 2413 2414void Hint(GLenum target, GLenum mode) 2415{ 2416 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); 2417 2418 switch(mode) 2419 { 2420 case GL_FASTEST: 2421 case GL_NICEST: 2422 case GL_DONT_CARE: 2423 break; 2424 default: 2425 return error(GL_INVALID_ENUM); 2426 } 2427 2428 es1::Context *context = es1::getContext(); 2429 2430 if(context) 2431 { 2432 switch(target) 2433 { 2434 case GL_GENERATE_MIPMAP_HINT: 2435 context->setGenerateMipmapHint(mode); 2436 break; 2437 case GL_PERSPECTIVE_CORRECTION_HINT: 2438 context->setPerspectiveCorrectionHint(mode); 2439 break; 2440 case GL_FOG_HINT: 2441 context->setFogHint(mode); 2442 break; 2443 default: 2444 return error(GL_INVALID_ENUM); 2445 } 2446 } 2447} 2448 2449GLboolean IsBuffer(GLuint buffer) 2450{ 2451 TRACE("(GLuint buffer = %d)", buffer); 2452 2453 es1::Context *context = es1::getContext(); 2454 2455 if(context && buffer) 2456 { 2457 es1::Buffer *bufferObject = context->getBuffer(buffer); 2458 2459 if(bufferObject) 2460 { 2461 return GL_TRUE; 2462 } 2463 } 2464 2465 return GL_FALSE; 2466} 2467 2468GLboolean IsEnabled(GLenum cap) 2469{ 2470 TRACE("(GLenum cap = 0x%X)", cap); 2471 2472 es1::Context *context = es1::getContext(); 2473 2474 if(context) 2475 { 2476 switch(cap) 2477 { 2478 case GL_CULL_FACE: return context->isCullFaceEnabled(); break; 2479 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled(); break; 2480 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break; 2481 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled(); break; 2482 case GL_SCISSOR_TEST: return context->isScissorTestEnabled(); break; 2483 case GL_STENCIL_TEST: return context->isStencilTestEnabled(); break; 2484 case GL_DEPTH_TEST: return context->isDepthTestEnabled(); break; 2485 case GL_BLEND: return context->isBlendEnabled(); break; 2486 case GL_DITHER: return context->isDitherEnabled(); break; 2487 case GL_LIGHTING: return context->isLightingEnabled(); break; 2488 case GL_LIGHT0: return context->isLightEnabled(0); break; 2489 case GL_LIGHT1: return context->isLightEnabled(1); break; 2490 case GL_LIGHT2: return context->isLightEnabled(2); break; 2491 case GL_LIGHT3: return context->isLightEnabled(3); break; 2492 case GL_LIGHT4: return context->isLightEnabled(4); break; 2493 case GL_LIGHT5: return context->isLightEnabled(5); break; 2494 case GL_LIGHT6: return context->isLightEnabled(6); break; 2495 case GL_LIGHT7: return context->isLightEnabled(7); break; 2496 case GL_FOG: return context->isFogEnabled(); break; 2497 case GL_TEXTURE_2D: return context->isTexture2Denabled(); break; 2498 case GL_TEXTURE_EXTERNAL_OES: return context->isTextureExternalEnabled(); break; 2499 case GL_ALPHA_TEST: return context->isAlphaTestEnabled(); break; 2500 case GL_COLOR_LOGIC_OP: return context->isColorLogicOpEnabled(); break; 2501 case GL_POINT_SMOOTH: return context->isPointSmoothEnabled(); break; 2502 case GL_LINE_SMOOTH: return context->isLineSmoothEnabled(); break; 2503 case GL_COLOR_MATERIAL: return context->isColorMaterialEnabled(); break; 2504 case GL_NORMALIZE: return context->isNormalizeEnabled(); break; 2505 case GL_RESCALE_NORMAL: return context->isRescaleNormalEnabled(); break; 2506 case GL_VERTEX_ARRAY: return context->isVertexArrayEnabled(); break; 2507 case GL_NORMAL_ARRAY: return context->isNormalArrayEnabled(); break; 2508 case GL_COLOR_ARRAY: return context->isColorArrayEnabled(); break; 2509 case GL_POINT_SIZE_ARRAY_OES: return context->isPointSizeArrayEnabled(); break; 2510 case GL_TEXTURE_COORD_ARRAY: return context->isTextureCoordArrayEnabled(); break; 2511 case GL_MULTISAMPLE: return context->isMultisampleEnabled(); break; 2512 case GL_SAMPLE_ALPHA_TO_ONE: return context->isSampleAlphaToOneEnabled(); break; 2513 case GL_CLIP_PLANE0: return context->isClipPlaneEnabled(0); break; 2514 case GL_CLIP_PLANE1: return context->isClipPlaneEnabled(1); break; 2515 case GL_CLIP_PLANE2: return context->isClipPlaneEnabled(2); break; 2516 case GL_CLIP_PLANE3: return context->isClipPlaneEnabled(3); break; 2517 case GL_CLIP_PLANE4: return context->isClipPlaneEnabled(4); break; 2518 case GL_CLIP_PLANE5: return context->isClipPlaneEnabled(5); break; 2519 case GL_POINT_SPRITE_OES: return context->isPointSpriteEnabled(); break; 2520 default: 2521 return error(GL_INVALID_ENUM, GL_FALSE); 2522 } 2523 } 2524 2525 return GL_FALSE; 2526} 2527 2528GLboolean IsFramebufferOES(GLuint framebuffer) 2529{ 2530 TRACE("(GLuint framebuffer = %d)", framebuffer); 2531 2532 es1::Context *context = es1::getContext(); 2533 2534 if(context && framebuffer) 2535 { 2536 es1::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer); 2537 2538 if(framebufferObject) 2539 { 2540 return GL_TRUE; 2541 } 2542 } 2543 2544 return GL_FALSE; 2545} 2546 2547GLboolean IsTexture(GLuint texture) 2548{ 2549 TRACE("(GLuint texture = %d)", texture); 2550 2551 es1::Context *context = es1::getContext(); 2552 2553 if(context && texture) 2554 { 2555 es1::Texture *textureObject = context->getTexture(texture); 2556 2557 if(textureObject) 2558 { 2559 return GL_TRUE; 2560 } 2561 } 2562 2563 return GL_FALSE; 2564} 2565 2566GLboolean IsRenderbufferOES(GLuint renderbuffer) 2567{ 2568 TRACE("(GLuint renderbuffer = %d)", renderbuffer); 2569 2570 es1::Context *context = es1::getContext(); 2571 2572 if(context && renderbuffer) 2573 { 2574 es1::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer); 2575 2576 if(renderbufferObject) 2577 { 2578 return GL_TRUE; 2579 } 2580 } 2581 2582 return GL_FALSE; 2583} 2584 2585void LightModelf(GLenum pname, GLfloat param) 2586{ 2587 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param); 2588 2589 es1::Context *context = es1::getContext(); 2590 2591 if(context) 2592 { 2593 switch(pname) 2594 { 2595 case GL_LIGHT_MODEL_TWO_SIDE: 2596 context->setLightModelTwoSide(param != 0.0f); 2597 break; 2598 case GL_LIGHT_MODEL_AMBIENT: 2599 return error(GL_INVALID_ENUM); // Need four values, should call glLightModelfv() instead 2600 default: 2601 return error(GL_INVALID_ENUM); 2602 } 2603 } 2604} 2605 2606void LightModelfv(GLenum pname, const GLfloat *params) 2607{ 2608 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname); 2609 2610 es1::Context *context = es1::getContext(); 2611 2612 if(context) 2613 { 2614 switch(pname) 2615 { 2616 case GL_LIGHT_MODEL_AMBIENT: 2617 context->setGlobalAmbient(params[0], params[1], params[2], params[3]); 2618 break; 2619 case GL_LIGHT_MODEL_TWO_SIDE: 2620 context->setLightModelTwoSide(params[0] != 0.0f); 2621 break; 2622 default: 2623 return error(GL_INVALID_ENUM); 2624 } 2625 } 2626} 2627 2628void LightModelx(GLenum pname, GLfixed param) 2629{ 2630 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param); 2631 2632 es1::Context *context = es1::getContext(); 2633 2634 if(context) 2635 { 2636 switch(pname) 2637 { 2638 case GL_LIGHT_MODEL_TWO_SIDE: 2639 context->setLightModelTwoSide(param != 0); 2640 break; 2641 case GL_LIGHT_MODEL_AMBIENT: 2642 return error(GL_INVALID_ENUM); // Need four values, should call glLightModelxv() instead 2643 default: 2644 return error(GL_INVALID_ENUM); 2645 } 2646 } 2647} 2648 2649void LightModelxv(GLenum pname, const GLfixed *params) 2650{ 2651 TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname); 2652 2653 es1::Context *context = es1::getContext(); 2654 2655 if(context) 2656 { 2657 switch(pname) 2658 { 2659 case GL_LIGHT_MODEL_AMBIENT: 2660 context->setGlobalAmbient((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000, (float)params[3] / 0x10000); 2661 break; 2662 case GL_LIGHT_MODEL_TWO_SIDE: 2663 context->setLightModelTwoSide(params[0] != 0); 2664 break; 2665 default: 2666 return error(GL_INVALID_ENUM); 2667 } 2668 } 2669} 2670 2671void Lightf(GLenum light, GLenum pname, GLfloat param) 2672{ 2673 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", light, pname, param); 2674 2675 int index = light - GL_LIGHT0; 2676 2677 if(index < 0 || index >= es1::MAX_LIGHTS) 2678 { 2679 return error(GL_INVALID_ENUM); 2680 } 2681 2682 es1::Context *context = es1::getContext(); 2683 2684 if(context) 2685 { 2686 switch(pname) 2687 { 2688 case GL_SPOT_EXPONENT: 2689 if(param < 0.0f || param > 128.0f) 2690 { 2691 return error(GL_INVALID_VALUE); 2692 } 2693 context->setSpotLightExponent(index, param); 2694 break; 2695 case GL_SPOT_CUTOFF: 2696 if((param < 0.0f || param > 90.0f) && param != 180.0f) 2697 { 2698 return error(GL_INVALID_VALUE); 2699 } 2700 context->setSpotLightCutoff(index, param); 2701 break; 2702 case GL_CONSTANT_ATTENUATION: 2703 if(param < 0.0f) 2704 { 2705 return error(GL_INVALID_VALUE); 2706 } 2707 context->setLightAttenuationConstant(index, param); 2708 break; 2709 case GL_LINEAR_ATTENUATION: 2710 if(param < 0.0f) 2711 { 2712 return error(GL_INVALID_VALUE); 2713 } 2714 context->setLightAttenuationLinear(index, param); 2715 break; 2716 case GL_QUADRATIC_ATTENUATION: 2717 if(param < 0.0f) 2718 { 2719 return error(GL_INVALID_VALUE); 2720 } 2721 context->setLightAttenuationQuadratic(index, param); 2722 break; 2723 case GL_AMBIENT: 2724 case GL_DIFFUSE: 2725 case GL_SPECULAR: 2726 case GL_POSITION: 2727 case GL_SPOT_DIRECTION: 2728 return error(GL_INVALID_ENUM); // Need four values, should call glLightfv() instead 2729 default: 2730 return error(GL_INVALID_ENUM); 2731 } 2732 } 2733} 2734 2735void Lightfv(GLenum light, GLenum pname, const GLfloat *params) 2736{ 2737 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname); 2738 2739 es1::Context *context = es1::getContext(); 2740 2741 if(context) 2742 { 2743 int index = light - GL_LIGHT0; 2744 2745 if(index < 0 || index > es1::MAX_LIGHTS) 2746 { 2747 return error(GL_INVALID_ENUM); 2748 } 2749 2750 switch(pname) 2751 { 2752 case GL_AMBIENT: context->setLightAmbient(index, params[0], params[1], params[2], params[3]); break; 2753 case GL_DIFFUSE: context->setLightDiffuse(index, params[0], params[1], params[2], params[3]); break; 2754 case GL_SPECULAR: context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break; 2755 case GL_POSITION: context->setLightPosition(index, params[0], params[1], params[2], params[3]); break; 2756 case GL_SPOT_DIRECTION: context->setLightDirection(index, params[0], params[1], params[2]); break; 2757 case GL_SPOT_EXPONENT: 2758 if(params[0] < 0.0f || params[0] > 128.0f) 2759 { 2760 return error(GL_INVALID_VALUE); 2761 } 2762 context->setSpotLightExponent(index, params[0]); 2763 break; 2764 case GL_SPOT_CUTOFF: 2765 if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f) 2766 { 2767 return error(GL_INVALID_VALUE); 2768 } 2769 context->setSpotLightCutoff(index, params[0]); 2770 break; 2771 case GL_CONSTANT_ATTENUATION: 2772 if(params[0] < 0.0f) 2773 { 2774 return error(GL_INVALID_VALUE); 2775 } 2776 context->setLightAttenuationConstant(index, params[0]); 2777 break; 2778 case GL_LINEAR_ATTENUATION: 2779 if(params[0] < 0.0f) 2780 { 2781 return error(GL_INVALID_VALUE); 2782 } 2783 context->setLightAttenuationLinear(index, params[0]); 2784 break; 2785 case GL_QUADRATIC_ATTENUATION: 2786 if(params[0] < 0.0f) 2787 { 2788 return error(GL_INVALID_VALUE); 2789 } 2790 context->setLightAttenuationQuadratic(index, params[0]); 2791 break; 2792 default: 2793 return error(GL_INVALID_ENUM); 2794 } 2795 } 2796} 2797 2798void Lightx(GLenum light, GLenum pname, GLfixed param) 2799{ 2800 UNIMPLEMENTED(); 2801} 2802 2803void Lightxv(GLenum light, GLenum pname, const GLfixed *params) 2804{ 2805 UNIMPLEMENTED(); 2806} 2807 2808void LineWidth(GLfloat width) 2809{ 2810 TRACE("(GLfloat width = %f)", width); 2811 2812 if(width <= 0.0f) 2813 { 2814 return error(GL_INVALID_VALUE); 2815 } 2816 2817 es1::Context *context = es1::getContext(); 2818 2819 if(context) 2820 { 2821 context->setLineWidth(width); 2822 } 2823} 2824 2825void LineWidthx(GLfixed width) 2826{ 2827 LineWidth((float)width / 0x10000); 2828} 2829 2830void LoadIdentity(void) 2831{ 2832 TRACE("()"); 2833 2834 es1::Context *context = es1::getContext(); 2835 2836 if(context) 2837 { 2838 context->loadIdentity(); 2839 } 2840} 2841 2842void LoadMatrixf(const GLfloat *m) 2843{ 2844 TRACE("(const GLfloat *m)"); 2845 2846 es1::Context *context = es1::getContext(); 2847 2848 if(context) 2849 { 2850 context->load(m); 2851 } 2852} 2853 2854void LoadMatrixx(const GLfixed *m) 2855{ 2856 GLfloat matrix[16] = 2857 { 2858 (float)m[0] / 0x10000, (float)m[1] / 0x10000, (float)m[2] / 0x10000, (float)m[3] / 0x10000, 2859 (float)m[4] / 0x10000, (float)m[5] / 0x10000, (float)m[6] / 0x10000, (float)m[7] / 0x10000, 2860 (float)m[8] / 0x10000, (float)m[9] / 0x10000, (float)m[10] / 0x10000, (float)m[11] / 0x10000, 2861 (float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000 2862 }; 2863 2864 LoadMatrixf(matrix); 2865} 2866 2867void LogicOp(GLenum opcode) 2868{ 2869 TRACE("(GLenum opcode = 0x%X)", opcode); 2870 2871 switch(opcode) 2872 { 2873 case GL_CLEAR: 2874 case GL_SET: 2875 case GL_COPY: 2876 case GL_COPY_INVERTED: 2877 case GL_NOOP: 2878 case GL_INVERT: 2879 case GL_AND: 2880 case GL_NAND: 2881 case GL_OR: 2882 case GL_NOR: 2883 case GL_XOR: 2884 case GL_EQUIV: 2885 case GL_AND_REVERSE: 2886 case GL_AND_INVERTED: 2887 case GL_OR_REVERSE: 2888 case GL_OR_INVERTED: 2889 break; 2890 default: 2891 return error(GL_INVALID_ENUM); 2892 } 2893 2894 es1::Context *context = es1::getContext(); 2895 2896 if(context) 2897 { 2898 context->setLogicalOperation(opcode); 2899 } 2900} 2901 2902void Materialf(GLenum face, GLenum pname, GLfloat param) 2903{ 2904 TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", face, pname, param); 2905 2906 if(face != GL_FRONT_AND_BACK) 2907 { 2908 return error(GL_INVALID_ENUM); 2909 } 2910 2911 es1::Context *context = es1::getContext(); 2912 2913 if(context) 2914 { 2915 switch(pname) 2916 { 2917 case GL_SHININESS: 2918 if(param < 0.0f || param > 128.0f) 2919 { 2920 return error(GL_INVALID_VALUE); 2921 } 2922 context->setMaterialShininess(param); 2923 break; 2924 case GL_AMBIENT: 2925 case GL_DIFFUSE: 2926 case GL_AMBIENT_AND_DIFFUSE: 2927 case GL_SPECULAR: 2928 case GL_EMISSION: 2929 return error(GL_INVALID_ENUM); // Need four values, should call glMaterialfv() instead 2930 default: 2931 return error(GL_INVALID_ENUM); 2932 } 2933 } 2934} 2935 2936void Materialfv(GLenum face, GLenum pname, const GLfloat *params) 2937{ 2938 TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname); 2939 2940 if(face != GL_FRONT_AND_BACK) 2941 { 2942 return error(GL_INVALID_ENUM); 2943 } 2944 2945 es1::Context *context = es1::getContext(); 2946 2947 if(context) 2948 { 2949 switch(pname) 2950 { 2951 case GL_AMBIENT: 2952 context->setMaterialAmbient(params[0], params[1], params[2], params[3]); 2953 break; 2954 case GL_DIFFUSE: 2955 context->setMaterialDiffuse(params[0], params[1], params[2], params[3]); 2956 break; 2957 case GL_AMBIENT_AND_DIFFUSE: 2958 context->setMaterialAmbient(params[0], params[1], params[2], params[3]); 2959 context->setMaterialDiffuse(params[0], params[1], params[2], params[3]); 2960 break; 2961 case GL_SPECULAR: 2962 context->setMaterialSpecular(params[0], params[1], params[2], params[3]); 2963 break; 2964 case GL_EMISSION: 2965 context->setMaterialEmission(params[0], params[1], params[2], params[3]); 2966 break; 2967 case GL_SHININESS: 2968 context->setMaterialShininess(params[0]); 2969 break; 2970 default: 2971 return error(GL_INVALID_ENUM); 2972 } 2973 } 2974} 2975 2976void Materialx(GLenum face, GLenum pname, GLfixed param) 2977{ 2978 UNIMPLEMENTED(); 2979} 2980 2981void Materialxv(GLenum face, GLenum pname, const GLfixed *params) 2982{ 2983 UNIMPLEMENTED(); 2984} 2985 2986void MatrixMode(GLenum mode) 2987{ 2988 TRACE("(GLenum mode = 0x%X)", mode); 2989 2990 es1::Context *context = es1::getContext(); 2991 2992 if(context) 2993 { 2994 context->setMatrixMode(mode); 2995 } 2996} 2997 2998void MultMatrixf(const GLfloat *m) 2999{ 3000 TRACE("(const GLfloat *m)"); 3001 3002 es1::Context *context = es1::getContext(); 3003 3004 if(context) 3005 { 3006 context->multiply(m); 3007 } 3008} 3009 3010void MultMatrixx(const GLfixed *m) 3011{ 3012 GLfloat matrix[16] = 3013 { 3014 (float)m[0] / 0x10000, (float)m[1] / 0x10000, (float)m[2] / 0x10000, (float)m[3] / 0x10000, 3015 (float)m[4] / 0x10000, (float)m[5] / 0x10000, (float)m[6] / 0x10000, (float)m[7] / 0x10000, 3016 (float)m[8] / 0x10000, (float)m[9] / 0x10000, (float)m[10] / 0x10000, (float)m[11] / 0x10000, 3017 (float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000 3018 }; 3019 3020 MultMatrixf(matrix); 3021} 3022 3023void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) 3024{ 3025 TRACE("(GLenum target = 0x%X, GLfloat s = %f, GLfloat t = %f, GLfloat r = %f, GLfloat q = %f)", target, s, t, r, q); 3026 3027 switch(target) 3028 { 3029 case GL_TEXTURE0: 3030 case GL_TEXTURE1: 3031 break; 3032 default: 3033 return error(GL_INVALID_ENUM); 3034 } 3035 3036 es1::Context *context = es1::getContext(); 3037 3038 if(context) 3039 { 3040 context->setVertexAttrib(sw::TexCoord0 + (target - GL_TEXTURE0), s, t, r, q); 3041 } 3042} 3043 3044void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) 3045{ 3046 UNIMPLEMENTED(); 3047} 3048 3049void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz) 3050{ 3051 TRACE("(GLfloat nx, GLfloat ny, GLfloat nz)", nx, ny, nz); 3052 3053 es1::Context *context = es1::getContext(); 3054 3055 if(context) 3056 { 3057 context->setVertexAttrib(sw::Normal, nx, ny, nz, 0); 3058 } 3059} 3060 3061void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz) 3062{ 3063 UNIMPLEMENTED(); 3064} 3065 3066void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) 3067{ 3068 TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer); 3069 3070 VertexAttribPointer(sw::Normal, 3, type, true, stride, pointer); 3071} 3072 3073void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) 3074{ 3075 TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar); 3076 3077 if(left == right || bottom == top || zNear == zFar) 3078 { 3079 return error(GL_INVALID_VALUE); 3080 } 3081 3082 es1::Context *context = es1::getContext(); 3083 3084 if(context) 3085 { 3086 context->ortho(left, right, bottom, top, zNear, zFar); 3087 } 3088} 3089 3090void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) 3091{ 3092 Orthof((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000); 3093} 3094 3095void PixelStorei(GLenum pname, GLint param) 3096{ 3097 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param); 3098 3099 es1::Context *context = es1::getContext(); 3100 3101 if(context) 3102 { 3103 switch(pname) 3104 { 3105 case GL_UNPACK_ALIGNMENT: 3106 if(param != 1 && param != 2 && param != 4 && param != 8) 3107 { 3108 return error(GL_INVALID_VALUE); 3109 } 3110 3111 context->setUnpackAlignment(param); 3112 break; 3113 case GL_PACK_ALIGNMENT: 3114 if(param != 1 && param != 2 && param != 4 && param != 8) 3115 { 3116 return error(GL_INVALID_VALUE); 3117 } 3118 3119 context->setPackAlignment(param); 3120 break; 3121 default: 3122 return error(GL_INVALID_ENUM); 3123 } 3124 } 3125} 3126 3127void PointParameterf(GLenum pname, GLfloat param) 3128{ 3129 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param); 3130 3131 es1::Context *context = es1::getContext(); 3132 3133 if(context) 3134 { 3135 switch(pname) 3136 { 3137 case GL_POINT_SIZE_MIN: 3138 if(param < 0.0f) 3139 { 3140 return error(GL_INVALID_VALUE); 3141 } 3142 context->setPointSizeMin(param); 3143 break; 3144 case GL_POINT_SIZE_MAX: 3145 if(param < 0.0f) 3146 { 3147 return error(GL_INVALID_VALUE); 3148 } 3149 context->setPointSizeMax(param); 3150 break; 3151 case GL_POINT_FADE_THRESHOLD_SIZE: 3152 if(param < 0.0f) 3153 { 3154 return error(GL_INVALID_VALUE); 3155 } 3156 context->setPointFadeThresholdSize(param); 3157 break; 3158 case GL_POINT_DISTANCE_ATTENUATION: 3159 return error(GL_INVALID_ENUM); // Needs three values, should call glPointParameterfv() instead 3160 default: 3161 return error(GL_INVALID_ENUM); 3162 } 3163 } 3164} 3165 3166void PointParameterfv(GLenum pname, const GLfloat *params) 3167{ 3168 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname); 3169 3170 es1::Context *context = es1::getContext(); 3171 3172 if(context) 3173 { 3174 switch(pname) 3175 { 3176 case GL_POINT_SIZE_MIN: 3177 if(params[0] < 0.0f) 3178 { 3179 return error(GL_INVALID_VALUE); 3180 } 3181 context->setPointSizeMin(params[0]); 3182 break; 3183 case GL_POINT_SIZE_MAX: 3184 if(params[0] < 0.0f) 3185 { 3186 return error(GL_INVALID_VALUE); 3187 } 3188 context->setPointSizeMax(params[0]); 3189 break; 3190 case GL_POINT_DISTANCE_ATTENUATION: 3191 context->setPointDistanceAttenuation(params[0], params[1], params[2]); 3192 break; 3193 case GL_POINT_FADE_THRESHOLD_SIZE: 3194 if(params[0] < 0.0f) 3195 { 3196 return error(GL_INVALID_VALUE); 3197 } 3198 context->setPointFadeThresholdSize(params[0]); 3199 break; 3200 default: 3201 return error(GL_INVALID_ENUM); 3202 } 3203 } 3204} 3205 3206void PointParameterx(GLenum pname, GLfixed param) 3207{ 3208 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param); 3209 3210 es1::Context *context = es1::getContext(); 3211 3212 if(context) 3213 { 3214 switch(pname) 3215 { 3216 case GL_POINT_SIZE_MIN: 3217 if(param < 0) 3218 { 3219 return error(GL_INVALID_VALUE); 3220 } 3221 context->setPointSizeMin((float)param / 0x10000); 3222 break; 3223 case GL_POINT_SIZE_MAX: 3224 if(param < 0) 3225 { 3226 return error(GL_INVALID_VALUE); 3227 } 3228 context->setPointSizeMax((float)param / 0x10000); 3229 break; 3230 case GL_POINT_FADE_THRESHOLD_SIZE: 3231 if(param < 0) 3232 { 3233 return error(GL_INVALID_VALUE); 3234 } 3235 context->setPointFadeThresholdSize((float)param / 0x10000); 3236 break; 3237 case GL_POINT_DISTANCE_ATTENUATION: 3238 return error(GL_INVALID_ENUM); // Needs three parameters, should call glPointParameterxv() instead 3239 default: 3240 return error(GL_INVALID_ENUM); 3241 } 3242 } 3243} 3244 3245void PointParameterxv(GLenum pname, const GLfixed *params) 3246{ 3247 TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname); 3248 3249 es1::Context *context = es1::getContext(); 3250 3251 if(context) 3252 { 3253 switch(pname) 3254 { 3255 case GL_POINT_SIZE_MIN: 3256 if(params[0] < 0) 3257 { 3258 return error(GL_INVALID_VALUE); 3259 } 3260 context->setPointSizeMin((float)params[0] / 0x10000); 3261 break; 3262 case GL_POINT_SIZE_MAX: 3263 if(params[0] < 0) 3264 { 3265 return error(GL_INVALID_VALUE); 3266 } 3267 context->setPointSizeMax((float)params[0] / 0x10000); 3268 break; 3269 case GL_POINT_DISTANCE_ATTENUATION: 3270 context->setPointDistanceAttenuation((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000); 3271 break; 3272 case GL_POINT_FADE_THRESHOLD_SIZE: 3273 if(params[0] < 0) 3274 { 3275 return error(GL_INVALID_VALUE); 3276 } 3277 context->setPointFadeThresholdSize((float)params[0] / 0x10000); 3278 break; 3279 default: 3280 return error(GL_INVALID_ENUM); 3281 } 3282 } 3283} 3284 3285void PointSize(GLfloat size) 3286{ 3287 TRACE("(GLfloat size = %f)", size); 3288 3289 if(size <= 0) 3290 { 3291 return error(GL_INVALID_VALUE); 3292 } 3293 3294 es1::Context *context = es1::getContext(); 3295 3296 if(context) 3297 { 3298 context->setVertexAttrib(sw::PointSize, size, size, size, size); 3299 } 3300} 3301 3302void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer) 3303{ 3304 TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer); 3305 3306 switch(type) 3307 { 3308 case GL_FIXED: 3309 case GL_FLOAT: 3310 break; 3311 default: 3312 return error(GL_INVALID_ENUM); 3313 } 3314 3315 VertexAttribPointer(sw::PointSize, 1, type, true, stride, pointer); 3316} 3317 3318void PointSizex(GLfixed size) 3319{ 3320 PointSize((float)size / 0x10000); 3321} 3322 3323void PolygonOffset(GLfloat factor, GLfloat units) 3324{ 3325 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units); 3326 3327 es1::Context *context = es1::getContext(); 3328 3329 if(context) 3330 { 3331 context->setPolygonOffsetParams(factor, units); 3332 } 3333} 3334 3335void PolygonOffsetx(GLfixed factor, GLfixed units) 3336{ 3337 PolygonOffset((float)factor / 0x10000, (float)units / 0x10000); 3338} 3339 3340void PopMatrix(void) 3341{ 3342 TRACE("()"); 3343 3344 es1::Context *context = es1::getContext(); 3345 3346 if(context) 3347 { 3348 context->popMatrix(); 3349 } 3350} 3351 3352void PushMatrix(void) 3353{ 3354 TRACE("()"); 3355 3356 es1::Context *context = es1::getContext(); 3357 3358 if(context) 3359 { 3360 context->pushMatrix(); 3361 } 3362} 3363 3364void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) 3365{ 3366 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " 3367 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)", 3368 x, y, width, height, format, type, pixels); 3369 3370 if(width < 0 || height < 0) 3371 { 3372 return error(GL_INVALID_VALUE); 3373 } 3374 3375 es1::Context *context = es1::getContext(); 3376 3377 if(context) 3378 { 3379 context->readPixels(x, y, width, height, format, type, nullptr, pixels); 3380 } 3381} 3382 3383void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) 3384{ 3385 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", 3386 target, internalformat, width, height); 3387 3388 switch(target) 3389 { 3390 case GL_RENDERBUFFER_OES: 3391 break; 3392 default: 3393 return error(GL_INVALID_ENUM); 3394 } 3395 3396 if(!es1::IsColorRenderable(internalformat) && !es1::IsDepthRenderable(internalformat) && !es1::IsStencilRenderable(internalformat)) 3397 { 3398 return error(GL_INVALID_ENUM); 3399 } 3400 3401 if(width < 0 || height < 0) 3402 { 3403 return error(GL_INVALID_VALUE); 3404 } 3405 3406 es1::Context *context = es1::getContext(); 3407 3408 if(context) 3409 { 3410 if(width > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE || 3411 height > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE) 3412 { 3413 return error(GL_INVALID_VALUE); 3414 } 3415 3416 GLuint handle = context->getRenderbufferName(); 3417 if(handle == 0) 3418 { 3419 return error(GL_INVALID_OPERATION); 3420 } 3421 3422 switch(internalformat) 3423 { 3424 case GL_RGBA4_OES: 3425 case GL_RGB5_A1_OES: 3426 case GL_RGB565_OES: 3427 case GL_RGB8_OES: 3428 case GL_RGBA8_OES: 3429 context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0)); 3430 break; 3431 case GL_DEPTH_COMPONENT16_OES: 3432 context->setRenderbufferStorage(new es1::Depthbuffer(width, height, internalformat, 0)); 3433 break; 3434 case GL_STENCIL_INDEX8_OES: 3435 context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0)); 3436 break; 3437 case GL_DEPTH24_STENCIL8_OES: 3438 context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, internalformat, 0)); 3439 break; 3440 default: 3441 return error(GL_INVALID_ENUM); 3442 } 3443 } 3444} 3445 3446void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) 3447{ 3448 TRACE("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z); 3449 3450 es1::Context *context = es1::getContext(); 3451 3452 if(context) 3453 { 3454 context->rotate(angle, x, y, z); 3455 } 3456} 3457 3458void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) 3459{ 3460 Rotatef((float)angle / 0x10000, (float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000); 3461} 3462 3463void SampleCoverage(GLclampf value, GLboolean invert) 3464{ 3465 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert); 3466 3467 es1::Context* context = es1::getContext(); 3468 3469 if(context) 3470 { 3471 context->setSampleCoverageParams(es1::clamp01(value), invert == GL_TRUE); 3472 } 3473} 3474 3475void SampleCoveragex(GLclampx value, GLboolean invert) 3476{ 3477 SampleCoverage((float)value / 0x10000, invert); 3478} 3479 3480void Scalef(GLfloat x, GLfloat y, GLfloat z) 3481{ 3482 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z); 3483 3484 es1::Context *context = es1::getContext(); 3485 3486 if(context) 3487 { 3488 context->scale(x, y, z); 3489 } 3490} 3491 3492void Scalex(GLfixed x, GLfixed y, GLfixed z) 3493{ 3494 Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000); 3495} 3496 3497void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) 3498{ 3499 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); 3500 3501 if(width < 0 || height < 0) 3502 { 3503 return error(GL_INVALID_VALUE); 3504 } 3505 3506 es1::Context* context = es1::getContext(); 3507 3508 if(context) 3509 { 3510 context->setScissorParams(x, y, width, height); 3511 } 3512} 3513 3514void ShadeModel(GLenum mode) 3515{ 3516 switch(mode) 3517 { 3518 case GL_FLAT: 3519 case GL_SMOOTH: 3520 break; 3521 default: 3522 return error(GL_INVALID_ENUM); 3523 } 3524 3525 es1::Context *context = es1::getContext(); 3526 3527 if(context) 3528 { 3529 context->setShadeModel(mode); 3530 } 3531} 3532 3533void StencilFunc(GLenum func, GLint ref, GLuint mask) 3534{ 3535 TRACE("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", func, ref, mask); 3536 3537 switch(func) 3538 { 3539 case GL_NEVER: 3540 case GL_ALWAYS: 3541 case GL_LESS: 3542 case GL_LEQUAL: 3543 case GL_EQUAL: 3544 case GL_GEQUAL: 3545 case GL_GREATER: 3546 case GL_NOTEQUAL: 3547 break; 3548 default: 3549 return error(GL_INVALID_ENUM); 3550 } 3551 3552 es1::Context *context = es1::getContext(); 3553 3554 if(context) 3555 { 3556 context->setStencilParams(func, ref, mask); 3557 } 3558} 3559 3560void StencilMask(GLuint mask) 3561{ 3562 TRACE("(GLuint mask = %d)", mask); 3563 3564 es1::Context *context = es1::getContext(); 3565 3566 if(context) 3567 { 3568 context->setStencilWritemask(mask); 3569 } 3570} 3571 3572void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) 3573{ 3574 TRACE("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", fail, zfail, zpass); 3575 3576 switch(fail) 3577 { 3578 case GL_ZERO: 3579 case GL_KEEP: 3580 case GL_REPLACE: 3581 case GL_INCR: 3582 case GL_DECR: 3583 case GL_INVERT: 3584 case GL_INCR_WRAP_OES: 3585 case GL_DECR_WRAP_OES: 3586 break; 3587 default: 3588 return error(GL_INVALID_ENUM); 3589 } 3590 3591 switch(zfail) 3592 { 3593 case GL_ZERO: 3594 case GL_KEEP: 3595 case GL_REPLACE: 3596 case GL_INCR: 3597 case GL_DECR: 3598 case GL_INVERT: 3599 case GL_INCR_WRAP_OES: 3600 case GL_DECR_WRAP_OES: 3601 break; 3602 default: 3603 return error(GL_INVALID_ENUM); 3604 } 3605 3606 switch(zpass) 3607 { 3608 case GL_ZERO: 3609 case GL_KEEP: 3610 case GL_REPLACE: 3611 case GL_INCR: 3612 case GL_DECR: 3613 case GL_INVERT: 3614 case GL_INCR_WRAP_OES: 3615 case GL_DECR_WRAP_OES: 3616 break; 3617 default: 3618 return error(GL_INVALID_ENUM); 3619 } 3620 3621 es1::Context *context = es1::getContext(); 3622 3623 if(context) 3624 { 3625 context->setStencilOperations(fail, zfail, zpass); 3626 } 3627} 3628 3629void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) 3630{ 3631 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer); 3632 3633 if(size < 2 || size > 4) 3634 { 3635 return error(GL_INVALID_VALUE); 3636 } 3637 3638 es1::Context *context = es1::getContext(); 3639 3640 if(context) 3641 { 3642 GLenum texture = context->getClientActiveTexture(); 3643 VertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer); 3644 } 3645} 3646 3647void TexEnvi(GLenum target, GLenum pname, GLint param); 3648 3649void TexEnvf(GLenum target, GLenum pname, GLfloat param) 3650{ 3651 TexEnvi(target, pname, (GLint)param); 3652} 3653 3654void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params) 3655{ 3656 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params)", target, pname); 3657 3658 es1::Context *context = es1::getContext(); 3659 3660 if(context) 3661 { 3662 GLint iParam = (GLint)roundf(params[0]); 3663 3664 switch(target) 3665 { 3666 case GL_POINT_SPRITE_OES: 3667 UNIMPLEMENTED(); 3668 break; 3669 case GL_TEXTURE_ENV: 3670 switch(pname) 3671 { 3672 case GL_TEXTURE_ENV_MODE: 3673 switch(iParam) 3674 { 3675 case GL_REPLACE: 3676 case GL_MODULATE: 3677 case GL_DECAL: 3678 case GL_BLEND: 3679 case GL_ADD: 3680 case GL_COMBINE: 3681 break; 3682 default: 3683 error(GL_INVALID_ENUM); 3684 } 3685 3686 context->setTextureEnvMode(iParam); 3687 break; 3688 case GL_TEXTURE_ENV_COLOR: 3689 context->setTextureEnvColor(clamp01(params[0]), clamp01(params[1]), clamp01(params[2]), clamp01(params[3])); 3690 break; 3691 case GL_COMBINE_RGB: 3692 switch(iParam) 3693 { 3694 case GL_REPLACE: 3695 case GL_MODULATE: 3696 case GL_ADD: 3697 case GL_ADD_SIGNED: 3698 case GL_INTERPOLATE: 3699 case GL_SUBTRACT: 3700 case GL_DOT3_RGB: 3701 case GL_DOT3_RGBA: 3702 break; 3703 default: 3704 error(GL_INVALID_ENUM); 3705 } 3706 3707 context->setCombineRGB(iParam); 3708 break; 3709 case GL_COMBINE_ALPHA: 3710 switch(iParam) 3711 { 3712 case GL_REPLACE: 3713 case GL_MODULATE: 3714 case GL_ADD: 3715 case GL_ADD_SIGNED: 3716 case GL_INTERPOLATE: 3717 case GL_SUBTRACT: 3718 break; 3719 default: 3720 error(GL_INVALID_ENUM); 3721 } 3722 3723 context->setCombineAlpha(iParam); 3724 break; 3725 case GL_RGB_SCALE: 3726 if(iParam != 1 && iParam != 2 && iParam != 4) 3727 { 3728 return error(GL_INVALID_VALUE); 3729 } 3730 if(iParam != 1) UNIMPLEMENTED(); 3731 break; 3732 case GL_ALPHA_SCALE: 3733 if(iParam != 1 && iParam != 2 && iParam != 4) 3734 { 3735 return error(GL_INVALID_VALUE); 3736 } 3737 if(iParam != 1) UNIMPLEMENTED(); 3738 break; 3739 case GL_OPERAND0_RGB: 3740 switch(iParam) 3741 { 3742 case GL_SRC_COLOR: 3743 case GL_ONE_MINUS_SRC_COLOR: 3744 case GL_SRC_ALPHA: 3745 case GL_ONE_MINUS_SRC_ALPHA: 3746 break; 3747 default: 3748 error(GL_INVALID_ENUM); 3749 } 3750 3751 context->setOperand0RGB(iParam); 3752 break; 3753 case GL_OPERAND1_RGB: 3754 switch(iParam) 3755 { 3756 case GL_SRC_COLOR: 3757 case GL_ONE_MINUS_SRC_COLOR: 3758 case GL_SRC_ALPHA: 3759 case GL_ONE_MINUS_SRC_ALPHA: 3760 break; 3761 default: 3762 error(GL_INVALID_ENUM); 3763 } 3764 3765 context->setOperand1RGB(iParam); 3766 break; 3767 case GL_OPERAND2_RGB: 3768 switch(iParam) 3769 { 3770 case GL_SRC_COLOR: 3771 case GL_ONE_MINUS_SRC_COLOR: 3772 case GL_SRC_ALPHA: 3773 case GL_ONE_MINUS_SRC_ALPHA: 3774 break; 3775 default: 3776 error(GL_INVALID_ENUM); 3777 } 3778 3779 context->setOperand2RGB(iParam); 3780 break; 3781 case GL_OPERAND0_ALPHA: 3782 switch(iParam) 3783 { 3784 case GL_SRC_ALPHA: 3785 case GL_ONE_MINUS_SRC_ALPHA: 3786 break; 3787 default: 3788 error(GL_INVALID_ENUM); 3789 } 3790 3791 context->setOperand0Alpha(iParam); 3792 break; 3793 case GL_OPERAND1_ALPHA: 3794 switch(iParam) 3795 { 3796 case GL_SRC_ALPHA: 3797 case GL_ONE_MINUS_SRC_ALPHA: 3798 break; 3799 default: 3800 error(GL_INVALID_ENUM); 3801 } 3802 3803 context->setOperand1Alpha(iParam); 3804 break; 3805 case GL_OPERAND2_ALPHA: 3806 switch(iParam) 3807 { 3808 case GL_SRC_ALPHA: 3809 case GL_ONE_MINUS_SRC_ALPHA: 3810 break; 3811 default: 3812 error(GL_INVALID_ENUM); 3813 } 3814 3815 context->setOperand2Alpha(iParam); 3816 break; 3817 case GL_SRC0_RGB: 3818 switch(iParam) 3819 { 3820 case GL_TEXTURE: 3821 case GL_CONSTANT: 3822 case GL_PRIMARY_COLOR: 3823 case GL_PREVIOUS: 3824 break; 3825 default: 3826 error(GL_INVALID_ENUM); 3827 } 3828 3829 context->setSrc0RGB(iParam); 3830 break; 3831 case GL_SRC1_RGB: 3832 switch(iParam) 3833 { 3834 case GL_TEXTURE: 3835 case GL_CONSTANT: 3836 case GL_PRIMARY_COLOR: 3837 case GL_PREVIOUS: 3838 break; 3839 default: 3840 error(GL_INVALID_ENUM); 3841 } 3842 3843 context->setSrc1RGB(iParam); 3844 break; 3845 case GL_SRC2_RGB: 3846 switch(iParam) 3847 { 3848 case GL_TEXTURE: 3849 case GL_CONSTANT: 3850 case GL_PRIMARY_COLOR: 3851 case GL_PREVIOUS: 3852 break; 3853 default: 3854 error(GL_INVALID_ENUM); 3855 } 3856 3857 context->setSrc2RGB(iParam); 3858 break; 3859 case GL_SRC0_ALPHA: 3860 switch(iParam) 3861 { 3862 case GL_TEXTURE: 3863 case GL_CONSTANT: 3864 case GL_PRIMARY_COLOR: 3865 case GL_PREVIOUS: 3866 break; 3867 default: 3868 error(GL_INVALID_ENUM); 3869 } 3870 3871 context->setSrc0Alpha(iParam); 3872 break; 3873 case GL_SRC1_ALPHA: 3874 switch(iParam) 3875 { 3876 case GL_TEXTURE: 3877 case GL_CONSTANT: 3878 case GL_PRIMARY_COLOR: 3879 case GL_PREVIOUS: 3880 break; 3881 default: 3882 error(GL_INVALID_ENUM); 3883 } 3884 3885 context->setSrc1Alpha(iParam); 3886 break; 3887 case GL_SRC2_ALPHA: 3888 switch(iParam) 3889 { 3890 case GL_TEXTURE: 3891 case GL_CONSTANT: 3892 case GL_PRIMARY_COLOR: 3893 case GL_PREVIOUS: 3894 break; 3895 default: 3896 error(GL_INVALID_ENUM); 3897 } 3898 3899 context->setSrc2Alpha(iParam); 3900 break; 3901 default: 3902 return error(GL_INVALID_ENUM); 3903 } 3904 break; 3905 default: 3906 return error(GL_INVALID_ENUM); 3907 } 3908 } 3909} 3910 3911void TexEnvi(GLenum target, GLenum pname, GLint param) 3912{ 3913 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); 3914 3915 es1::Context *context = es1::getContext(); 3916 3917 if(context) 3918 { 3919 switch(target) 3920 { 3921 case GL_POINT_SPRITE_OES: 3922 UNIMPLEMENTED(); 3923 break; 3924 case GL_TEXTURE_ENV: 3925 switch(pname) 3926 { 3927 case GL_TEXTURE_ENV_MODE: 3928 switch((GLenum)param) 3929 { 3930 case GL_REPLACE: 3931 case GL_MODULATE: 3932 case GL_DECAL: 3933 case GL_BLEND: 3934 case GL_ADD: 3935 case GL_COMBINE: 3936 break; 3937 default: 3938 error(GL_INVALID_ENUM); 3939 } 3940 3941 context->setTextureEnvMode((GLenum)param); 3942 break; 3943 case GL_TEXTURE_ENV_COLOR: 3944 return error(GL_INVALID_ENUM); // Needs four values, should call glTexEnviv() instead 3945 break; 3946 case GL_COMBINE_RGB: 3947 switch((GLenum)param) 3948 { 3949 case GL_REPLACE: 3950 case GL_MODULATE: 3951 case GL_ADD: 3952 case GL_ADD_SIGNED: 3953 case GL_INTERPOLATE: 3954 case GL_SUBTRACT: 3955 case GL_DOT3_RGB: 3956 case GL_DOT3_RGBA: 3957 break; 3958 default: 3959 error(GL_INVALID_ENUM); 3960 } 3961 3962 context->setCombineRGB((GLenum)param); 3963 break; 3964 case GL_COMBINE_ALPHA: 3965 switch((GLenum)param) 3966 { 3967 case GL_REPLACE: 3968 case GL_MODULATE: 3969 case GL_ADD: 3970 case GL_ADD_SIGNED: 3971 case GL_INTERPOLATE: 3972 case GL_SUBTRACT: 3973 break; 3974 default: 3975 error(GL_INVALID_ENUM); 3976 } 3977 3978 context->setCombineAlpha((GLenum)param); 3979 break; 3980 case GL_RGB_SCALE: 3981 if(param != 1 && param != 2 && param != 4) 3982 { 3983 return error(GL_INVALID_VALUE); 3984 } 3985 if(param != 1) UNIMPLEMENTED(); 3986 break; 3987 case GL_ALPHA_SCALE: 3988 if(param != 1 && param != 2 && param != 4) 3989 { 3990 return error(GL_INVALID_VALUE); 3991 } 3992 if(param != 1) UNIMPLEMENTED(); 3993 break; 3994 case GL_OPERAND0_RGB: 3995 switch((GLenum)param) 3996 { 3997 case GL_SRC_COLOR: 3998 case GL_ONE_MINUS_SRC_COLOR: 3999 case GL_SRC_ALPHA: 4000 case GL_ONE_MINUS_SRC_ALPHA: 4001 break; 4002 default: 4003 error(GL_INVALID_ENUM); 4004 } 4005 4006 context->setOperand0RGB((GLenum)param); 4007 break; 4008 case GL_OPERAND1_RGB: 4009 switch((GLenum)param) 4010 { 4011 case GL_SRC_COLOR: 4012 case GL_ONE_MINUS_SRC_COLOR: 4013 case GL_SRC_ALPHA: 4014 case GL_ONE_MINUS_SRC_ALPHA: 4015 break; 4016 default: 4017 error(GL_INVALID_ENUM); 4018 } 4019 4020 context->setOperand1RGB((GLenum)param); 4021 break; 4022 case GL_OPERAND2_RGB: 4023 switch((GLenum)param) 4024 { 4025 case GL_SRC_COLOR: 4026 case GL_ONE_MINUS_SRC_COLOR: 4027 case GL_SRC_ALPHA: 4028 case GL_ONE_MINUS_SRC_ALPHA: 4029 break; 4030 default: 4031 error(GL_INVALID_ENUM); 4032 } 4033 4034 context->setOperand2RGB((GLenum)param); 4035 break; 4036 case GL_OPERAND0_ALPHA: 4037 switch((GLenum)param) 4038 { 4039 case GL_SRC_ALPHA: 4040 case GL_ONE_MINUS_SRC_ALPHA: 4041 break; 4042 default: 4043 error(GL_INVALID_ENUM); 4044 } 4045 4046 context->setOperand0Alpha((GLenum)param); 4047 break; 4048 case GL_OPERAND1_ALPHA: 4049 switch((GLenum)param) 4050 { 4051 case GL_SRC_ALPHA: 4052 case GL_ONE_MINUS_SRC_ALPHA: 4053 break; 4054 default: 4055 error(GL_INVALID_ENUM); 4056 } 4057 4058 context->setOperand1Alpha((GLenum)param); 4059 break; 4060 case GL_OPERAND2_ALPHA: 4061 switch((GLenum)param) 4062 { 4063 case GL_SRC_ALPHA: 4064 case GL_ONE_MINUS_SRC_ALPHA: 4065 break; 4066 default: 4067 error(GL_INVALID_ENUM); 4068 } 4069 4070 context->setOperand2Alpha((GLenum)param); 4071 break; 4072 case GL_SRC0_RGB: 4073 switch((GLenum)param) 4074 { 4075 case GL_TEXTURE: 4076 case GL_CONSTANT: 4077 case GL_PRIMARY_COLOR: 4078 case GL_PREVIOUS: 4079 break; 4080 default: 4081 error(GL_INVALID_ENUM); 4082 } 4083 4084 context->setSrc0RGB((GLenum)param); 4085 break; 4086 case GL_SRC1_RGB: 4087 switch((GLenum)param) 4088 { 4089 case GL_TEXTURE: 4090 case GL_CONSTANT: 4091 case GL_PRIMARY_COLOR: 4092 case GL_PREVIOUS: 4093 break; 4094 default: 4095 error(GL_INVALID_ENUM); 4096 } 4097 4098 context->setSrc1RGB((GLenum)param); 4099 break; 4100 case GL_SRC2_RGB: 4101 switch((GLenum)param) 4102 { 4103 case GL_TEXTURE: 4104 case GL_CONSTANT: 4105 case GL_PRIMARY_COLOR: 4106 case GL_PREVIOUS: 4107 break; 4108 default: 4109 error(GL_INVALID_ENUM); 4110 } 4111 4112 context->setSrc2RGB((GLenum)param); 4113 break; 4114 case GL_SRC0_ALPHA: 4115 switch((GLenum)param) 4116 { 4117 case GL_TEXTURE: 4118 case GL_CONSTANT: 4119 case GL_PRIMARY_COLOR: 4120 case GL_PREVIOUS: 4121 break; 4122 default: 4123 error(GL_INVALID_ENUM); 4124 } 4125 4126 context->setSrc0Alpha((GLenum)param); 4127 break; 4128 case GL_SRC1_ALPHA: 4129 switch((GLenum)param) 4130 { 4131 case GL_TEXTURE: 4132 case GL_CONSTANT: 4133 case GL_PRIMARY_COLOR: 4134 case GL_PREVIOUS: 4135 break; 4136 default: 4137 error(GL_INVALID_ENUM); 4138 } 4139 4140 context->setSrc1Alpha((GLenum)param); 4141 break; 4142 case GL_SRC2_ALPHA: 4143 switch((GLenum)param) 4144 { 4145 case GL_TEXTURE: 4146 case GL_CONSTANT: 4147 case GL_PRIMARY_COLOR: 4148 case GL_PREVIOUS: 4149 break; 4150 default: 4151 error(GL_INVALID_ENUM); 4152 } 4153 4154 context->setSrc2Alpha((GLenum)param); 4155 break; 4156 default: 4157 return error(GL_INVALID_ENUM); 4158 } 4159 break; 4160 default: 4161 return error(GL_INVALID_ENUM); 4162 } 4163 } 4164} 4165 4166void TexEnvx(GLenum target, GLenum pname, GLfixed param) 4167{ 4168 TexEnvi(target, pname, (GLint)param); 4169} 4170 4171void TexEnviv(GLenum target, GLenum pname, const GLint *params) 4172{ 4173 UNIMPLEMENTED(); 4174} 4175 4176void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params) 4177{ 4178 UNIMPLEMENTED(); 4179} 4180 4181void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, 4182 GLint border, GLenum format, GLenum type, const GLvoid* pixels) 4183{ 4184 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " 4185 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)", 4186 target, level, internalformat, width, height, border, format, type, pixels); 4187 4188 if(!validImageSize(level, width, height)) 4189 { 4190 return error(GL_INVALID_VALUE); 4191 } 4192 4193 if(internalformat != (GLint)format) 4194 { 4195 return error(GL_INVALID_OPERATION); 4196 } 4197 4198 switch(format) 4199 { 4200 case GL_ALPHA: 4201 case GL_LUMINANCE: 4202 case GL_LUMINANCE_ALPHA: 4203 switch(type) 4204 { 4205 case GL_UNSIGNED_BYTE: 4206 break; 4207 default: 4208 return error(GL_INVALID_ENUM); 4209 } 4210 break; 4211 case GL_RGB: 4212 switch(type) 4213 { 4214 case GL_UNSIGNED_BYTE: 4215 case GL_UNSIGNED_SHORT_5_6_5: 4216 break; 4217 default: 4218 return error(GL_INVALID_ENUM); 4219 } 4220 break; 4221 case GL_RGBA: 4222 switch(type) 4223 { 4224 case GL_UNSIGNED_BYTE: 4225 case GL_UNSIGNED_SHORT_4_4_4_4: 4226 case GL_UNSIGNED_SHORT_5_5_5_1: 4227 break; 4228 default: 4229 return error(GL_INVALID_ENUM); 4230 } 4231 break; 4232 case GL_BGRA_EXT: 4233 switch(type) 4234 { 4235 case GL_UNSIGNED_BYTE: 4236 break; 4237 default: 4238 return error(GL_INVALID_ENUM); 4239 } 4240 break; 4241 case GL_ETC1_RGB8_OES: 4242 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 4243 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 4244 return error(GL_INVALID_OPERATION); 4245 case GL_DEPTH_STENCIL_OES: 4246 switch(type) 4247 { 4248 case GL_UNSIGNED_INT_24_8_OES: 4249 break; 4250 default: 4251 return error(GL_INVALID_ENUM); 4252 } 4253 break; 4254 default: 4255 return error(GL_INVALID_VALUE); 4256 } 4257 4258 if(border != 0) 4259 { 4260 return error(GL_INVALID_VALUE); 4261 } 4262 4263 GLint sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type); 4264 4265 es1::Context *context = es1::getContext(); 4266 4267 if(context) 4268 { 4269 switch(target) 4270 { 4271 case GL_TEXTURE_2D: 4272 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || 4273 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) 4274 { 4275 return error(GL_INVALID_VALUE); 4276 } 4277 break; 4278 default: 4279 return error(GL_INVALID_ENUM); 4280 } 4281 4282 if(target == GL_TEXTURE_2D) 4283 { 4284 es1::Texture2D *texture = context->getTexture2D(); 4285 4286 if(!texture) 4287 { 4288 return error(GL_INVALID_OPERATION); 4289 } 4290 4291 texture->setImage(level, width, height, sizedInternalFormat, format, type, context->getUnpackAlignment(), pixels); 4292 } 4293 else UNREACHABLE(target); 4294 } 4295} 4296 4297void TexParameterf(GLenum target, GLenum pname, GLfloat param) 4298{ 4299 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param); 4300 4301 es1::Context *context = es1::getContext(); 4302 4303 if(context) 4304 { 4305 es1::Texture *texture; 4306 4307 switch(target) 4308 { 4309 case GL_TEXTURE_2D: 4310 texture = context->getTexture2D(); 4311 break; 4312 case GL_TEXTURE_EXTERNAL_OES: 4313 texture = context->getTextureExternal(); 4314 break; 4315 default: 4316 return error(GL_INVALID_ENUM); 4317 } 4318 4319 switch(pname) 4320 { 4321 case GL_TEXTURE_WRAP_S: 4322 if(!texture->setWrapS((GLenum)param)) 4323 { 4324 return error(GL_INVALID_ENUM); 4325 } 4326 break; 4327 case GL_TEXTURE_WRAP_T: 4328 if(!texture->setWrapT((GLenum)param)) 4329 { 4330 return error(GL_INVALID_ENUM); 4331 } 4332 break; 4333 case GL_TEXTURE_MIN_FILTER: 4334 if(!texture->setMinFilter((GLenum)param)) 4335 { 4336 return error(GL_INVALID_ENUM); 4337 } 4338 break; 4339 case GL_TEXTURE_MAG_FILTER: 4340 if(!texture->setMagFilter((GLenum)param)) 4341 { 4342 return error(GL_INVALID_ENUM); 4343 } 4344 break; 4345 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 4346 if(!texture->setMaxAnisotropy(param)) 4347 { 4348 return error(GL_INVALID_VALUE); 4349 } 4350 break; 4351 case GL_GENERATE_MIPMAP: 4352 texture->setGenerateMipmap((GLboolean)param); 4353 break; 4354 case GL_TEXTURE_CROP_RECT_OES: 4355 return error(GL_INVALID_ENUM); // Needs four values, should call glTexParameterfv() instead 4356 default: 4357 return error(GL_INVALID_ENUM); 4358 } 4359 } 4360} 4361 4362void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) 4363{ 4364 TexParameterf(target, pname, *params); 4365} 4366 4367void TexParameteri(GLenum target, GLenum pname, GLint param) 4368{ 4369 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); 4370 4371 es1::Context *context = es1::getContext(); 4372 4373 if(context) 4374 { 4375 es1::Texture *texture; 4376 4377 switch(target) 4378 { 4379 case GL_TEXTURE_2D: 4380 texture = context->getTexture2D(); 4381 break; 4382 case GL_TEXTURE_EXTERNAL_OES: 4383 texture = context->getTextureExternal(); 4384 break; 4385 default: 4386 return error(GL_INVALID_ENUM); 4387 } 4388 4389 switch(pname) 4390 { 4391 case GL_TEXTURE_WRAP_S: 4392 if(!texture->setWrapS((GLenum)param)) 4393 { 4394 return error(GL_INVALID_ENUM); 4395 } 4396 break; 4397 case GL_TEXTURE_WRAP_T: 4398 if(!texture->setWrapT((GLenum)param)) 4399 { 4400 return error(GL_INVALID_ENUM); 4401 } 4402 break; 4403 case GL_TEXTURE_MIN_FILTER: 4404 if(!texture->setMinFilter((GLenum)param)) 4405 { 4406 return error(GL_INVALID_ENUM); 4407 } 4408 break; 4409 case GL_TEXTURE_MAG_FILTER: 4410 if(!texture->setMagFilter((GLenum)param)) 4411 { 4412 return error(GL_INVALID_ENUM); 4413 } 4414 break; 4415 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 4416 if(!texture->setMaxAnisotropy((GLfloat)param)) 4417 { 4418 return error(GL_INVALID_VALUE); 4419 } 4420 break; 4421 case GL_GENERATE_MIPMAP: 4422 texture->setGenerateMipmap((GLboolean)param); 4423 break; 4424 case GL_TEXTURE_CROP_RECT_OES: 4425 return error(GL_INVALID_ENUM); // Needs four values, should call glTexParameteriv() instead 4426 default: 4427 return error(GL_INVALID_ENUM); 4428 } 4429 } 4430} 4431 4432void TexParameteriv(GLenum target, GLenum pname, const GLint* params) 4433{ 4434 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %p)", target, pname, params); 4435 4436 switch(pname) 4437 { 4438 case GL_TEXTURE_CROP_RECT_OES: 4439 break; 4440 default: 4441 return TexParameteri(target, pname, params[0]); 4442 } 4443 4444 es1::Context *context = es1::getContext(); 4445 4446 if(context) 4447 { 4448 es1::Texture *texture; 4449 4450 switch(target) 4451 { 4452 case GL_TEXTURE_2D: 4453 texture = context->getTexture2D(); 4454 break; 4455 default: 4456 return error(GL_INVALID_ENUM); 4457 } 4458 4459 switch(pname) 4460 { 4461 case GL_TEXTURE_CROP_RECT_OES: 4462 texture->setCropRect(params[0], params[1], params[2], params[3]); 4463 break; 4464 default: 4465 return error(GL_INVALID_ENUM); 4466 } 4467 } 4468} 4469 4470void TexParameterx(GLenum target, GLenum pname, GLfixed param) 4471{ 4472 TexParameteri(target, pname, (GLint)param); 4473} 4474 4475void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params) 4476{ 4477 UNIMPLEMENTED(); 4478} 4479 4480void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, 4481 GLenum format, GLenum type, const GLvoid* pixels) 4482{ 4483 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 4484 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " 4485 "const GLvoid* pixels = %p)", 4486 target, level, xoffset, yoffset, width, height, format, type, pixels); 4487 4488 if(!es1::IsTextureTarget(target)) 4489 { 4490 return error(GL_INVALID_ENUM); 4491 } 4492 4493 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 4494 { 4495 return error(GL_INVALID_VALUE); 4496 } 4497 4498 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0) 4499 { 4500 return error(GL_INVALID_VALUE); 4501 } 4502 4503 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) 4504 { 4505 return error(GL_INVALID_VALUE); 4506 } 4507 4508 if(width == 0 || height == 0 || !pixels) 4509 { 4510 return; 4511 } 4512 4513 es1::Context *context = es1::getContext(); 4514 4515 if(context) 4516 { 4517 if(target == GL_TEXTURE_2D) 4518 { 4519 es1::Texture2D *texture = context->getTexture2D(); 4520 4521 GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture); 4522 if(validationError != GL_NO_ERROR) 4523 { 4524 return error(validationError); 4525 } 4526 4527 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); 4528 } 4529 else UNREACHABLE(target); 4530 } 4531} 4532 4533void Translatef(GLfloat x, GLfloat y, GLfloat z) 4534{ 4535 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z); 4536 4537 es1::Context *context = es1::getContext(); 4538 4539 if(context) 4540 { 4541 context->translate(x, y, z); 4542 } 4543} 4544 4545void Translatex(GLfixed x, GLfixed y, GLfixed z) 4546{ 4547 Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000); 4548} 4549 4550void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) 4551{ 4552 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer); 4553 4554 if(size < 2 || size > 4) 4555 { 4556 return error(GL_INVALID_VALUE); 4557 } 4558 4559 VertexAttribPointer(sw::Position, size, type, false, stride, pointer); 4560} 4561 4562void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) 4563{ 4564 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); 4565 4566 if(width < 0 || height < 0) 4567 { 4568 return error(GL_INVALID_VALUE); 4569 } 4570 4571 es1::Context *context = es1::getContext(); 4572 4573 if(context) 4574 { 4575 context->setViewportParams(x, y, width, height); 4576 } 4577} 4578 4579void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) 4580{ 4581 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image); 4582 4583 switch(target) 4584 { 4585 case GL_TEXTURE_2D: 4586 case GL_TEXTURE_EXTERNAL_OES: 4587 break; 4588 default: 4589 return error(GL_INVALID_ENUM); 4590 } 4591 4592 es1::Context *context = es1::getContext(); 4593 4594 if(context) 4595 { 4596 es1::Texture2D *texture = nullptr; 4597 4598 switch(target) 4599 { 4600 case GL_TEXTURE_2D: texture = context->getTexture2D(); break; 4601 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break; 4602 default: UNREACHABLE(target); 4603 } 4604 4605 if(!texture) 4606 { 4607 return error(GL_INVALID_OPERATION); 4608 } 4609 4610 egl::Image *eglImage = context->getSharedImage(image); 4611 4612 if(!eglImage) 4613 { 4614 return error(GL_INVALID_OPERATION); 4615 } 4616 4617 texture->setSharedImage(eglImage); 4618 } 4619} 4620 4621void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) 4622{ 4623 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image); 4624 4625 UNIMPLEMENTED(); 4626} 4627 4628void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height) 4629{ 4630 UNIMPLEMENTED(); 4631} 4632 4633void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height) 4634{ 4635 TRACE("(GLint x = %d, GLint y = %d, GLint z = %d, GLint width = %d, GLint height = %d)", x, y, z, width, height); 4636 4637 if(width <= 0 || height <= 0) 4638 { 4639 return error(GL_INVALID_VALUE); 4640 } 4641 4642 es1::Context *context = es1::getContext(); 4643 4644 if(context) 4645 { 4646 context->drawTexture((GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)width, (GLfloat)height); 4647 } 4648} 4649 4650void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) 4651{ 4652 UNIMPLEMENTED(); 4653} 4654 4655void DrawTexsvOES(const GLshort *coords) 4656{ 4657 UNIMPLEMENTED(); 4658} 4659 4660void DrawTexivOES(const GLint *coords) 4661{ 4662 UNIMPLEMENTED(); 4663} 4664 4665void DrawTexxvOES(const GLfixed *coords) 4666{ 4667 UNIMPLEMENTED(); 4668} 4669 4670void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height) 4671{ 4672 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat width = %f, GLfloat height = %f)", x, y, z, width, height); 4673 4674 if(width <= 0 || height <= 0) 4675 { 4676 return error(GL_INVALID_VALUE); 4677 } 4678 4679 es1::Context *context = es1::getContext(); 4680 4681 if(context) 4682 { 4683 context->drawTexture(x, y, z, width, height); 4684 } 4685} 4686 4687void DrawTexfvOES(const GLfloat *coords) 4688{ 4689 UNIMPLEMENTED(); 4690} 4691 4692} 4693 4694extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname) 4695{ 4696 struct Function 4697 { 4698 const char *name; 4699 __eglMustCastToProperFunctionPointerType address; 4700 }; 4701 4702 struct CompareFunctor 4703 { 4704 bool operator()(const Function &a, const Function &b) const 4705 { 4706 return strcmp(a.name, b.name) < 0; 4707 } 4708 }; 4709 4710 // This array must be kept sorted with respect to strcmp(), so that binary search works correctly. 4711 // The Unix command "LC_COLLATE=C sort" will generate the correct order. 4712 static const Function glFunctions[] = 4713 { 4714 #define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name} 4715 4716 FUNCTION(glActiveTexture), 4717 FUNCTION(glAlphaFunc), 4718 FUNCTION(glAlphaFuncx), 4719 FUNCTION(glBindBuffer), 4720 FUNCTION(glBindFramebufferOES), 4721 FUNCTION(glBindRenderbufferOES), 4722 FUNCTION(glBindTexture), 4723 FUNCTION(glBlendEquationOES), 4724 FUNCTION(glBlendEquationSeparateOES), 4725 FUNCTION(glBlendFunc), 4726 FUNCTION(glBlendFuncSeparateOES), 4727 FUNCTION(glBufferData), 4728 FUNCTION(glBufferSubData), 4729 FUNCTION(glCheckFramebufferStatusOES), 4730 FUNCTION(glClear), 4731 FUNCTION(glClearColor), 4732 FUNCTION(glClearColorx), 4733 FUNCTION(glClearDepthf), 4734 FUNCTION(glClearDepthx), 4735 FUNCTION(glClearStencil), 4736 FUNCTION(glClientActiveTexture), 4737 FUNCTION(glClipPlanef), 4738 FUNCTION(glClipPlanex), 4739 FUNCTION(glColor4f), 4740 FUNCTION(glColor4ub), 4741 FUNCTION(glColor4x), 4742 FUNCTION(glColorMask), 4743 FUNCTION(glColorPointer), 4744 FUNCTION(glCompressedTexImage2D), 4745 FUNCTION(glCompressedTexSubImage2D), 4746 FUNCTION(glCopyTexImage2D), 4747 FUNCTION(glCopyTexSubImage2D), 4748 FUNCTION(glCullFace), 4749 FUNCTION(glDeleteBuffers), 4750 FUNCTION(glDeleteFramebuffersOES), 4751 FUNCTION(glDeleteRenderbuffersOES), 4752 FUNCTION(glDeleteTextures), 4753 FUNCTION(glDepthFunc), 4754 FUNCTION(glDepthMask), 4755 FUNCTION(glDepthRangef), 4756 FUNCTION(glDepthRangex), 4757 FUNCTION(glDisable), 4758 FUNCTION(glDisableClientState), 4759 FUNCTION(glDrawArrays), 4760 FUNCTION(glDrawElements), 4761 FUNCTION(glDrawTexfOES), 4762 FUNCTION(glDrawTexfvOES), 4763 FUNCTION(glDrawTexiOES), 4764 FUNCTION(glDrawTexivOES), 4765 FUNCTION(glDrawTexsOES), 4766 FUNCTION(glDrawTexsvOES), 4767 FUNCTION(glDrawTexxOES), 4768 FUNCTION(glDrawTexxvOES), 4769 FUNCTION(glEGLImageTargetRenderbufferStorageOES), 4770 FUNCTION(glEGLImageTargetTexture2DOES), 4771 FUNCTION(glEnable), 4772 FUNCTION(glEnableClientState), 4773 FUNCTION(glFinish), 4774 FUNCTION(glFlush), 4775 FUNCTION(glFogf), 4776 FUNCTION(glFogfv), 4777 FUNCTION(glFogx), 4778 FUNCTION(glFogxv), 4779 FUNCTION(glFramebufferRenderbufferOES), 4780 FUNCTION(glFramebufferTexture2DOES), 4781 FUNCTION(glFrontFace), 4782 FUNCTION(glFrustumf), 4783 FUNCTION(glFrustumx), 4784 FUNCTION(glGenBuffers), 4785 FUNCTION(glGenFramebuffersOES), 4786 FUNCTION(glGenRenderbuffersOES), 4787 FUNCTION(glGenTextures), 4788 FUNCTION(glGenerateMipmapOES), 4789 FUNCTION(glGetBooleanv), 4790 FUNCTION(glGetBufferParameteriv), 4791 FUNCTION(glGetClipPlanef), 4792 FUNCTION(glGetClipPlanex), 4793 FUNCTION(glGetError), 4794 FUNCTION(glGetFixedv), 4795 FUNCTION(glGetFloatv), 4796 FUNCTION(glGetFramebufferAttachmentParameterivOES), 4797 FUNCTION(glGetIntegerv), 4798 FUNCTION(glGetLightfv), 4799 FUNCTION(glGetLightxv), 4800 FUNCTION(glGetMaterialfv), 4801 FUNCTION(glGetMaterialxv), 4802 FUNCTION(glGetPointerv), 4803 FUNCTION(glGetRenderbufferParameterivOES), 4804 FUNCTION(glGetString), 4805 FUNCTION(glGetTexEnvfv), 4806 FUNCTION(glGetTexEnviv), 4807 FUNCTION(glGetTexEnvxv), 4808 FUNCTION(glGetTexParameterfv), 4809 FUNCTION(glGetTexParameteriv), 4810 FUNCTION(glGetTexParameterxv), 4811 FUNCTION(glHint), 4812 FUNCTION(glIsBuffer), 4813 FUNCTION(glIsEnabled), 4814 FUNCTION(glIsFramebufferOES), 4815 FUNCTION(glIsRenderbufferOES), 4816 FUNCTION(glIsTexture), 4817 FUNCTION(glLightModelf), 4818 FUNCTION(glLightModelfv), 4819 FUNCTION(glLightModelx), 4820 FUNCTION(glLightModelxv), 4821 FUNCTION(glLightf), 4822 FUNCTION(glLightfv), 4823 FUNCTION(glLightx), 4824 FUNCTION(glLightxv), 4825 FUNCTION(glLineWidth), 4826 FUNCTION(glLineWidthx), 4827 FUNCTION(glLoadIdentity), 4828 FUNCTION(glLoadMatrixf), 4829 FUNCTION(glLoadMatrixx), 4830 FUNCTION(glLogicOp), 4831 FUNCTION(glMaterialf), 4832 FUNCTION(glMaterialfv), 4833 FUNCTION(glMaterialx), 4834 FUNCTION(glMaterialxv), 4835 FUNCTION(glMatrixMode), 4836 FUNCTION(glMultMatrixf), 4837 FUNCTION(glMultMatrixx), 4838 FUNCTION(glMultiTexCoord4f), 4839 FUNCTION(glMultiTexCoord4x), 4840 FUNCTION(glNormal3f), 4841 FUNCTION(glNormal3x), 4842 FUNCTION(glNormalPointer), 4843 FUNCTION(glOrthof), 4844 FUNCTION(glOrthox), 4845 FUNCTION(glPixelStorei), 4846 FUNCTION(glPointParameterf), 4847 FUNCTION(glPointParameterfv), 4848 FUNCTION(glPointParameterx), 4849 FUNCTION(glPointParameterxv), 4850 FUNCTION(glPointSize), 4851 FUNCTION(glPointSizePointerOES), 4852 FUNCTION(glPointSizex), 4853 FUNCTION(glPolygonOffset), 4854 FUNCTION(glPolygonOffsetx), 4855 FUNCTION(glPopMatrix), 4856 FUNCTION(glPushMatrix), 4857 FUNCTION(glReadPixels), 4858 FUNCTION(glRenderbufferStorageOES), 4859 FUNCTION(glRotatef), 4860 FUNCTION(glRotatex), 4861 FUNCTION(glSampleCoverage), 4862 FUNCTION(glSampleCoveragex), 4863 FUNCTION(glScalef), 4864 FUNCTION(glScalex), 4865 FUNCTION(glScissor), 4866 FUNCTION(glShadeModel), 4867 FUNCTION(glStencilFunc), 4868 FUNCTION(glStencilMask), 4869 FUNCTION(glStencilOp), 4870 FUNCTION(glTexCoordPointer), 4871 FUNCTION(glTexEnvf), 4872 FUNCTION(glTexEnvfv), 4873 FUNCTION(glTexEnvi), 4874 FUNCTION(glTexEnviv), 4875 FUNCTION(glTexEnvx), 4876 FUNCTION(glTexEnvxv), 4877 FUNCTION(glTexImage2D), 4878 FUNCTION(glTexParameterf), 4879 FUNCTION(glTexParameterfv), 4880 FUNCTION(glTexParameteri), 4881 FUNCTION(glTexParameteriv), 4882 FUNCTION(glTexParameterx), 4883 FUNCTION(glTexParameterxv), 4884 FUNCTION(glTexSubImage2D), 4885 FUNCTION(glTranslatef), 4886 FUNCTION(glTranslatex), 4887 FUNCTION(glVertexPointer), 4888 FUNCTION(glViewport), 4889 4890 #undef FUNCTION 4891 }; 4892 4893 static const size_t numFunctions = sizeof glFunctions / sizeof(Function); 4894 static const Function *const glFunctionsEnd = glFunctions + numFunctions; 4895 4896 Function needle; 4897 needle.name = procname; 4898 4899 if(procname && strncmp("gl", procname, 2) == 0) 4900 { 4901 const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor()); 4902 if(result != glFunctionsEnd && strcmp(procname, result->name) == 0) 4903 { 4904 return (__eglMustCastToProperFunctionPointerType)result->address; 4905 } 4906 } 4907 4908 return nullptr; 4909} 4910