blob: 46946eb11bc98101a37e6d8ca4a14379320ff975 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000017
18#include "libGLESv2/main.h"
19#include "libGLESv2/mathutil.h"
20#include "libGLESv2/utilities.h"
21#include "libGLESv2/Buffer.h"
22#include "libGLESv2/Context.h"
23#include "libGLESv2/Framebuffer.h"
24#include "libGLESv2/Program.h"
25#include "libGLESv2/Renderbuffer.h"
26#include "libGLESv2/Shader.h"
27#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000028
29extern "C"
30{
31
32void __stdcall glActiveTexture(GLenum texture)
33{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000034 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035
36 try
37 {
38 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
39 {
40 return error(GL_INVALID_ENUM);
41 }
42
43 gl::Context *context = gl::getContext();
44
45 if (context)
46 {
47 context->activeSampler = texture - GL_TEXTURE0;
48 }
49 }
50 catch(std::bad_alloc&)
51 {
52 return error(GL_OUT_OF_MEMORY);
53 }
54}
55
56void __stdcall glAttachShader(GLuint program, GLuint shader)
57{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000058 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000059
60 try
61 {
62 gl::Context *context = gl::getContext();
63
64 if (context)
65 {
66 gl::Program *programObject = context->getProgram(program);
67 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000068
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000069 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000071 if (context->getShader(program))
72 {
73 return error(GL_INVALID_OPERATION);
74 }
75 else
76 {
77 return error(GL_INVALID_VALUE);
78 }
79 }
80
81 if (!shaderObject)
82 {
83 if (context->getProgram(shader))
84 {
85 return error(GL_INVALID_OPERATION);
86 }
87 else
88 {
89 return error(GL_INVALID_VALUE);
90 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000091 }
92
93 if (!programObject->attachShader(shaderObject))
94 {
95 return error(GL_INVALID_OPERATION);
96 }
97 }
98 }
99 catch(std::bad_alloc&)
100 {
101 return error(GL_OUT_OF_MEMORY);
102 }
103}
104
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000105void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000106{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000107 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108
109 try
110 {
111 if (index >= gl::MAX_VERTEX_ATTRIBS)
112 {
113 return error(GL_INVALID_VALUE);
114 }
115
116 gl::Context *context = gl::getContext();
117
118 if (context)
119 {
120 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000121
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000122 if (!programObject)
123 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000124 if (context->getShader(program))
125 {
126 return error(GL_INVALID_OPERATION);
127 }
128 else
129 {
130 return error(GL_INVALID_VALUE);
131 }
132 }
133
134 if (strncmp(name, "gl_", 3) == 0)
135 {
136 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137 }
138
139 programObject->bindAttributeLocation(index, name);
140 }
141 }
142 catch(std::bad_alloc&)
143 {
144 return error(GL_OUT_OF_MEMORY);
145 }
146}
147
148void __stdcall glBindBuffer(GLenum target, GLuint buffer)
149{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000150 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000151
152 try
153 {
154 gl::Context *context = gl::getContext();
155
156 if (context)
157 {
158 switch (target)
159 {
160 case GL_ARRAY_BUFFER:
161 context->bindArrayBuffer(buffer);
162 return;
163 case GL_ELEMENT_ARRAY_BUFFER:
164 context->bindElementArrayBuffer(buffer);
165 return;
166 default:
167 return error(GL_INVALID_ENUM);
168 }
169 }
170 }
171 catch(std::bad_alloc&)
172 {
173 return error(GL_OUT_OF_MEMORY);
174 }
175}
176
177void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
178{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000179 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000180
181 try
182 {
183 if (target != GL_FRAMEBUFFER)
184 {
185 return error(GL_INVALID_ENUM);
186 }
187
188 gl::Context *context = gl::getContext();
189
190 if (context)
191 {
192 context->bindFramebuffer(framebuffer);
193 }
194 }
195 catch(std::bad_alloc&)
196 {
197 return error(GL_OUT_OF_MEMORY);
198 }
199}
200
201void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
202{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000203 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204
205 try
206 {
207 if (target != GL_RENDERBUFFER)
208 {
209 return error(GL_INVALID_ENUM);
210 }
211
212 gl::Context *context = gl::getContext();
213
214 if (context)
215 {
216 context->bindRenderbuffer(renderbuffer);
217 }
218 }
219 catch(std::bad_alloc&)
220 {
221 return error(GL_OUT_OF_MEMORY);
222 }
223}
224
225void __stdcall glBindTexture(GLenum target, GLuint texture)
226{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000227 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228
229 try
230 {
231 gl::Context *context = gl::getContext();
232
233 if (context)
234 {
235 gl::Texture *textureObject = context->getTexture(texture);
236
237 if (textureObject && textureObject->getTarget() != target && texture != 0)
238 {
239 return error(GL_INVALID_OPERATION);
240 }
241
242 switch (target)
243 {
244 case GL_TEXTURE_2D:
245 context->bindTexture2D(texture);
246 return;
247 case GL_TEXTURE_CUBE_MAP:
248 context->bindTextureCubeMap(texture);
249 return;
250 default:
251 return error(GL_INVALID_ENUM);
252 }
253 }
254 }
255 catch(std::bad_alloc&)
256 {
257 return error(GL_OUT_OF_MEMORY);
258 }
259}
260
261void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
262{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000263 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
264 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000265
266 try
267 {
268 gl::Context* context = gl::getContext();
269
270 if (context)
271 {
272 context->blendColor.red = gl::clamp01(red);
273 context->blendColor.blue = gl::clamp01(blue);
274 context->blendColor.green = gl::clamp01(green);
275 context->blendColor.alpha = gl::clamp01(alpha);
276 }
277 }
278 catch(std::bad_alloc&)
279 {
280 return error(GL_OUT_OF_MEMORY);
281 }
282}
283
284void __stdcall glBlendEquation(GLenum mode)
285{
286 glBlendEquationSeparate(mode, mode);
287}
288
289void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
290{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000291 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000292
293 try
294 {
295 switch (modeRGB)
296 {
297 case GL_FUNC_ADD:
298 case GL_FUNC_SUBTRACT:
299 case GL_FUNC_REVERSE_SUBTRACT:
300 break;
301 default:
302 return error(GL_INVALID_ENUM);
303 }
304
305 switch (modeAlpha)
306 {
307 case GL_FUNC_ADD:
308 case GL_FUNC_SUBTRACT:
309 case GL_FUNC_REVERSE_SUBTRACT:
310 break;
311 default:
312 return error(GL_INVALID_ENUM);
313 }
314
315 gl::Context *context = gl::getContext();
316
317 if (context)
318 {
319 context->blendEquationRGB = modeRGB;
320 context->blendEquationAlpha = modeAlpha;
321 }
322 }
323 catch(std::bad_alloc&)
324 {
325 return error(GL_OUT_OF_MEMORY);
326 }
327}
328
329void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
330{
331 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
332}
333
334void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
335{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000336 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
337 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000338
339 try
340 {
341 switch (srcRGB)
342 {
343 case GL_ZERO:
344 case GL_ONE:
345 case GL_SRC_COLOR:
346 case GL_ONE_MINUS_SRC_COLOR:
347 case GL_DST_COLOR:
348 case GL_ONE_MINUS_DST_COLOR:
349 case GL_SRC_ALPHA:
350 case GL_ONE_MINUS_SRC_ALPHA:
351 case GL_DST_ALPHA:
352 case GL_ONE_MINUS_DST_ALPHA:
353 case GL_CONSTANT_COLOR:
354 case GL_ONE_MINUS_CONSTANT_COLOR:
355 case GL_CONSTANT_ALPHA:
356 case GL_ONE_MINUS_CONSTANT_ALPHA:
357 case GL_SRC_ALPHA_SATURATE:
358 break;
359 default:
360 return error(GL_INVALID_ENUM);
361 }
362
363 switch (dstRGB)
364 {
365 case GL_ZERO:
366 case GL_ONE:
367 case GL_SRC_COLOR:
368 case GL_ONE_MINUS_SRC_COLOR:
369 case GL_DST_COLOR:
370 case GL_ONE_MINUS_DST_COLOR:
371 case GL_SRC_ALPHA:
372 case GL_ONE_MINUS_SRC_ALPHA:
373 case GL_DST_ALPHA:
374 case GL_ONE_MINUS_DST_ALPHA:
375 case GL_CONSTANT_COLOR:
376 case GL_ONE_MINUS_CONSTANT_COLOR:
377 case GL_CONSTANT_ALPHA:
378 case GL_ONE_MINUS_CONSTANT_ALPHA:
379 break;
380 default:
381 return error(GL_INVALID_ENUM);
382 }
383
384 switch (srcAlpha)
385 {
386 case GL_ZERO:
387 case GL_ONE:
388 case GL_SRC_COLOR:
389 case GL_ONE_MINUS_SRC_COLOR:
390 case GL_DST_COLOR:
391 case GL_ONE_MINUS_DST_COLOR:
392 case GL_SRC_ALPHA:
393 case GL_ONE_MINUS_SRC_ALPHA:
394 case GL_DST_ALPHA:
395 case GL_ONE_MINUS_DST_ALPHA:
396 case GL_CONSTANT_COLOR:
397 case GL_ONE_MINUS_CONSTANT_COLOR:
398 case GL_CONSTANT_ALPHA:
399 case GL_ONE_MINUS_CONSTANT_ALPHA:
400 case GL_SRC_ALPHA_SATURATE:
401 break;
402 default:
403 return error(GL_INVALID_ENUM);
404 }
405
406 switch (dstAlpha)
407 {
408 case GL_ZERO:
409 case GL_ONE:
410 case GL_SRC_COLOR:
411 case GL_ONE_MINUS_SRC_COLOR:
412 case GL_DST_COLOR:
413 case GL_ONE_MINUS_DST_COLOR:
414 case GL_SRC_ALPHA:
415 case GL_ONE_MINUS_SRC_ALPHA:
416 case GL_DST_ALPHA:
417 case GL_ONE_MINUS_DST_ALPHA:
418 case GL_CONSTANT_COLOR:
419 case GL_ONE_MINUS_CONSTANT_COLOR:
420 case GL_CONSTANT_ALPHA:
421 case GL_ONE_MINUS_CONSTANT_ALPHA:
422 break;
423 default:
424 return error(GL_INVALID_ENUM);
425 }
426
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000427 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
428 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
429
430 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
431 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
432
433 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000434 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000435 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
436 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000437 }
438
439 gl::Context *context = gl::getContext();
440
441 if (context)
442 {
443 context->sourceBlendRGB = srcRGB;
444 context->sourceBlendAlpha = srcAlpha;
445 context->destBlendRGB = dstRGB;
446 context->destBlendAlpha = dstAlpha;
447 }
448 }
449 catch(std::bad_alloc&)
450 {
451 return error(GL_OUT_OF_MEMORY);
452 }
453}
454
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000455void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000456{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000457 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000458 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000459
460 try
461 {
462 if (size < 0)
463 {
464 return error(GL_INVALID_VALUE);
465 }
466
467 switch (usage)
468 {
469 case GL_STREAM_DRAW:
470 case GL_STATIC_DRAW:
471 case GL_DYNAMIC_DRAW:
472 break;
473 default:
474 return error(GL_INVALID_ENUM);
475 }
476
477 gl::Context *context = gl::getContext();
478
479 if (context)
480 {
481 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000482
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000483 switch (target)
484 {
485 case GL_ARRAY_BUFFER:
486 buffer = context->getArrayBuffer();
487 break;
488 case GL_ELEMENT_ARRAY_BUFFER:
489 buffer = context->getElementArrayBuffer();
490 break;
491 default:
492 return error(GL_INVALID_ENUM);
493 }
494
495 if (!buffer)
496 {
497 return error(GL_INVALID_OPERATION);
498 }
499
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000500 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000501 }
502 }
503 catch(std::bad_alloc&)
504 {
505 return error(GL_OUT_OF_MEMORY);
506 }
507}
508
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000509void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000510{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000511 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000512 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000513
514 try
515 {
516 if (size < 0)
517 {
518 return error(GL_INVALID_VALUE);
519 }
520
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000521 if (data == NULL)
522 {
523 return;
524 }
525
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000526 gl::Context *context = gl::getContext();
527
528 if (context)
529 {
530 gl::Buffer *buffer;
531
532 switch (target)
533 {
534 case GL_ARRAY_BUFFER:
535 buffer = context->getArrayBuffer();
536 break;
537 case GL_ELEMENT_ARRAY_BUFFER:
538 buffer = context->getElementArrayBuffer();
539 break;
540 default:
541 return error(GL_INVALID_ENUM);
542 }
543
544 if (!buffer)
545 {
546 return error(GL_INVALID_OPERATION);
547 }
548
549 GLenum err = buffer->bufferSubData(data, size, offset);
550
551 if (err != GL_NO_ERROR)
552 {
553 return error(err);
554 }
555 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000556 }
557 catch(std::bad_alloc&)
558 {
559 return error(GL_OUT_OF_MEMORY);
560 }
561}
562
563GLenum __stdcall glCheckFramebufferStatus(GLenum target)
564{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000565 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000566
567 try
568 {
569 if (target != GL_FRAMEBUFFER)
570 {
571 return error(GL_INVALID_ENUM, 0);
572 }
573
574 gl::Context *context = gl::getContext();
575
576 if (context)
577 {
578 gl::Framebuffer *framebuffer = context->getFramebuffer();
579
580 return framebuffer->completeness();
581 }
582 }
583 catch(std::bad_alloc&)
584 {
585 return error(GL_OUT_OF_MEMORY, 0);
586 }
587
588 return 0;
589}
590
591void __stdcall glClear(GLbitfield mask)
592{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000593 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000594
595 try
596 {
597 gl::Context *context = gl::getContext();
598
599 if (context)
600 {
601 context->clear(mask);
602 }
603 }
604 catch(std::bad_alloc&)
605 {
606 return error(GL_OUT_OF_MEMORY);
607 }
608}
609
610void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
611{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000612 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
613 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000614
615 try
616 {
617 gl::Context *context = gl::getContext();
618
619 if (context)
620 {
621 context->setClearColor(red, green, blue, alpha);
622 }
623 }
624 catch(std::bad_alloc&)
625 {
626 return error(GL_OUT_OF_MEMORY);
627 }
628}
629
630void __stdcall glClearDepthf(GLclampf depth)
631{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000632 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000633
634 try
635 {
636 gl::Context *context = gl::getContext();
637
638 if (context)
639 {
640 context->setClearDepth(depth);
641 }
642 }
643 catch(std::bad_alloc&)
644 {
645 return error(GL_OUT_OF_MEMORY);
646 }
647}
648
649void __stdcall glClearStencil(GLint s)
650{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000651 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000652
653 try
654 {
655 gl::Context *context = gl::getContext();
656
657 if (context)
658 {
659 context->setClearStencil(s);
660 }
661 }
662 catch(std::bad_alloc&)
663 {
664 return error(GL_OUT_OF_MEMORY);
665 }
666}
667
668void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
669{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000670 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
671 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000672
673 try
674 {
675 gl::Context *context = gl::getContext();
676
677 if (context)
678 {
679 context->colorMaskRed = red != GL_FALSE;
680 context->colorMaskGreen = green != GL_FALSE;
681 context->colorMaskBlue = blue != GL_FALSE;
682 context->colorMaskAlpha = alpha != GL_FALSE;
683 }
684 }
685 catch(std::bad_alloc&)
686 {
687 return error(GL_OUT_OF_MEMORY);
688 }
689}
690
691void __stdcall glCompileShader(GLuint shader)
692{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000693 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000694
695 try
696 {
697 gl::Context *context = gl::getContext();
698
699 if (context)
700 {
701 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000702
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000703 if (!shaderObject)
704 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000705 if (context->getProgram(shader))
706 {
707 return error(GL_INVALID_OPERATION);
708 }
709 else
710 {
711 return error(GL_INVALID_VALUE);
712 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000713 }
714
715 shaderObject->compile();
716 }
717 }
718 catch(std::bad_alloc&)
719 {
720 return error(GL_OUT_OF_MEMORY);
721 }
722}
723
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000724void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
725 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000726{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000727 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000728 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000729 target, level, internalformat, width, height, border, imageSize, data);
730
731 try
732 {
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000733 if (!es2dx::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000734 {
735 return error(GL_INVALID_ENUM);
736 }
737
738 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000739 {
740 return error(GL_INVALID_VALUE);
741 }
742
daniel@transgaming.com41430492010-03-11 20:36:18 +0000743 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
744 {
745 return error(GL_INVALID_VALUE);
746 }
747
748 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000749 }
750 catch(std::bad_alloc&)
751 {
752 return error(GL_OUT_OF_MEMORY);
753 }
754}
755
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000756void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
757 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000758{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000759 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
760 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000761 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000762 target, level, xoffset, yoffset, width, height, format, imageSize, data);
763
764 try
765 {
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000766 if (!es2dx::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000767 {
768 return error(GL_INVALID_ENUM);
769 }
770
771 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000772 {
773 return error(GL_INVALID_VALUE);
774 }
775
daniel@transgaming.com41430492010-03-11 20:36:18 +0000776 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
777 {
778 return error(GL_INVALID_VALUE);
779 }
780
781 if (xoffset != 0 || yoffset != 0)
782 {
783 return error(GL_INVALID_OPERATION);
784 }
785
786 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000787 }
788 catch(std::bad_alloc&)
789 {
790 return error(GL_OUT_OF_MEMORY);
791 }
792}
793
794void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
795{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000796 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
797 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000798 target, level, internalformat, x, y, width, height, border);
799
800 try
801 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000802 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000803 {
804 return error(GL_INVALID_VALUE);
805 }
806
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000807 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
808 {
809 return error(GL_INVALID_VALUE);
810 }
811
812 switch (target)
813 {
814 case GL_TEXTURE_2D:
815 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
816 {
817 return error(GL_INVALID_VALUE);
818 }
819 break;
820 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
821 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
822 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
823 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
824 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
825 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +0000826 if (width != height)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000827 {
828 return error(GL_INVALID_VALUE);
829 }
830
831 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
832 {
833 return error(GL_INVALID_VALUE);
834 }
835 break;
836 default:
837 return error(GL_INVALID_ENUM);
838 }
839
840 switch (internalformat)
841 {
842 case GL_ALPHA:
843 case GL_LUMINANCE:
844 case GL_LUMINANCE_ALPHA:
845 case GL_RGB:
846 case GL_RGBA:
847 break;
848 default:
849 return error(GL_INVALID_VALUE);
850 }
851
852 if (border != 0)
853 {
854 return error(GL_INVALID_VALUE);
855 }
856
857 gl::Context *context = gl::getContext();
858
859 if (context)
860 {
861 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
862
863 if (target == GL_TEXTURE_2D)
864 {
865 gl::Texture2D *texture = context->getTexture2D();
866
867 if (!texture)
868 {
869 return error(GL_INVALID_OPERATION);
870 }
871
872 texture->copyImage(level, internalformat, x, y, width, height, source);
873 }
874 else if (es2dx::IsCubemapTextureTarget(target))
875 {
876 gl::TextureCubeMap *texture = context->getTextureCubeMap();
877
878 if (!texture)
879 {
880 return error(GL_INVALID_OPERATION);
881 }
882
883 texture->copyImage(target, level, internalformat, x, y, width, height, source);
884 }
885 else
886 {
887 UNREACHABLE();
888 }
889 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000890 }
891 catch(std::bad_alloc&)
892 {
893 return error(GL_OUT_OF_MEMORY);
894 }
895}
896
897void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
898{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000899 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
900 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000901 target, level, xoffset, yoffset, x, y, width, height);
902
903 try
904 {
daniel@transgaming.comfbc09532010-04-26 15:33:41 +0000905 if (!es2dx::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000906 {
907 return error(GL_INVALID_ENUM);
908 }
909
910 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000911 {
912 return error(GL_INVALID_VALUE);
913 }
914
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000915 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
916 {
917 return error(GL_INVALID_VALUE);
918 }
919
920 if (width == 0 || height == 0)
921 {
922 return;
923 }
924
925 gl::Context *context = gl::getContext();
926
927 if (context)
928 {
929 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
930
931 if (target == GL_TEXTURE_2D)
932 {
933 gl::Texture2D *texture = context->getTexture2D();
934
935 if (!texture)
936 {
937 return error(GL_INVALID_OPERATION);
938 }
939
940 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
941 }
942 else if (es2dx::IsCubemapTextureTarget(target))
943 {
944 gl::TextureCubeMap *texture = context->getTextureCubeMap();
945
946 if (!texture)
947 {
948 return error(GL_INVALID_OPERATION);
949 }
950
951 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
952 }
953 else
954 {
955 UNREACHABLE();
956 }
957 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000958 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000959
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000960 catch(std::bad_alloc&)
961 {
962 return error(GL_OUT_OF_MEMORY);
963 }
964}
965
966GLuint __stdcall glCreateProgram(void)
967{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000968 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000969
970 try
971 {
972 gl::Context *context = gl::getContext();
973
974 if (context)
975 {
976 return context->createProgram();
977 }
978 }
979 catch(std::bad_alloc&)
980 {
981 return error(GL_OUT_OF_MEMORY, 0);
982 }
983
984 return 0;
985}
986
987GLuint __stdcall glCreateShader(GLenum type)
988{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000989 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000990
991 try
992 {
993 gl::Context *context = gl::getContext();
994
995 if (context)
996 {
997 switch (type)
998 {
999 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001000 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001001 return context->createShader(type);
1002 default:
1003 return error(GL_INVALID_ENUM, 0);
1004 }
1005 }
1006 }
1007 catch(std::bad_alloc&)
1008 {
1009 return error(GL_OUT_OF_MEMORY, 0);
1010 }
1011
1012 return 0;
1013}
1014
1015void __stdcall glCullFace(GLenum mode)
1016{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001017 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001018
1019 try
1020 {
1021 switch (mode)
1022 {
1023 case GL_FRONT:
1024 case GL_BACK:
1025 case GL_FRONT_AND_BACK:
1026 {
1027 gl::Context *context = gl::getContext();
1028
1029 if (context)
1030 {
1031 context->cullMode = mode;
1032 }
1033 }
1034 break;
1035 default:
1036 return error(GL_INVALID_ENUM);
1037 }
1038 }
1039 catch(std::bad_alloc&)
1040 {
1041 return error(GL_OUT_OF_MEMORY);
1042 }
1043}
1044
1045void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1046{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001047 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001048
1049 try
1050 {
1051 if (n < 0)
1052 {
1053 return error(GL_INVALID_VALUE);
1054 }
1055
1056 gl::Context *context = gl::getContext();
1057
1058 if (context)
1059 {
1060 for (int i = 0; i < n; i++)
1061 {
1062 context->deleteBuffer(buffers[i]);
1063 }
1064 }
1065 }
1066 catch(std::bad_alloc&)
1067 {
1068 return error(GL_OUT_OF_MEMORY);
1069 }
1070}
1071
1072void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1073{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001074 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001075
1076 try
1077 {
1078 if (n < 0)
1079 {
1080 return error(GL_INVALID_VALUE);
1081 }
1082
1083 gl::Context *context = gl::getContext();
1084
1085 if (context)
1086 {
1087 for (int i = 0; i < n; i++)
1088 {
1089 if (framebuffers[i] != 0)
1090 {
1091 context->deleteFramebuffer(framebuffers[i]);
1092 }
1093 }
1094 }
1095 }
1096 catch(std::bad_alloc&)
1097 {
1098 return error(GL_OUT_OF_MEMORY);
1099 }
1100}
1101
1102void __stdcall glDeleteProgram(GLuint program)
1103{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001104 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001105
1106 try
1107 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001108 if (program == 0)
1109 {
1110 return;
1111 }
1112
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001113 gl::Context *context = gl::getContext();
1114
1115 if (context)
1116 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001117 if (!context->getProgram(program))
1118 {
1119 if(context->getShader(program))
1120 {
1121 return error(GL_INVALID_OPERATION);
1122 }
1123 else
1124 {
1125 return error(GL_INVALID_VALUE);
1126 }
1127 }
1128
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001129 context->deleteProgram(program);
1130 }
1131 }
1132 catch(std::bad_alloc&)
1133 {
1134 return error(GL_OUT_OF_MEMORY);
1135 }
1136}
1137
1138void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1139{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001140 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001141
1142 try
1143 {
1144 if (n < 0)
1145 {
1146 return error(GL_INVALID_VALUE);
1147 }
1148
1149 gl::Context *context = gl::getContext();
1150
1151 if (context)
1152 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001153 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001154 {
1155 context->deleteRenderbuffer(renderbuffers[i]);
1156 }
1157 }
1158 }
1159 catch(std::bad_alloc&)
1160 {
1161 return error(GL_OUT_OF_MEMORY);
1162 }
1163}
1164
1165void __stdcall glDeleteShader(GLuint shader)
1166{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001167 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001168
1169 try
1170 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001171 if (shader == 0)
1172 {
1173 return;
1174 }
1175
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001176 gl::Context *context = gl::getContext();
1177
1178 if (context)
1179 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001180 if (!context->getShader(shader))
1181 {
1182 if(context->getProgram(shader))
1183 {
1184 return error(GL_INVALID_OPERATION);
1185 }
1186 else
1187 {
1188 return error(GL_INVALID_VALUE);
1189 }
1190 }
1191
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001192 context->deleteShader(shader);
1193 }
1194 }
1195 catch(std::bad_alloc&)
1196 {
1197 return error(GL_OUT_OF_MEMORY);
1198 }
1199}
1200
1201void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1202{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001203 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001204
1205 try
1206 {
1207 if (n < 0)
1208 {
1209 return error(GL_INVALID_VALUE);
1210 }
1211
1212 gl::Context *context = gl::getContext();
1213
1214 if (context)
1215 {
1216 for (int i = 0; i < n; i++)
1217 {
1218 if (textures[i] != 0)
1219 {
1220 context->deleteTexture(textures[i]);
1221 }
1222 }
1223 }
1224 }
1225 catch(std::bad_alloc&)
1226 {
1227 return error(GL_OUT_OF_MEMORY);
1228 }
1229}
1230
1231void __stdcall glDepthFunc(GLenum func)
1232{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001233 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001234
1235 try
1236 {
1237 switch (func)
1238 {
1239 case GL_NEVER:
1240 case GL_ALWAYS:
1241 case GL_LESS:
1242 case GL_LEQUAL:
1243 case GL_EQUAL:
1244 case GL_GREATER:
1245 case GL_GEQUAL:
1246 case GL_NOTEQUAL:
1247 break;
1248 default:
1249 return error(GL_INVALID_ENUM);
1250 }
1251
1252 gl::Context *context = gl::getContext();
1253
1254 if (context)
1255 {
1256 context->depthFunc = func;
1257 }
1258 }
1259 catch(std::bad_alloc&)
1260 {
1261 return error(GL_OUT_OF_MEMORY);
1262 }
1263}
1264
1265void __stdcall glDepthMask(GLboolean flag)
1266{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001267 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001268
1269 try
1270 {
1271 gl::Context *context = gl::getContext();
1272
1273 if (context)
1274 {
1275 context->depthMask = flag != GL_FALSE;
1276 }
1277 }
1278 catch(std::bad_alloc&)
1279 {
1280 return error(GL_OUT_OF_MEMORY);
1281 }
1282}
1283
1284void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1285{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001286 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001287
1288 try
1289 {
1290 gl::Context *context = gl::getContext();
1291
1292 if (context)
1293 {
1294 context->zNear = zNear;
1295 context->zFar = zFar;
1296 }
1297 }
1298 catch(std::bad_alloc&)
1299 {
1300 return error(GL_OUT_OF_MEMORY);
1301 }
1302}
1303
1304void __stdcall glDetachShader(GLuint program, GLuint shader)
1305{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001306 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001307
1308 try
1309 {
1310 gl::Context *context = gl::getContext();
1311
1312 if (context)
1313 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001314
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001315 gl::Program *programObject = context->getProgram(program);
1316 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001317
1318 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001319 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001320 gl::Shader *shaderByProgramHandle;
1321 shaderByProgramHandle = context->getShader(program);
1322 if (!shaderByProgramHandle)
1323 {
1324 return error(GL_INVALID_VALUE);
1325 }
1326 else
1327 {
1328 return error(GL_INVALID_OPERATION);
1329 }
1330 }
1331
1332 if (!shaderObject)
1333 {
1334 gl::Program *programByShaderHandle = context->getProgram(shader);
1335 if (!programByShaderHandle)
1336 {
1337 return error(GL_INVALID_VALUE);
1338 }
1339 else
1340 {
1341 return error(GL_INVALID_OPERATION);
1342 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001343 }
1344
1345 if (!programObject->detachShader(shaderObject))
1346 {
1347 return error(GL_INVALID_OPERATION);
1348 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001349 }
1350 }
1351 catch(std::bad_alloc&)
1352 {
1353 return error(GL_OUT_OF_MEMORY);
1354 }
1355}
1356
1357void __stdcall glDisable(GLenum cap)
1358{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001359 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001360
1361 try
1362 {
1363 gl::Context *context = gl::getContext();
1364
1365 if (context)
1366 {
1367 switch (cap)
1368 {
1369 case GL_CULL_FACE: context->cullFace = false; break;
1370 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1371 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1372 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1373 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1374 case GL_STENCIL_TEST: context->stencilTest = false; break;
1375 case GL_DEPTH_TEST: context->depthTest = false; break;
1376 case GL_BLEND: context->blend = false; break;
1377 case GL_DITHER: context->dither = false; break;
1378 default:
1379 return error(GL_INVALID_ENUM);
1380 }
1381 }
1382 }
1383 catch(std::bad_alloc&)
1384 {
1385 return error(GL_OUT_OF_MEMORY);
1386 }
1387}
1388
1389void __stdcall glDisableVertexAttribArray(GLuint index)
1390{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001391 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001392
1393 try
1394 {
1395 if (index >= gl::MAX_VERTEX_ATTRIBS)
1396 {
1397 return error(GL_INVALID_VALUE);
1398 }
1399
1400 gl::Context *context = gl::getContext();
1401
1402 if (context)
1403 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001404 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001405 }
1406 }
1407 catch(std::bad_alloc&)
1408 {
1409 return error(GL_OUT_OF_MEMORY);
1410 }
1411}
1412
1413void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1414{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001415 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001416
1417 try
1418 {
1419 if (count < 0 || first < 0)
1420 {
1421 return error(GL_INVALID_VALUE);
1422 }
1423
1424 gl::Context *context = gl::getContext();
1425
1426 if (context)
1427 {
1428 context->drawArrays(mode, first, count);
1429 }
1430 }
1431 catch(std::bad_alloc&)
1432 {
1433 return error(GL_OUT_OF_MEMORY);
1434 }
1435}
1436
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001437void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001438{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001439 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001440 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001441
1442 try
1443 {
1444 if (count < 0)
1445 {
1446 return error(GL_INVALID_VALUE);
1447 }
1448
1449 switch (type)
1450 {
1451 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001452 case GL_UNSIGNED_SHORT:
1453 break;
1454 default:
1455 return error(GL_INVALID_ENUM);
1456 }
1457
1458 gl::Context *context = gl::getContext();
1459
1460 if (context)
1461 {
1462 context->drawElements(mode, count, type, indices);
1463 }
1464 }
1465 catch(std::bad_alloc&)
1466 {
1467 return error(GL_OUT_OF_MEMORY);
1468 }
1469}
1470
1471void __stdcall glEnable(GLenum cap)
1472{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001473 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001474
1475 try
1476 {
1477 gl::Context *context = gl::getContext();
1478
1479 if (context)
1480 {
1481 switch (cap)
1482 {
1483 case GL_CULL_FACE: context->cullFace = true; break;
1484 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1485 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1486 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1487 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1488 case GL_STENCIL_TEST: context->stencilTest = true; break;
1489 case GL_DEPTH_TEST: context->depthTest = true; break;
1490 case GL_BLEND: context->blend = true; break;
1491 case GL_DITHER: context->dither = true; break;
1492 default:
1493 return error(GL_INVALID_ENUM);
1494 }
1495 }
1496 }
1497 catch(std::bad_alloc&)
1498 {
1499 return error(GL_OUT_OF_MEMORY);
1500 }
1501}
1502
1503void __stdcall glEnableVertexAttribArray(GLuint index)
1504{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001505 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001506
1507 try
1508 {
1509 if (index >= gl::MAX_VERTEX_ATTRIBS)
1510 {
1511 return error(GL_INVALID_VALUE);
1512 }
1513
1514 gl::Context *context = gl::getContext();
1515
1516 if (context)
1517 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001518 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001519 }
1520 }
1521 catch(std::bad_alloc&)
1522 {
1523 return error(GL_OUT_OF_MEMORY);
1524 }
1525}
1526
1527void __stdcall glFinish(void)
1528{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001529 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001530
1531 try
1532 {
1533 gl::Context *context = gl::getContext();
1534
1535 if (context)
1536 {
1537 context->finish();
1538 }
1539 }
1540 catch(std::bad_alloc&)
1541 {
1542 return error(GL_OUT_OF_MEMORY);
1543 }
1544}
1545
1546void __stdcall glFlush(void)
1547{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001548 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001549
1550 try
1551 {
1552 gl::Context *context = gl::getContext();
1553
1554 if (context)
1555 {
1556 context->flush();
1557 }
1558 }
1559 catch(std::bad_alloc&)
1560 {
1561 return error(GL_OUT_OF_MEMORY);
1562 }
1563}
1564
1565void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1566{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001567 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1568 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001569
1570 try
1571 {
1572 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1573 {
1574 return error(GL_INVALID_ENUM);
1575 }
1576
1577 gl::Context *context = gl::getContext();
1578
1579 if (context)
1580 {
1581 gl::Framebuffer *framebuffer = context->getFramebuffer();
1582
1583 if (context->framebuffer == 0 || !framebuffer)
1584 {
1585 return error(GL_INVALID_OPERATION);
1586 }
1587
1588 switch (attachment)
1589 {
1590 case GL_COLOR_ATTACHMENT0:
1591 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1592 break;
1593 case GL_DEPTH_ATTACHMENT:
1594 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1595 break;
1596 case GL_STENCIL_ATTACHMENT:
1597 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1598 break;
1599 default:
1600 return error(GL_INVALID_ENUM);
1601 }
1602 }
1603 }
1604 catch(std::bad_alloc&)
1605 {
1606 return error(GL_OUT_OF_MEMORY);
1607 }
1608}
1609
1610void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1611{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001612 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1613 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001614
1615 try
1616 {
1617 if (target != GL_FRAMEBUFFER)
1618 {
1619 return error(GL_INVALID_ENUM);
1620 }
1621
1622 switch (attachment)
1623 {
1624 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001625 case GL_DEPTH_ATTACHMENT:
1626 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001627 break;
1628 default:
1629 return error(GL_INVALID_ENUM);
1630 }
1631
1632 gl::Context *context = gl::getContext();
1633
1634 if (context)
1635 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001636 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001637 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001638 textarget = GL_NONE;
1639 }
1640 else
1641 {
1642 gl::Texture *tex = context->getTexture(texture);
1643
1644 if (tex == NULL)
1645 {
1646 return error(GL_INVALID_OPERATION);
1647 }
1648
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001649 switch (textarget)
1650 {
1651 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001652 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001653 {
1654 return error(GL_INVALID_OPERATION);
1655 }
1656 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001657
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001658 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001659 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001660 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001661 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001662 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001663 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001664 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1665 {
1666 return error(GL_INVALID_OPERATION);
1667 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001668 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001669
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001670 default:
1671 return error(GL_INVALID_ENUM);
1672 }
1673
1674 if (level != 0)
1675 {
1676 return error(GL_INVALID_VALUE);
1677 }
1678 }
1679
1680 gl::Framebuffer *framebuffer = context->getFramebuffer();
1681
1682 if (context->framebuffer == 0 || !framebuffer)
1683 {
1684 return error(GL_INVALID_OPERATION);
1685 }
1686
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001687 switch (attachment)
1688 {
1689 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
1690 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
1691 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
1692 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001693 }
1694 }
1695 catch(std::bad_alloc&)
1696 {
1697 return error(GL_OUT_OF_MEMORY);
1698 }
1699}
1700
1701void __stdcall glFrontFace(GLenum mode)
1702{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001703 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001704
1705 try
1706 {
1707 switch (mode)
1708 {
1709 case GL_CW:
1710 case GL_CCW:
1711 {
1712 gl::Context *context = gl::getContext();
1713
1714 if (context)
1715 {
1716 context->frontFace = mode;
1717 }
1718 }
1719 break;
1720 default:
1721 return error(GL_INVALID_ENUM);
1722 }
1723 }
1724 catch(std::bad_alloc&)
1725 {
1726 return error(GL_OUT_OF_MEMORY);
1727 }
1728}
1729
1730void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1731{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001732 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001733
1734 try
1735 {
1736 if (n < 0)
1737 {
1738 return error(GL_INVALID_VALUE);
1739 }
1740
1741 gl::Context *context = gl::getContext();
1742
1743 if (context)
1744 {
1745 for (int i = 0; i < n; i++)
1746 {
1747 buffers[i] = context->createBuffer();
1748 }
1749 }
1750 }
1751 catch(std::bad_alloc&)
1752 {
1753 return error(GL_OUT_OF_MEMORY);
1754 }
1755}
1756
1757void __stdcall glGenerateMipmap(GLenum target)
1758{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001759 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001760
1761 try
1762 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00001763 gl::Context *context = gl::getContext();
1764
1765 if (context)
1766 {
1767 gl::Texture *texture;
1768
1769 switch (target)
1770 {
1771 case GL_TEXTURE_2D:
1772 texture = context->getTexture2D();
1773 break;
1774
1775 case GL_TEXTURE_CUBE_MAP:
1776 texture = context->getTextureCubeMap();
1777 break;
1778
1779 default:
1780 return error(GL_INVALID_ENUM);
1781 }
1782
1783 texture->generateMipmaps();
1784 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001785 }
1786 catch(std::bad_alloc&)
1787 {
1788 return error(GL_OUT_OF_MEMORY);
1789 }
1790}
1791
1792void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1793{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001794 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001795
1796 try
1797 {
1798 if (n < 0)
1799 {
1800 return error(GL_INVALID_VALUE);
1801 }
1802
1803 gl::Context *context = gl::getContext();
1804
1805 if (context)
1806 {
1807 for (int i = 0; i < n; i++)
1808 {
1809 framebuffers[i] = context->createFramebuffer();
1810 }
1811 }
1812 }
1813 catch(std::bad_alloc&)
1814 {
1815 return error(GL_OUT_OF_MEMORY);
1816 }
1817}
1818
1819void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1820{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001821 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001822
1823 try
1824 {
1825 if (n < 0)
1826 {
1827 return error(GL_INVALID_VALUE);
1828 }
1829
1830 gl::Context *context = gl::getContext();
1831
1832 if (context)
1833 {
1834 for (int i = 0; i < n; i++)
1835 {
1836 renderbuffers[i] = context->createRenderbuffer();
1837 }
1838 }
1839 }
1840 catch(std::bad_alloc&)
1841 {
1842 return error(GL_OUT_OF_MEMORY);
1843 }
1844}
1845
1846void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1847{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001848 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001849
1850 try
1851 {
1852 if (n < 0)
1853 {
1854 return error(GL_INVALID_VALUE);
1855 }
1856
1857 gl::Context *context = gl::getContext();
1858
1859 if (context)
1860 {
1861 for (int i = 0; i < n; i++)
1862 {
1863 textures[i] = context->createTexture();
1864 }
1865 }
1866 }
1867 catch(std::bad_alloc&)
1868 {
1869 return error(GL_OUT_OF_MEMORY);
1870 }
1871}
1872
daniel@transgaming.com85423182010-04-22 13:35:27 +00001873void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001874{
daniel@transgaming.com85423182010-04-22 13:35:27 +00001875 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
1876 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001877 program, index, bufsize, length, size, type, name);
1878
1879 try
1880 {
1881 if (bufsize < 0)
1882 {
1883 return error(GL_INVALID_VALUE);
1884 }
1885
daniel@transgaming.com85423182010-04-22 13:35:27 +00001886 gl::Context *context = gl::getContext();
1887
1888 if (context)
1889 {
1890 gl::Program *programObject = context->getProgram(program);
1891
1892 if (!programObject)
1893 {
1894 if (context->getShader(program))
1895 {
1896 return error(GL_INVALID_OPERATION);
1897 }
1898 else
1899 {
1900 return error(GL_INVALID_VALUE);
1901 }
1902 }
1903
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001904 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00001905 {
1906 return error(GL_INVALID_VALUE);
1907 }
1908
1909 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
1910 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001911 }
1912 catch(std::bad_alloc&)
1913 {
1914 return error(GL_OUT_OF_MEMORY);
1915 }
1916}
1917
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001918void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001919{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001920 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001921 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001922 program, index, bufsize, length, size, type, name);
1923
1924 try
1925 {
1926 if (bufsize < 0)
1927 {
1928 return error(GL_INVALID_VALUE);
1929 }
1930
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001931 gl::Context *context = gl::getContext();
1932
1933 if (context)
1934 {
1935 gl::Program *programObject = context->getProgram(program);
1936
1937 if (!programObject)
1938 {
1939 if (context->getShader(program))
1940 {
1941 return error(GL_INVALID_OPERATION);
1942 }
1943 else
1944 {
1945 return error(GL_INVALID_VALUE);
1946 }
1947 }
1948
1949 if (index >= (GLuint)programObject->getActiveUniformCount())
1950 {
1951 return error(GL_INVALID_VALUE);
1952 }
1953
1954 programObject->getActiveUniform(index, bufsize, length, size, type, name);
1955 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001956 }
1957 catch(std::bad_alloc&)
1958 {
1959 return error(GL_OUT_OF_MEMORY);
1960 }
1961}
1962
1963void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1964{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001965 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1966 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001967
1968 try
1969 {
1970 if (maxcount < 0)
1971 {
1972 return error(GL_INVALID_VALUE);
1973 }
1974
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001975 gl::Context *context = gl::getContext();
1976
1977 if (context)
1978 {
1979 gl::Program *programObject = context->getProgram(program);
1980
1981 if (!programObject)
1982 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001983 if (context->getShader(program))
1984 {
1985 return error(GL_INVALID_OPERATION);
1986 }
1987 else
1988 {
1989 return error(GL_INVALID_VALUE);
1990 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001991 }
1992
1993 return programObject->getAttachedShaders(maxcount, count, shaders);
1994 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001995 }
1996 catch(std::bad_alloc&)
1997 {
1998 return error(GL_OUT_OF_MEMORY);
1999 }
2000}
2001
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002002int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002003{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002004 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002005
2006 try
2007 {
2008 gl::Context *context = gl::getContext();
2009
2010 if (context)
2011 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002012
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002013 gl::Program *programObject = context->getProgram(program);
2014
2015 if (!programObject)
2016 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002017 if (context->getShader(program))
2018 {
2019 return error(GL_INVALID_OPERATION, -1);
2020 }
2021 else
2022 {
2023 return error(GL_INVALID_VALUE, -1);
2024 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002025 }
2026
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002027 if (!programObject->isLinked())
2028 {
2029 return error(GL_INVALID_OPERATION, -1);
2030 }
2031
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002032 return programObject->getAttributeLocation(name);
2033 }
2034 }
2035 catch(std::bad_alloc&)
2036 {
2037 return error(GL_OUT_OF_MEMORY, -1);
2038 }
2039
2040 return -1;
2041}
2042
2043void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2044{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002045 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002046
2047 try
2048 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002049 gl::Context *context = gl::getContext();
2050
2051 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002052 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002053 if (!(context->getBooleanv(pname, params)))
2054 {
2055 GLenum nativeType;
2056 unsigned int numParams = 0;
2057 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2058 return error(GL_INVALID_ENUM);
2059
2060 if (numParams == 0)
2061 return; // it is known that the pname is valid, but there are no parameters to return
2062
2063 if (nativeType == GL_FLOAT)
2064 {
2065 GLfloat *floatParams = NULL;
2066 floatParams = new GLfloat[numParams];
2067
2068 context->getFloatv(pname, floatParams);
2069
2070 for (unsigned int i = 0; i < numParams; ++i)
2071 {
2072 if (floatParams[i] == 0.0f)
2073 params[i] = GL_FALSE;
2074 else
2075 params[i] = GL_TRUE;
2076 }
2077
2078 delete [] floatParams;
2079 }
2080 else if (nativeType == GL_INT)
2081 {
2082 GLint *intParams = NULL;
2083 intParams = new GLint[numParams];
2084
2085 context->getIntegerv(pname, intParams);
2086
2087 for (unsigned int i = 0; i < numParams; ++i)
2088 {
2089 if (intParams[i] == 0)
2090 params[i] = GL_FALSE;
2091 else
2092 params[i] = GL_TRUE;
2093 }
2094
2095 delete [] intParams;
2096 }
2097 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002098 }
2099 }
2100 catch(std::bad_alloc&)
2101 {
2102 return error(GL_OUT_OF_MEMORY);
2103 }
2104}
2105
2106void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2107{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002108 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002109
2110 try
2111 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002112 gl::Context *context = gl::getContext();
2113
2114 if (context)
2115 {
2116 gl::Buffer *buffer;
2117
2118 switch (target)
2119 {
2120 case GL_ARRAY_BUFFER:
2121 buffer = context->getArrayBuffer();
2122 break;
2123 case GL_ELEMENT_ARRAY_BUFFER:
2124 buffer = context->getElementArrayBuffer();
2125 break;
2126 default: return error(GL_INVALID_ENUM);
2127 }
2128
2129 if (!buffer)
2130 {
2131 // A null buffer means that "0" is bound to the requested buffer target
2132 return error(GL_INVALID_OPERATION);
2133 }
2134
2135 switch (pname)
2136 {
2137 case GL_BUFFER_USAGE:
2138 *params = buffer->usage();
2139 break;
2140 case GL_BUFFER_SIZE:
2141 *params = buffer->size();
2142 break;
2143 default: return error(GL_INVALID_ENUM);
2144 }
2145 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002146 }
2147 catch(std::bad_alloc&)
2148 {
2149 return error(GL_OUT_OF_MEMORY);
2150 }
2151}
2152
2153GLenum __stdcall glGetError(void)
2154{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002155 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002156
2157 gl::Context *context = gl::getContext();
2158
2159 if (context)
2160 {
2161 return context->getError();
2162 }
2163
2164 return GL_NO_ERROR;
2165}
2166
2167void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2168{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002169 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002170
2171 try
2172 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002173 gl::Context *context = gl::getContext();
2174
2175 if (context)
2176 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002177 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002178 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002179 GLenum nativeType;
2180 unsigned int numParams = 0;
2181 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2182 return error(GL_INVALID_ENUM);
2183
2184 if (numParams == 0)
2185 return; // it is known that the pname is valid, but that there are no parameters to return.
2186
2187 if (nativeType == GL_BOOL)
2188 {
2189 GLboolean *boolParams = NULL;
2190 boolParams = new GLboolean[numParams];
2191
2192 context->getBooleanv(pname, boolParams);
2193
2194 for (unsigned int i = 0; i < numParams; ++i)
2195 {
2196 if (boolParams[i] == GL_FALSE)
2197 params[i] = 0.0f;
2198 else
2199 params[i] = 1.0f;
2200 }
2201
2202 delete [] boolParams;
2203 }
2204 else if (nativeType == GL_INT)
2205 {
2206 GLint *intParams = NULL;
2207 intParams = new GLint[numParams];
2208
2209 context->getIntegerv(pname, intParams);
2210
2211 for (unsigned int i = 0; i < numParams; ++i)
2212 {
2213 params[i] = (GLfloat)intParams[i];
2214 }
2215
2216 delete [] intParams;
2217 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002218 }
2219 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002220 }
2221 catch(std::bad_alloc&)
2222 {
2223 return error(GL_OUT_OF_MEMORY);
2224 }
2225}
2226
2227void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2228{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002229 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2230 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002231
2232 try
2233 {
2234 gl::Context *context = gl::getContext();
2235
2236 if (context)
2237 {
2238 if (context->framebuffer == 0)
2239 {
2240 return error(GL_INVALID_OPERATION);
2241 }
2242
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002243 if (target != GL_FRAMEBUFFER)
2244 {
2245 return error(GL_INVALID_ENUM);
2246 }
2247
2248 GLenum attachmentType;
2249 GLuint attachmentHandle;
2250 switch (attachment)
2251 {
2252 case GL_COLOR_ATTACHMENT0:
2253 attachmentType = context->getFramebuffer()->getColorbufferType();
2254 attachmentHandle = context->getFramebuffer()->getColorbufferHandle();
2255 break;
2256 case GL_DEPTH_ATTACHMENT:
2257 attachmentType = context->getFramebuffer()->getDepthbufferType();
2258 attachmentHandle = context->getFramebuffer()->getDepthbufferHandle();
2259 break;
2260 case GL_STENCIL_ATTACHMENT:
2261 attachmentType = context->getFramebuffer()->getStencilbufferType();
2262 attachmentHandle = context->getFramebuffer()->getStencilbufferHandle();
2263 break;
2264 default: return error(GL_INVALID_ENUM);
2265 }
2266
2267 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002268 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002269 {
2270 attachmentObjectType = attachmentType;
2271 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002272 else if (es2dx::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002273 {
2274 attachmentObjectType = GL_TEXTURE;
2275 }
2276 else UNREACHABLE();
2277
2278 switch (pname)
2279 {
2280 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2281 *params = attachmentObjectType;
2282 break;
2283 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2284 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2285 {
2286 *params = attachmentHandle;
2287 }
2288 else
2289 {
2290 return error(GL_INVALID_ENUM);
2291 }
2292 break;
2293 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2294 if (attachmentObjectType == GL_TEXTURE)
2295 {
2296 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2297 }
2298 else
2299 {
2300 return error(GL_INVALID_ENUM);
2301 }
2302 break;
2303 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2304 if (attachmentObjectType == GL_TEXTURE)
2305 {
2306 if (es2dx::IsCubemapTextureTarget(attachmentType))
2307 {
2308 *params = attachmentType;
2309 }
2310 else
2311 {
2312 *params = 0;
2313 }
2314 }
2315 else
2316 {
2317 return error(GL_INVALID_ENUM);
2318 }
2319 break;
2320 default:
2321 return error(GL_INVALID_ENUM);
2322 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002323 }
2324 }
2325 catch(std::bad_alloc&)
2326 {
2327 return error(GL_OUT_OF_MEMORY);
2328 }
2329}
2330
2331void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2332{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002333 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002334
2335 try
2336 {
2337 gl::Context *context = gl::getContext();
2338
2339 if (context)
2340 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002341 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002342 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002343 GLenum nativeType;
2344 unsigned int numParams = 0;
2345 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2346 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002347
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002348 if (numParams == 0)
2349 return; // it is known that pname is valid, but there are no parameters to return
2350
2351 if (nativeType == GL_BOOL)
2352 {
2353 GLboolean *boolParams = NULL;
2354 boolParams = new GLboolean[numParams];
2355
2356 context->getBooleanv(pname, boolParams);
2357
2358 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002359 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002360 if (boolParams[i] == GL_FALSE)
2361 params[i] = 0;
2362 else
2363 params[i] = 1;
2364 }
2365
2366 delete [] boolParams;
2367 }
2368 else if (nativeType == GL_FLOAT)
2369 {
2370 GLfloat *floatParams = NULL;
2371 floatParams = new GLfloat[numParams];
2372
2373 context->getFloatv(pname, floatParams);
2374
2375 for (unsigned int i = 0; i < numParams; ++i)
2376 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002377 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002378 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002379 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002380 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002381 else
2382 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002383 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002384
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002385 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002386 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002387 }
2388 }
2389 }
2390 catch(std::bad_alloc&)
2391 {
2392 return error(GL_OUT_OF_MEMORY);
2393 }
2394}
2395
2396void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2397{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002398 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002399
2400 try
2401 {
2402 gl::Context *context = gl::getContext();
2403
2404 if (context)
2405 {
2406 gl::Program *programObject = context->getProgram(program);
2407
2408 if (!programObject)
2409 {
2410 return error(GL_INVALID_VALUE);
2411 }
2412
2413 switch (pname)
2414 {
2415 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002416 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002417 return;
2418 case GL_LINK_STATUS:
2419 *params = programObject->isLinked();
2420 return;
2421 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002422 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002423 return;
2424 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002425 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002426 return;
2427 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002428 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002429 return;
2430 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002431 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002432 return;
2433 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002434 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002435 return;
2436 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002437 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002438 return;
2439 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002440 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002441 return;
2442 default:
2443 return error(GL_INVALID_ENUM);
2444 }
2445 }
2446 }
2447 catch(std::bad_alloc&)
2448 {
2449 return error(GL_OUT_OF_MEMORY);
2450 }
2451}
2452
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002453void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002454{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002455 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002456 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002457
2458 try
2459 {
2460 if (bufsize < 0)
2461 {
2462 return error(GL_INVALID_VALUE);
2463 }
2464
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002465 gl::Context *context = gl::getContext();
2466
2467 if (context)
2468 {
2469 gl::Program *programObject = context->getProgram(program);
2470
2471 if (!programObject)
2472 {
2473 return error(GL_INVALID_VALUE);
2474 }
2475
2476 programObject->getInfoLog(bufsize, length, infolog);
2477 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002478 }
2479 catch(std::bad_alloc&)
2480 {
2481 return error(GL_OUT_OF_MEMORY);
2482 }
2483}
2484
2485void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2486{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002487 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002488
2489 try
2490 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002491 gl::Context *context = gl::getContext();
2492
2493 if (context)
2494 {
2495 if (target != GL_RENDERBUFFER)
2496 {
2497 return error(GL_INVALID_ENUM);
2498 }
2499
2500 if (context->renderbuffer == 0)
2501 {
2502 return error(GL_INVALID_OPERATION);
2503 }
2504
2505 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->renderbuffer);
2506
2507 switch (pname)
2508 {
2509 case GL_RENDERBUFFER_WIDTH:
2510 *params = renderbuffer->getWidth();
2511 break;
2512 case GL_RENDERBUFFER_HEIGHT:
2513 *params = renderbuffer->getHeight();
2514 break;
2515 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2516 *params = renderbuffer->getFormat();
2517 break;
2518 case GL_RENDERBUFFER_RED_SIZE:
2519 if (renderbuffer->isColorbuffer())
2520 {
2521 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
2522 }
2523 else
2524 {
2525 *params = 0;
2526 }
2527 break;
2528 case GL_RENDERBUFFER_GREEN_SIZE:
2529 if (renderbuffer->isColorbuffer())
2530 {
2531 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
2532 }
2533 else
2534 {
2535 *params = 0;
2536 }
2537 break;
2538 case GL_RENDERBUFFER_BLUE_SIZE:
2539 if (renderbuffer->isColorbuffer())
2540 {
2541 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
2542 }
2543 else
2544 {
2545 *params = 0;
2546 }
2547 break;
2548 case GL_RENDERBUFFER_ALPHA_SIZE:
2549 if (renderbuffer->isColorbuffer())
2550 {
2551 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
2552 }
2553 else
2554 {
2555 *params = 0;
2556 }
2557 break;
2558 case GL_RENDERBUFFER_DEPTH_SIZE:
2559 if (renderbuffer->isDepthbuffer())
2560 {
2561 *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
2562 }
2563 else
2564 {
2565 *params = 0;
2566 }
2567 break;
2568 case GL_RENDERBUFFER_STENCIL_SIZE:
2569 if (renderbuffer->isStencilbuffer())
2570 {
2571 *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
2572 }
2573 else
2574 {
2575 *params = 0;
2576 }
2577 break;
2578 default:
2579 return error(GL_INVALID_ENUM);
2580 }
2581 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002582 }
2583 catch(std::bad_alloc&)
2584 {
2585 return error(GL_OUT_OF_MEMORY);
2586 }
2587}
2588
2589void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2590{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002591 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002592
2593 try
2594 {
2595 gl::Context *context = gl::getContext();
2596
2597 if (context)
2598 {
2599 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002600
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002601 if (!shaderObject)
2602 {
2603 return error(GL_INVALID_VALUE);
2604 }
2605
2606 switch (pname)
2607 {
2608 case GL_SHADER_TYPE:
2609 *params = shaderObject->getType();
2610 return;
2611 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002612 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002613 return;
2614 case GL_COMPILE_STATUS:
2615 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2616 return;
2617 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002618 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002619 return;
2620 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002621 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002622 return;
2623 default:
2624 return error(GL_INVALID_ENUM);
2625 }
2626 }
2627 }
2628 catch(std::bad_alloc&)
2629 {
2630 return error(GL_OUT_OF_MEMORY);
2631 }
2632}
2633
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002634void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002635{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002636 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002637 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002638
2639 try
2640 {
2641 if (bufsize < 0)
2642 {
2643 return error(GL_INVALID_VALUE);
2644 }
2645
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002646 gl::Context *context = gl::getContext();
2647
2648 if (context)
2649 {
2650 gl::Shader *shaderObject = context->getShader(shader);
2651
2652 if (!shaderObject)
2653 {
2654 return error(GL_INVALID_VALUE);
2655 }
2656
2657 shaderObject->getInfoLog(bufsize, length, infolog);
2658 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002659 }
2660 catch(std::bad_alloc&)
2661 {
2662 return error(GL_OUT_OF_MEMORY);
2663 }
2664}
2665
2666void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2667{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002668 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2669 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002670
2671 try
2672 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002673 switch (shadertype)
2674 {
2675 case GL_VERTEX_SHADER:
2676 case GL_FRAGMENT_SHADER:
2677 break;
2678 default:
2679 return error(GL_INVALID_ENUM);
2680 }
2681
2682 switch (precisiontype)
2683 {
2684 case GL_LOW_FLOAT:
2685 case GL_MEDIUM_FLOAT:
2686 case GL_HIGH_FLOAT:
2687 // Assume IEEE 754 precision
2688 range[0] = 127;
2689 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002690 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002691 break;
2692 case GL_LOW_INT:
2693 case GL_MEDIUM_INT:
2694 case GL_HIGH_INT:
2695 // Some (most) hardware only supports single-precision floating-point numbers,
2696 // which can accurately represent integers up to +/-16777216
2697 range[0] = 24;
2698 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002699 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002700 break;
2701 default:
2702 return error(GL_INVALID_ENUM);
2703 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002704 }
2705 catch(std::bad_alloc&)
2706 {
2707 return error(GL_OUT_OF_MEMORY);
2708 }
2709}
2710
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002711void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002712{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002713 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002714 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002715
2716 try
2717 {
2718 if (bufsize < 0)
2719 {
2720 return error(GL_INVALID_VALUE);
2721 }
2722
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002723 gl::Context *context = gl::getContext();
2724
2725 if (context)
2726 {
2727 gl::Shader *shaderObject = context->getShader(shader);
2728
2729 if (!shaderObject)
2730 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002731 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002732 }
2733
2734 shaderObject->getSource(bufsize, length, source);
2735 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002736 }
2737 catch(std::bad_alloc&)
2738 {
2739 return error(GL_OUT_OF_MEMORY);
2740 }
2741}
2742
2743const GLubyte* __stdcall glGetString(GLenum name)
2744{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002745 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002746
2747 try
2748 {
2749 switch (name)
2750 {
2751 case GL_VENDOR:
2752 return (GLubyte*)"TransGaming Inc.";
2753 case GL_RENDERER:
2754 return (GLubyte*)"ANGLE";
2755 case GL_VERSION:
2756 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2757 case GL_SHADING_LANGUAGE_VERSION:
2758 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2759 case GL_EXTENSIONS:
2760 return (GLubyte*)"";
2761 default:
2762 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2763 }
2764 }
2765 catch(std::bad_alloc&)
2766 {
2767 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2768 }
2769
2770 return NULL;
2771}
2772
2773void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2774{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002775 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002776
2777 try
2778 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002779 gl::Context *context = gl::getContext();
2780
2781 if (context)
2782 {
2783 gl::Texture *texture;
2784
2785 switch (target)
2786 {
2787 case GL_TEXTURE_2D:
2788 texture = context->getTexture2D();
2789 break;
2790 case GL_TEXTURE_CUBE_MAP:
2791 texture = context->getTextureCubeMap();
2792 break;
2793 default:
2794 return error(GL_INVALID_ENUM);
2795 }
2796
2797 switch (pname)
2798 {
2799 case GL_TEXTURE_MAG_FILTER:
2800 *params = (GLfloat)texture->getMagFilter();
2801 break;
2802 case GL_TEXTURE_MIN_FILTER:
2803 *params = (GLfloat)texture->getMinFilter();
2804 break;
2805 case GL_TEXTURE_WRAP_S:
2806 *params = (GLfloat)texture->getWrapS();
2807 break;
2808 case GL_TEXTURE_WRAP_T:
2809 *params = (GLfloat)texture->getWrapT();
2810 break;
2811 default:
2812 return error(GL_INVALID_ENUM);
2813 }
2814 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002815 }
2816 catch(std::bad_alloc&)
2817 {
2818 return error(GL_OUT_OF_MEMORY);
2819 }
2820}
2821
2822void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2823{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002824 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002825
2826 try
2827 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002828 gl::Context *context = gl::getContext();
2829
2830 if (context)
2831 {
2832 gl::Texture *texture;
2833
2834 switch (target)
2835 {
2836 case GL_TEXTURE_2D:
2837 texture = context->getTexture2D();
2838 break;
2839 case GL_TEXTURE_CUBE_MAP:
2840 texture = context->getTextureCubeMap();
2841 break;
2842 default:
2843 return error(GL_INVALID_ENUM);
2844 }
2845
2846 switch (pname)
2847 {
2848 case GL_TEXTURE_MAG_FILTER:
2849 *params = texture->getMagFilter();
2850 break;
2851 case GL_TEXTURE_MIN_FILTER:
2852 *params = texture->getMinFilter();
2853 break;
2854 case GL_TEXTURE_WRAP_S:
2855 *params = texture->getWrapS();
2856 break;
2857 case GL_TEXTURE_WRAP_T:
2858 *params = texture->getWrapT();
2859 break;
2860 default:
2861 return error(GL_INVALID_ENUM);
2862 }
2863 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002864 }
2865 catch(std::bad_alloc&)
2866 {
2867 return error(GL_OUT_OF_MEMORY);
2868 }
2869}
2870
2871void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2872{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002873 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002874
2875 try
2876 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002877 gl::Context *context = gl::getContext();
2878
2879 if (context)
2880 {
2881 if (program == 0)
2882 {
2883 return error(GL_INVALID_VALUE);
2884 }
2885
2886 gl::Program *programObject = context->getProgram(program);
2887
2888 if (!programObject || !programObject->isLinked())
2889 {
2890 return error(GL_INVALID_OPERATION);
2891 }
2892
2893 if (!programObject->getUniformfv(location, params))
2894 {
2895 return error(GL_INVALID_OPERATION);
2896 }
2897 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002898 }
2899 catch(std::bad_alloc&)
2900 {
2901 return error(GL_OUT_OF_MEMORY);
2902 }
2903}
2904
2905void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2906{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002907 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002908
2909 try
2910 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002911 gl::Context *context = gl::getContext();
2912
2913 if (context)
2914 {
2915 if (program == 0)
2916 {
2917 return error(GL_INVALID_VALUE);
2918 }
2919
2920 gl::Program *programObject = context->getProgram(program);
2921
2922 if (!programObject || !programObject->isLinked())
2923 {
2924 return error(GL_INVALID_OPERATION);
2925 }
2926
2927 if (!programObject)
2928 {
2929 return error(GL_INVALID_OPERATION);
2930 }
2931
2932 if (!programObject->getUniformiv(location, params))
2933 {
2934 return error(GL_INVALID_OPERATION);
2935 }
2936 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002937 }
2938 catch(std::bad_alloc&)
2939 {
2940 return error(GL_OUT_OF_MEMORY);
2941 }
2942}
2943
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002944int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002945{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002946 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002947
2948 try
2949 {
2950 gl::Context *context = gl::getContext();
2951
2952 if (strstr(name, "gl_") == name)
2953 {
2954 return -1;
2955 }
2956
2957 if (context)
2958 {
2959 gl::Program *programObject = context->getProgram(program);
2960
2961 if (!programObject)
2962 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002963 if (context->getShader(program))
2964 {
2965 return error(GL_INVALID_OPERATION, -1);
2966 }
2967 else
2968 {
2969 return error(GL_INVALID_VALUE, -1);
2970 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002971 }
2972
2973 if (!programObject->isLinked())
2974 {
2975 return error(GL_INVALID_OPERATION, -1);
2976 }
2977
2978 return programObject->getUniformLocation(name);
2979 }
2980 }
2981 catch(std::bad_alloc&)
2982 {
2983 return error(GL_OUT_OF_MEMORY, -1);
2984 }
2985
2986 return -1;
2987}
2988
2989void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2990{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002991 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002992
2993 try
2994 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002995 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002996
daniel@transgaming.come0078962010-04-15 20:45:08 +00002997 if (context)
2998 {
2999 if (index >= gl::MAX_VERTEX_ATTRIBS)
3000 {
3001 return error(GL_INVALID_VALUE);
3002 }
3003
3004 switch (pname)
3005 {
3006 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3007 *params = (GLfloat)(context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
3008 break;
3009 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3010 *params = (GLfloat)context->vertexAttribute[index].mSize;
3011 break;
3012 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3013 *params = (GLfloat)context->vertexAttribute[index].mStride;
3014 break;
3015 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3016 *params = (GLfloat)context->vertexAttribute[index].mType;
3017 break;
3018 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3019 *params = (GLfloat)(context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
3020 break;
3021 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
3022 *params = (GLfloat)context->vertexAttribute[index].mBoundBuffer;
3023 break;
3024 case GL_CURRENT_VERTEX_ATTRIB:
3025 for (int i = 0; i < 4; ++i)
3026 {
3027 params[i] = context->vertexAttribute[index].mCurrentValue[i];
3028 }
3029 break;
3030 default: return error(GL_INVALID_ENUM);
3031 }
3032 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003033 }
3034 catch(std::bad_alloc&)
3035 {
3036 return error(GL_OUT_OF_MEMORY);
3037 }
3038}
3039
3040void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3041{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003042 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003043
3044 try
3045 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003046 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003047
daniel@transgaming.come0078962010-04-15 20:45:08 +00003048 if (context)
3049 {
3050 if (index >= gl::MAX_VERTEX_ATTRIBS)
3051 {
3052 return error(GL_INVALID_VALUE);
3053 }
3054
3055 switch (pname)
3056 {
3057 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3058 *params = (context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
3059 break;
3060 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3061 *params = context->vertexAttribute[index].mSize;
3062 break;
3063 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3064 *params = context->vertexAttribute[index].mStride;
3065 break;
3066 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3067 *params = context->vertexAttribute[index].mType;
3068 break;
3069 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3070 *params = (context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
3071 break;
3072 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
3073 *params = context->vertexAttribute[index].mBoundBuffer;
3074 break;
3075 case GL_CURRENT_VERTEX_ATTRIB:
3076 for (int i = 0; i < 4; ++i)
3077 {
3078 float currentValue = context->vertexAttribute[index].mCurrentValue[i];
3079 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3080 }
3081 break;
3082 default: return error(GL_INVALID_ENUM);
3083 }
3084 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003085 }
3086 catch(std::bad_alloc&)
3087 {
3088 return error(GL_OUT_OF_MEMORY);
3089 }
3090}
3091
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003092void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003093{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003094 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003095
3096 try
3097 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003098 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003099
daniel@transgaming.come0078962010-04-15 20:45:08 +00003100 if (context)
3101 {
3102 if (index >= gl::MAX_VERTEX_ATTRIBS)
3103 {
3104 return error(GL_INVALID_VALUE);
3105 }
3106
3107 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3108 {
3109 return error(GL_INVALID_ENUM);
3110 }
3111
3112 *pointer = const_cast<GLvoid*>(context->vertexAttribute[index].mPointer);
3113 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003114 }
3115 catch(std::bad_alloc&)
3116 {
3117 return error(GL_OUT_OF_MEMORY);
3118 }
3119}
3120
3121void __stdcall glHint(GLenum target, GLenum mode)
3122{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003123 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003124
3125 try
3126 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003127 switch (target)
3128 {
3129 case GL_GENERATE_MIPMAP_HINT:
3130 switch (mode)
3131 {
3132 case GL_FASTEST:
3133 case GL_NICEST:
3134 case GL_DONT_CARE:
3135 break;
3136 default:
3137 return error(GL_INVALID_ENUM);
3138 }
3139 break;
3140 default:
3141 return error(GL_INVALID_ENUM);
3142 }
3143
3144 gl::Context *context = gl::getContext();
3145 if (context)
3146 {
3147 if (target == GL_GENERATE_MIPMAP_HINT)
3148 context->generateMipmapHint = mode;
3149 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003150 }
3151 catch(std::bad_alloc&)
3152 {
3153 return error(GL_OUT_OF_MEMORY);
3154 }
3155}
3156
3157GLboolean __stdcall glIsBuffer(GLuint buffer)
3158{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003159 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003160
3161 try
3162 {
3163 gl::Context *context = gl::getContext();
3164
3165 if (context && buffer)
3166 {
3167 gl::Buffer *bufferObject = context->getBuffer(buffer);
3168
3169 if (bufferObject)
3170 {
3171 return GL_TRUE;
3172 }
3173 }
3174 }
3175 catch(std::bad_alloc&)
3176 {
3177 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3178 }
3179
3180 return GL_FALSE;
3181}
3182
3183GLboolean __stdcall glIsEnabled(GLenum cap)
3184{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003185 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003186
3187 try
3188 {
3189 gl::Context *context = gl::getContext();
3190
3191 if (context)
3192 {
3193 switch (cap)
3194 {
3195 case GL_CULL_FACE: return context->cullFace;
3196 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
3197 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
3198 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
3199 case GL_SCISSOR_TEST: return context->scissorTest;
3200 case GL_STENCIL_TEST: return context->stencilTest;
3201 case GL_DEPTH_TEST: return context->depthTest;
3202 case GL_BLEND: return context->blend;
3203 case GL_DITHER: return context->dither;
3204 default:
3205 return error(GL_INVALID_ENUM, false);
3206 }
3207 }
3208 }
3209 catch(std::bad_alloc&)
3210 {
3211 return error(GL_OUT_OF_MEMORY, false);
3212 }
3213
3214 return false;
3215}
3216
3217GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3218{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003219 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003220
3221 try
3222 {
3223 gl::Context *context = gl::getContext();
3224
3225 if (context && framebuffer)
3226 {
3227 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3228
3229 if (framebufferObject)
3230 {
3231 return GL_TRUE;
3232 }
3233 }
3234 }
3235 catch(std::bad_alloc&)
3236 {
3237 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3238 }
3239
3240 return GL_FALSE;
3241}
3242
3243GLboolean __stdcall glIsProgram(GLuint program)
3244{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003245 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003246
3247 try
3248 {
3249 gl::Context *context = gl::getContext();
3250
3251 if (context && program)
3252 {
3253 gl::Program *programObject = context->getProgram(program);
3254
3255 if (programObject)
3256 {
3257 return GL_TRUE;
3258 }
3259 }
3260 }
3261 catch(std::bad_alloc&)
3262 {
3263 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3264 }
3265
3266 return GL_FALSE;
3267}
3268
3269GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3270{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003271 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003272
3273 try
3274 {
3275 gl::Context *context = gl::getContext();
3276
3277 if (context && renderbuffer)
3278 {
3279 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3280
3281 if (renderbufferObject)
3282 {
3283 return GL_TRUE;
3284 }
3285 }
3286 }
3287 catch(std::bad_alloc&)
3288 {
3289 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3290 }
3291
3292 return GL_FALSE;
3293}
3294
3295GLboolean __stdcall glIsShader(GLuint shader)
3296{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003297 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003298
3299 try
3300 {
3301 gl::Context *context = gl::getContext();
3302
3303 if (context && shader)
3304 {
3305 gl::Shader *shaderObject = context->getShader(shader);
3306
3307 if (shaderObject)
3308 {
3309 return GL_TRUE;
3310 }
3311 }
3312 }
3313 catch(std::bad_alloc&)
3314 {
3315 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3316 }
3317
3318 return GL_FALSE;
3319}
3320
3321GLboolean __stdcall glIsTexture(GLuint texture)
3322{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003323 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003324
3325 try
3326 {
3327 gl::Context *context = gl::getContext();
3328
3329 if (context && texture)
3330 {
3331 gl::Texture *textureObject = context->getTexture(texture);
3332
3333 if (textureObject)
3334 {
3335 return GL_TRUE;
3336 }
3337 }
3338 }
3339 catch(std::bad_alloc&)
3340 {
3341 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3342 }
3343
3344 return GL_FALSE;
3345}
3346
3347void __stdcall glLineWidth(GLfloat width)
3348{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003349 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003350
3351 try
3352 {
3353 if (width <= 0.0f)
3354 {
3355 return error(GL_INVALID_VALUE);
3356 }
3357
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003358 gl::Context *context = gl::getContext();
3359
3360 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003361 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003362 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003363 }
3364 }
3365 catch(std::bad_alloc&)
3366 {
3367 return error(GL_OUT_OF_MEMORY);
3368 }
3369}
3370
3371void __stdcall glLinkProgram(GLuint program)
3372{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003373 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003374
3375 try
3376 {
3377 gl::Context *context = gl::getContext();
3378
3379 if (context)
3380 {
3381 gl::Program *programObject = context->getProgram(program);
3382
3383 if (!programObject)
3384 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003385 if (context->getShader(program))
3386 {
3387 return error(GL_INVALID_OPERATION);
3388 }
3389 else
3390 {
3391 return error(GL_INVALID_VALUE);
3392 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003393 }
3394
3395 programObject->link();
3396 }
3397 }
3398 catch(std::bad_alloc&)
3399 {
3400 return error(GL_OUT_OF_MEMORY);
3401 }
3402}
3403
3404void __stdcall glPixelStorei(GLenum pname, GLint param)
3405{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003406 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003407
3408 try
3409 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003410 gl::Context *context = gl::getContext();
3411
3412 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003413 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003414 switch (pname)
3415 {
3416 case GL_UNPACK_ALIGNMENT:
3417 if (param != 1 && param != 2 && param != 4 && param != 8)
3418 {
3419 return error(GL_INVALID_VALUE);
3420 }
3421
3422 context->unpackAlignment = param;
3423 break;
3424
3425 case GL_PACK_ALIGNMENT:
3426 if (param != 1 && param != 2 && param != 4 && param != 8)
3427 {
3428 return error(GL_INVALID_VALUE);
3429 }
3430
3431 context->packAlignment = param;
3432 break;
3433
3434 default:
3435 return error(GL_INVALID_ENUM);
3436 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003437 }
3438 }
3439 catch(std::bad_alloc&)
3440 {
3441 return error(GL_OUT_OF_MEMORY);
3442 }
3443}
3444
3445void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3446{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003447 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003448
3449 try
3450 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003451 gl::Context *context = gl::getContext();
3452
3453 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003454 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003455 context->polygonOffsetFactor = factor;
3456 context->polygonOffsetUnits = units;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003457 }
3458 }
3459 catch(std::bad_alloc&)
3460 {
3461 return error(GL_OUT_OF_MEMORY);
3462 }
3463}
3464
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003465void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003466{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003467 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003468 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003469 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003470
3471 try
3472 {
3473 if (width < 0 || height < 0)
3474 {
3475 return error(GL_INVALID_VALUE);
3476 }
3477
3478 switch (format)
3479 {
3480 case GL_RGBA:
3481 switch (type)
3482 {
3483 case GL_UNSIGNED_BYTE:
3484 break;
3485 default:
3486 return error(GL_INVALID_OPERATION);
3487 }
3488 break;
3489 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3490 switch (type)
3491 {
3492 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3493 break;
3494 default:
3495 return error(GL_INVALID_OPERATION);
3496 }
3497 break;
3498 default:
3499 return error(GL_INVALID_OPERATION);
3500 }
3501
3502 gl::Context *context = gl::getContext();
3503
3504 if (context)
3505 {
3506 context->readPixels(x, y, width, height, format, type, pixels);
3507 }
3508 }
3509 catch(std::bad_alloc&)
3510 {
3511 return error(GL_OUT_OF_MEMORY);
3512 }
3513}
3514
3515void __stdcall glReleaseShaderCompiler(void)
3516{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003517 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003518
3519 try
3520 {
3521 gl::Shader::releaseCompiler();
3522 }
3523 catch(std::bad_alloc&)
3524 {
3525 return error(GL_OUT_OF_MEMORY);
3526 }
3527}
3528
3529void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3530{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003531 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3532 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003533
3534 try
3535 {
3536 switch (target)
3537 {
3538 case GL_RENDERBUFFER:
3539 break;
3540 default:
3541 return error(GL_INVALID_ENUM);
3542 }
3543
3544 switch (internalformat)
3545 {
3546 case GL_DEPTH_COMPONENT16:
3547 case GL_RGBA4:
3548 case GL_RGB5_A1:
3549 case GL_RGB565:
3550 case GL_STENCIL_INDEX8:
3551 break;
3552 default:
3553 return error(GL_INVALID_ENUM);
3554 }
3555
3556 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3557 {
3558 return error(GL_INVALID_VALUE);
3559 }
3560
3561 gl::Context *context = gl::getContext();
3562
3563 if (context)
3564 {
3565 if (context->framebuffer == 0 || context->renderbuffer == 0)
3566 {
3567 return error(GL_INVALID_OPERATION);
3568 }
3569
3570 switch (internalformat)
3571 {
3572 case GL_DEPTH_COMPONENT16:
3573 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3574 break;
3575 case GL_RGBA4:
3576 case GL_RGB5_A1:
3577 case GL_RGB565:
daniel@transgaming.com70d312a2010-04-20 18:52:38 +00003578 context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003579 break;
3580 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003581 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003582 break;
3583 default:
3584 return error(GL_INVALID_ENUM);
3585 }
3586 }
3587 }
3588 catch(std::bad_alloc&)
3589 {
3590 return error(GL_OUT_OF_MEMORY);
3591 }
3592}
3593
3594void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3595{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003596 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003597
3598 try
3599 {
3600 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003601
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003602 if (context)
3603 {
3604 context->sampleCoverageValue = gl::clamp01(value);
3605 context->sampleCoverageInvert = invert;
3606 }
3607 }
3608 catch(std::bad_alloc&)
3609 {
3610 return error(GL_OUT_OF_MEMORY);
3611 }
3612}
3613
3614void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3615{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003616 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003617
3618 try
3619 {
3620 if (width < 0 || height < 0)
3621 {
3622 return error(GL_INVALID_VALUE);
3623 }
3624
3625 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003626
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003627 if (context)
3628 {
3629 context->scissorX = x;
3630 context->scissorY = y;
3631 context->scissorWidth = width;
3632 context->scissorHeight = height;
3633 }
3634 }
3635 catch(std::bad_alloc&)
3636 {
3637 return error(GL_OUT_OF_MEMORY);
3638 }
3639}
3640
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003641void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003642{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003643 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003644 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003645 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003646
3647 try
3648 {
3649 if (n < 0 || length < 0)
3650 {
3651 return error(GL_INVALID_VALUE);
3652 }
3653
3654 UNIMPLEMENTED(); // FIXME
3655 }
3656 catch(std::bad_alloc&)
3657 {
3658 return error(GL_OUT_OF_MEMORY);
3659 }
3660}
3661
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003662void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003663{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003664 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003665 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003666
3667 try
3668 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003669 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003670 {
3671 return error(GL_INVALID_VALUE);
3672 }
3673
3674 gl::Context *context = gl::getContext();
3675
3676 if (context)
3677 {
3678 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003679
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003680 if (!shaderObject)
3681 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003682 if (context->getProgram(shader))
3683 {
3684 return error(GL_INVALID_OPERATION);
3685 }
3686 else
3687 {
3688 return error(GL_INVALID_VALUE);
3689 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003690 }
3691
3692 shaderObject->setSource(count, string, length);
3693 }
3694 }
3695 catch(std::bad_alloc&)
3696 {
3697 return error(GL_OUT_OF_MEMORY);
3698 }
3699}
3700
3701void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3702{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003703 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003704}
3705
3706void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3707{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003708 TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003709
3710 try
3711 {
3712 switch (face)
3713 {
3714 case GL_FRONT:
3715 case GL_BACK:
3716 case GL_FRONT_AND_BACK:
3717 break;
3718 default:
3719 return error(GL_INVALID_ENUM);
3720 }
3721
3722 switch (func)
3723 {
3724 case GL_NEVER:
3725 case GL_ALWAYS:
3726 case GL_LESS:
3727 case GL_LEQUAL:
3728 case GL_EQUAL:
3729 case GL_GEQUAL:
3730 case GL_GREATER:
3731 case GL_NOTEQUAL:
3732 break;
3733 default:
3734 return error(GL_INVALID_ENUM);
3735 }
3736
3737 gl::Context *context = gl::getContext();
3738
3739 if (context)
3740 {
3741 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3742 {
3743 context->stencilFunc = func;
3744 context->stencilRef = ref;
3745 context->stencilMask = mask;
3746 }
3747
3748 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3749 {
3750 context->stencilBackFunc = func;
3751 context->stencilBackRef = ref;
3752 context->stencilBackMask = mask;
3753 }
3754 }
3755 }
3756 catch(std::bad_alloc&)
3757 {
3758 return error(GL_OUT_OF_MEMORY);
3759 }
3760}
3761
3762void __stdcall glStencilMask(GLuint mask)
3763{
3764 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3765}
3766
3767void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3768{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003769 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003770
3771 try
3772 {
3773 switch (face)
3774 {
3775 case GL_FRONT:
3776 case GL_BACK:
3777 case GL_FRONT_AND_BACK:
3778 break;
3779 default:
3780 return error(GL_INVALID_ENUM);
3781 }
3782
3783 gl::Context *context = gl::getContext();
3784
3785 if (context)
3786 {
3787 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3788 {
3789 context->stencilWritemask = mask;
3790 }
3791
3792 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3793 {
3794 context->stencilBackWritemask = mask;
3795 }
3796 }
3797 }
3798 catch(std::bad_alloc&)
3799 {
3800 return error(GL_OUT_OF_MEMORY);
3801 }
3802}
3803
3804void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3805{
3806 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3807}
3808
3809void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3810{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003811 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3812 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003813
3814 try
3815 {
3816 switch (face)
3817 {
3818 case GL_FRONT:
3819 case GL_BACK:
3820 case GL_FRONT_AND_BACK:
3821 break;
3822 default:
3823 return error(GL_INVALID_ENUM);
3824 }
3825
3826 switch (fail)
3827 {
3828 case GL_ZERO:
3829 case GL_KEEP:
3830 case GL_REPLACE:
3831 case GL_INCR:
3832 case GL_DECR:
3833 case GL_INVERT:
3834 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003835 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003836 break;
3837 default:
3838 return error(GL_INVALID_ENUM);
3839 }
3840
3841 switch (zfail)
3842 {
3843 case GL_ZERO:
3844 case GL_KEEP:
3845 case GL_REPLACE:
3846 case GL_INCR:
3847 case GL_DECR:
3848 case GL_INVERT:
3849 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003850 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003851 break;
3852 default:
3853 return error(GL_INVALID_ENUM);
3854 }
3855
3856 switch (zpass)
3857 {
3858 case GL_ZERO:
3859 case GL_KEEP:
3860 case GL_REPLACE:
3861 case GL_INCR:
3862 case GL_DECR:
3863 case GL_INVERT:
3864 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003865 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003866 break;
3867 default:
3868 return error(GL_INVALID_ENUM);
3869 }
3870
3871 gl::Context *context = gl::getContext();
3872
3873 if (context)
3874 {
3875 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3876 {
3877 context->stencilFail = fail;
3878 context->stencilPassDepthFail = zfail;
3879 context->stencilPassDepthPass = zpass;
3880 }
3881
3882 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3883 {
3884 context->stencilBackFail = fail;
3885 context->stencilBackPassDepthFail = zfail;
3886 context->stencilBackPassDepthPass = zpass;
3887 }
3888 }
3889 }
3890 catch(std::bad_alloc&)
3891 {
3892 return error(GL_OUT_OF_MEMORY);
3893 }
3894}
3895
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003896void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3897 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003898{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003899 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003900 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003901 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003902
3903 try
3904 {
3905 if (level < 0 || width < 0 || height < 0)
3906 {
3907 return error(GL_INVALID_VALUE);
3908 }
3909
3910 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3911 {
3912 return error(GL_INVALID_VALUE);
3913 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003914
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003915 switch (target)
3916 {
3917 case GL_TEXTURE_2D:
3918 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3919 {
3920 return error(GL_INVALID_VALUE);
3921 }
3922 break;
3923 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3924 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3925 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3926 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3927 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3928 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003929 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003930 {
3931 return error(GL_INVALID_VALUE);
3932 }
3933
3934 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3935 {
3936 return error(GL_INVALID_VALUE);
3937 }
3938 break;
3939 default:
3940 return error(GL_INVALID_ENUM);
3941 }
3942
3943 if (internalformat != format)
3944 {
3945 return error(GL_INVALID_OPERATION);
3946 }
3947
3948 switch (internalformat)
3949 {
3950 case GL_ALPHA:
3951 case GL_LUMINANCE:
3952 case GL_LUMINANCE_ALPHA:
3953 switch (type)
3954 {
3955 case GL_UNSIGNED_BYTE:
3956 break;
3957 default:
3958 return error(GL_INVALID_ENUM);
3959 }
3960 break;
3961 case GL_RGB:
3962 switch (type)
3963 {
3964 case GL_UNSIGNED_BYTE:
3965 case GL_UNSIGNED_SHORT_5_6_5:
3966 break;
3967 default:
3968 return error(GL_INVALID_ENUM);
3969 }
3970 break;
3971 case GL_RGBA:
3972 switch (type)
3973 {
3974 case GL_UNSIGNED_BYTE:
3975 case GL_UNSIGNED_SHORT_4_4_4_4:
3976 case GL_UNSIGNED_SHORT_5_5_5_1:
3977 break;
3978 default:
3979 return error(GL_INVALID_ENUM);
3980 }
3981 break;
3982 default:
3983 return error(GL_INVALID_VALUE);
3984 }
3985
3986 if (border != 0)
3987 {
3988 return error(GL_INVALID_VALUE);
3989 }
3990
3991 gl::Context *context = gl::getContext();
3992
3993 if (context)
3994 {
3995 if (target == GL_TEXTURE_2D)
3996 {
3997 gl::Texture2D *texture = context->getTexture2D();
3998
3999 if (!texture)
4000 {
4001 return error(GL_INVALID_OPERATION);
4002 }
4003
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004004 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004005 }
4006 else
4007 {
4008 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4009
4010 if (!texture)
4011 {
4012 return error(GL_INVALID_OPERATION);
4013 }
4014
4015 switch (target)
4016 {
4017 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004018 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004019 break;
4020 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004021 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004022 break;
4023 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004024 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004025 break;
4026 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004027 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004028 break;
4029 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004030 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004031 break;
4032 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004033 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004034 break;
4035 default: UNREACHABLE();
4036 }
4037 }
4038 }
4039 }
4040 catch(std::bad_alloc&)
4041 {
4042 return error(GL_OUT_OF_MEMORY);
4043 }
4044}
4045
4046void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4047{
4048 glTexParameteri(target, pname, (GLint)param);
4049}
4050
4051void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4052{
4053 glTexParameteri(target, pname, (GLint)*params);
4054}
4055
4056void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4057{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004058 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004059
4060 try
4061 {
4062 gl::Context *context = gl::getContext();
4063
4064 if (context)
4065 {
4066 gl::Texture *texture;
4067
4068 switch (target)
4069 {
4070 case GL_TEXTURE_2D:
4071 texture = context->getTexture2D();
4072 break;
4073 case GL_TEXTURE_CUBE_MAP:
4074 texture = context->getTextureCubeMap();
4075 break;
4076 default:
4077 return error(GL_INVALID_ENUM);
4078 }
4079
4080 switch (pname)
4081 {
4082 case GL_TEXTURE_WRAP_S:
4083 if (!texture->setWrapS((GLenum)param))
4084 {
4085 return error(GL_INVALID_ENUM);
4086 }
4087 break;
4088 case GL_TEXTURE_WRAP_T:
4089 if (!texture->setWrapT((GLenum)param))
4090 {
4091 return error(GL_INVALID_ENUM);
4092 }
4093 break;
4094 case GL_TEXTURE_MIN_FILTER:
4095 if (!texture->setMinFilter((GLenum)param))
4096 {
4097 return error(GL_INVALID_ENUM);
4098 }
4099 break;
4100 case GL_TEXTURE_MAG_FILTER:
4101 if (!texture->setMagFilter((GLenum)param))
4102 {
4103 return error(GL_INVALID_ENUM);
4104 }
4105 break;
4106 default:
4107 return error(GL_INVALID_ENUM);
4108 }
4109 }
4110 }
4111 catch(std::bad_alloc&)
4112 {
4113 return error(GL_OUT_OF_MEMORY);
4114 }
4115}
4116
4117void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4118{
4119 glTexParameteri(target, pname, *params);
4120}
4121
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004122void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4123 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004124{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004125 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4126 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004127 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004128 target, level, xoffset, yoffset, width, height, format, type, pixels);
4129
4130 try
4131 {
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00004132 if (!es2dx::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004133 {
4134 return error(GL_INVALID_ENUM);
4135 }
4136
4137 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004138 {
4139 return error(GL_INVALID_VALUE);
4140 }
4141
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004142 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4143 {
4144 return error(GL_INVALID_VALUE);
4145 }
4146
4147 if (!es2dx::CheckTextureFormatType(format, type))
4148 {
4149 return error(GL_INVALID_ENUM);
4150 }
4151
4152 if (width == 0 || height == 0 || pixels == NULL)
4153 {
4154 return;
4155 }
4156
4157 gl::Context *context = gl::getContext();
4158
4159 if (context)
4160 {
4161 if (target == GL_TEXTURE_2D)
4162 {
4163 gl::Texture2D *texture = context->getTexture2D();
4164
4165 if (!texture)
4166 {
4167 return error(GL_INVALID_OPERATION);
4168 }
4169
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004170 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004171 }
4172 else if (es2dx::IsCubemapTextureTarget(target))
4173 {
4174 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4175
4176 if (!texture)
4177 {
4178 return error(GL_INVALID_OPERATION);
4179 }
4180
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004181 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004182 }
4183 else
4184 {
4185 UNREACHABLE();
4186 }
4187 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004188 }
4189 catch(std::bad_alloc&)
4190 {
4191 return error(GL_OUT_OF_MEMORY);
4192 }
4193}
4194
4195void __stdcall glUniform1f(GLint location, GLfloat x)
4196{
4197 glUniform1fv(location, 1, &x);
4198}
4199
4200void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4201{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004202 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004203
4204 try
4205 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004206 if (count < 0)
4207 {
4208 return error(GL_INVALID_VALUE);
4209 }
4210
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004211 if (location == -1)
4212 {
4213 return;
4214 }
4215
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004216 gl::Context *context = gl::getContext();
4217
4218 if (context)
4219 {
4220 gl::Program *program = context->getCurrentProgram();
4221
4222 if (!program)
4223 {
4224 return error(GL_INVALID_OPERATION);
4225 }
4226
4227 if (!program->setUniform1fv(location, count, v))
4228 {
4229 return error(GL_INVALID_OPERATION);
4230 }
4231 }
4232 }
4233 catch(std::bad_alloc&)
4234 {
4235 return error(GL_OUT_OF_MEMORY);
4236 }
4237}
4238
4239void __stdcall glUniform1i(GLint location, GLint x)
4240{
4241 glUniform1iv(location, 1, &x);
4242}
4243
4244void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4245{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004246 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004247
4248 try
4249 {
4250 if (count < 0)
4251 {
4252 return error(GL_INVALID_VALUE);
4253 }
4254
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004255 if (location == -1)
4256 {
4257 return;
4258 }
4259
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004260 gl::Context *context = gl::getContext();
4261
4262 if (context)
4263 {
4264 gl::Program *program = context->getCurrentProgram();
4265
4266 if (!program)
4267 {
4268 return error(GL_INVALID_OPERATION);
4269 }
4270
4271 if (!program->setUniform1iv(location, count, v))
4272 {
4273 return error(GL_INVALID_OPERATION);
4274 }
4275 }
4276 }
4277 catch(std::bad_alloc&)
4278 {
4279 return error(GL_OUT_OF_MEMORY);
4280 }
4281}
4282
4283void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4284{
4285 GLfloat xy[2] = {x, y};
4286
4287 glUniform2fv(location, 1, (GLfloat*)&xy);
4288}
4289
4290void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4291{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004292 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004293
4294 try
4295 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004296 if (count < 0)
4297 {
4298 return error(GL_INVALID_VALUE);
4299 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004300
4301 if (location == -1)
4302 {
4303 return;
4304 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004305
4306 gl::Context *context = gl::getContext();
4307
4308 if (context)
4309 {
4310 gl::Program *program = context->getCurrentProgram();
4311
4312 if (!program)
4313 {
4314 return error(GL_INVALID_OPERATION);
4315 }
4316
4317 if (!program->setUniform2fv(location, count, v))
4318 {
4319 return error(GL_INVALID_OPERATION);
4320 }
4321 }
4322 }
4323 catch(std::bad_alloc&)
4324 {
4325 return error(GL_OUT_OF_MEMORY);
4326 }
4327}
4328
4329void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4330{
4331 GLint xy[4] = {x, y};
4332
4333 glUniform2iv(location, 1, (GLint*)&xy);
4334}
4335
4336void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4337{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004338 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004339
4340 try
4341 {
4342 if (count < 0)
4343 {
4344 return error(GL_INVALID_VALUE);
4345 }
4346
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004347 if (location == -1)
4348 {
4349 return;
4350 }
4351
4352 gl::Context *context = gl::getContext();
4353
4354 if (context)
4355 {
4356 gl::Program *program = context->getCurrentProgram();
4357
4358 if (!program)
4359 {
4360 return error(GL_INVALID_OPERATION);
4361 }
4362
4363 if (!program->setUniform2iv(location, count, v))
4364 {
4365 return error(GL_INVALID_OPERATION);
4366 }
4367 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004368 }
4369 catch(std::bad_alloc&)
4370 {
4371 return error(GL_OUT_OF_MEMORY);
4372 }
4373}
4374
4375void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4376{
4377 GLfloat xyz[3] = {x, y, z};
4378
4379 glUniform3fv(location, 1, (GLfloat*)&xyz);
4380}
4381
4382void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4383{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004384 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004385
4386 try
4387 {
4388 if (count < 0)
4389 {
4390 return error(GL_INVALID_VALUE);
4391 }
4392
4393 if (location == -1)
4394 {
4395 return;
4396 }
4397
4398 gl::Context *context = gl::getContext();
4399
4400 if (context)
4401 {
4402 gl::Program *program = context->getCurrentProgram();
4403
4404 if (!program)
4405 {
4406 return error(GL_INVALID_OPERATION);
4407 }
4408
4409 if (!program->setUniform3fv(location, count, v))
4410 {
4411 return error(GL_INVALID_OPERATION);
4412 }
4413 }
4414 }
4415 catch(std::bad_alloc&)
4416 {
4417 return error(GL_OUT_OF_MEMORY);
4418 }
4419}
4420
4421void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4422{
4423 GLint xyz[3] = {x, y, z};
4424
4425 glUniform3iv(location, 1, (GLint*)&xyz);
4426}
4427
4428void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4429{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004430 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004431
4432 try
4433 {
4434 if (count < 0)
4435 {
4436 return error(GL_INVALID_VALUE);
4437 }
4438
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004439 if (location == -1)
4440 {
4441 return;
4442 }
4443
4444 gl::Context *context = gl::getContext();
4445
4446 if (context)
4447 {
4448 gl::Program *program = context->getCurrentProgram();
4449
4450 if (!program)
4451 {
4452 return error(GL_INVALID_OPERATION);
4453 }
4454
4455 if (!program->setUniform3iv(location, count, v))
4456 {
4457 return error(GL_INVALID_OPERATION);
4458 }
4459 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004460 }
4461 catch(std::bad_alloc&)
4462 {
4463 return error(GL_OUT_OF_MEMORY);
4464 }
4465}
4466
4467void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4468{
4469 GLfloat xyzw[4] = {x, y, z, w};
4470
4471 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4472}
4473
4474void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4475{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004476 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004477
4478 try
4479 {
4480 if (count < 0)
4481 {
4482 return error(GL_INVALID_VALUE);
4483 }
4484
4485 if (location == -1)
4486 {
4487 return;
4488 }
4489
4490 gl::Context *context = gl::getContext();
4491
4492 if (context)
4493 {
4494 gl::Program *program = context->getCurrentProgram();
4495
4496 if (!program)
4497 {
4498 return error(GL_INVALID_OPERATION);
4499 }
4500
4501 if (!program->setUniform4fv(location, count, v))
4502 {
4503 return error(GL_INVALID_OPERATION);
4504 }
4505 }
4506 }
4507 catch(std::bad_alloc&)
4508 {
4509 return error(GL_OUT_OF_MEMORY);
4510 }
4511}
4512
4513void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4514{
4515 GLint xyzw[4] = {x, y, z, w};
4516
4517 glUniform4iv(location, 1, (GLint*)&xyzw);
4518}
4519
4520void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4521{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004522 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004523
4524 try
4525 {
4526 if (count < 0)
4527 {
4528 return error(GL_INVALID_VALUE);
4529 }
4530
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004531 if (location == -1)
4532 {
4533 return;
4534 }
4535
4536 gl::Context *context = gl::getContext();
4537
4538 if (context)
4539 {
4540 gl::Program *program = context->getCurrentProgram();
4541
4542 if (!program)
4543 {
4544 return error(GL_INVALID_OPERATION);
4545 }
4546
4547 if (!program->setUniform4iv(location, count, v))
4548 {
4549 return error(GL_INVALID_OPERATION);
4550 }
4551 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004552 }
4553 catch(std::bad_alloc&)
4554 {
4555 return error(GL_OUT_OF_MEMORY);
4556 }
4557}
4558
4559void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4560{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004561 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4562 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004563
4564 try
4565 {
4566 if (count < 0 || transpose != GL_FALSE)
4567 {
4568 return error(GL_INVALID_VALUE);
4569 }
4570
4571 if (location == -1)
4572 {
4573 return;
4574 }
4575
4576 gl::Context *context = gl::getContext();
4577
4578 if (context)
4579 {
4580 gl::Program *program = context->getCurrentProgram();
4581
4582 if (!program)
4583 {
4584 return error(GL_INVALID_OPERATION);
4585 }
4586
4587 if (!program->setUniformMatrix2fv(location, count, value))
4588 {
4589 return error(GL_INVALID_OPERATION);
4590 }
4591 }
4592 }
4593 catch(std::bad_alloc&)
4594 {
4595 return error(GL_OUT_OF_MEMORY);
4596 }
4597}
4598
4599void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4600{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004601 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4602 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004603
4604 try
4605 {
4606 if (count < 0 || transpose != GL_FALSE)
4607 {
4608 return error(GL_INVALID_VALUE);
4609 }
4610
4611 if (location == -1)
4612 {
4613 return;
4614 }
4615
4616 gl::Context *context = gl::getContext();
4617
4618 if (context)
4619 {
4620 gl::Program *program = context->getCurrentProgram();
4621
4622 if (!program)
4623 {
4624 return error(GL_INVALID_OPERATION);
4625 }
4626
4627 if (!program->setUniformMatrix3fv(location, count, value))
4628 {
4629 return error(GL_INVALID_OPERATION);
4630 }
4631 }
4632 }
4633 catch(std::bad_alloc&)
4634 {
4635 return error(GL_OUT_OF_MEMORY);
4636 }
4637}
4638
4639void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4640{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004641 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4642 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004643
4644 try
4645 {
4646 if (count < 0 || transpose != GL_FALSE)
4647 {
4648 return error(GL_INVALID_VALUE);
4649 }
4650
4651 if (location == -1)
4652 {
4653 return;
4654 }
4655
4656 gl::Context *context = gl::getContext();
4657
4658 if (context)
4659 {
4660 gl::Program *program = context->getCurrentProgram();
4661
4662 if (!program)
4663 {
4664 return error(GL_INVALID_OPERATION);
4665 }
4666
4667 if (!program->setUniformMatrix4fv(location, count, value))
4668 {
4669 return error(GL_INVALID_OPERATION);
4670 }
4671 }
4672 }
4673 catch(std::bad_alloc&)
4674 {
4675 return error(GL_OUT_OF_MEMORY);
4676 }
4677}
4678
4679void __stdcall glUseProgram(GLuint program)
4680{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004681 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004682
4683 try
4684 {
4685 gl::Context *context = gl::getContext();
4686
4687 if (context)
4688 {
4689 gl::Program *programObject = context->getProgram(program);
4690
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004691 if (!programObject && program != 0)
4692 {
4693 if (context->getShader(program))
4694 {
4695 return error(GL_INVALID_OPERATION);
4696 }
4697 else
4698 {
4699 return error(GL_INVALID_VALUE);
4700 }
4701 }
4702
4703 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004704 {
4705 return error(GL_INVALID_OPERATION);
4706 }
4707
4708 context->useProgram(program);
4709 }
4710 }
4711 catch(std::bad_alloc&)
4712 {
4713 return error(GL_OUT_OF_MEMORY);
4714 }
4715}
4716
4717void __stdcall glValidateProgram(GLuint program)
4718{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004719 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004720
4721 try
4722 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00004723 gl::Context *context = gl::getContext();
4724
4725 if (context)
4726 {
4727 gl::Program *programObject = context->getProgram(program);
4728
4729 if (!programObject)
4730 {
4731 if (context->getShader(program))
4732 {
4733 return error(GL_INVALID_OPERATION);
4734 }
4735 else
4736 {
4737 return error(GL_INVALID_VALUE);
4738 }
4739 }
4740
4741 programObject->validate();
4742 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004743 }
4744 catch(std::bad_alloc&)
4745 {
4746 return error(GL_OUT_OF_MEMORY);
4747 }
4748}
4749
4750void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4751{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004752 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004753
4754 try
4755 {
4756 if (index >= gl::MAX_VERTEX_ATTRIBS)
4757 {
4758 return error(GL_INVALID_VALUE);
4759 }
4760
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004761 gl::Context *context = gl::getContext();
4762
4763 if (context)
4764 {
4765 GLfloat vals[4] = { x, 0, 0, 1 };
4766 context->setVertexAttrib(index, vals);
4767 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004768 }
4769 catch(std::bad_alloc&)
4770 {
4771 return error(GL_OUT_OF_MEMORY);
4772 }
4773}
4774
4775void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4776{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004777 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004778
4779 try
4780 {
4781 if (index >= gl::MAX_VERTEX_ATTRIBS)
4782 {
4783 return error(GL_INVALID_VALUE);
4784 }
4785
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004786 gl::Context *context = gl::getContext();
4787
4788 if (context)
4789 {
4790 GLfloat vals[4] = { values[0], 0, 0, 1 };
4791 context->setVertexAttrib(index, vals);
4792 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004793 }
4794 catch(std::bad_alloc&)
4795 {
4796 return error(GL_OUT_OF_MEMORY);
4797 }
4798}
4799
4800void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4801{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004802 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004803
4804 try
4805 {
4806 if (index >= gl::MAX_VERTEX_ATTRIBS)
4807 {
4808 return error(GL_INVALID_VALUE);
4809 }
4810
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004811 gl::Context *context = gl::getContext();
4812
4813 if (context)
4814 {
4815 GLfloat vals[4] = { x, y, 0, 1 };
4816 context->setVertexAttrib(index, vals);
4817 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004818 }
4819 catch(std::bad_alloc&)
4820 {
4821 return error(GL_OUT_OF_MEMORY);
4822 }
4823}
4824
4825void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4826{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004827 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004828
4829 try
4830 {
4831 if (index >= gl::MAX_VERTEX_ATTRIBS)
4832 {
4833 return error(GL_INVALID_VALUE);
4834 }
4835
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004836 gl::Context *context = gl::getContext();
4837
4838 if (context)
4839 {
4840 GLfloat vals[4] = { values[0], values[1], 0, 1 };
4841 context->setVertexAttrib(index, vals);
4842 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004843 }
4844 catch(std::bad_alloc&)
4845 {
4846 return error(GL_OUT_OF_MEMORY);
4847 }
4848}
4849
4850void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4851{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004852 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004853
4854 try
4855 {
4856 if (index >= gl::MAX_VERTEX_ATTRIBS)
4857 {
4858 return error(GL_INVALID_VALUE);
4859 }
4860
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004861 gl::Context *context = gl::getContext();
4862
4863 if (context)
4864 {
4865 GLfloat vals[4] = { x, y, z, 1 };
4866 context->setVertexAttrib(index, vals);
4867 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004868 }
4869 catch(std::bad_alloc&)
4870 {
4871 return error(GL_OUT_OF_MEMORY);
4872 }
4873}
4874
4875void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4876{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004877 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004878
4879 try
4880 {
4881 if (index >= gl::MAX_VERTEX_ATTRIBS)
4882 {
4883 return error(GL_INVALID_VALUE);
4884 }
4885
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004886 gl::Context *context = gl::getContext();
4887
4888 if (context)
4889 {
4890 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
4891 context->setVertexAttrib(index, vals);
4892 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004893 }
4894 catch(std::bad_alloc&)
4895 {
4896 return error(GL_OUT_OF_MEMORY);
4897 }
4898}
4899
4900void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4901{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004902 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004903
4904 try
4905 {
4906 if (index >= gl::MAX_VERTEX_ATTRIBS)
4907 {
4908 return error(GL_INVALID_VALUE);
4909 }
4910
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004911 gl::Context *context = gl::getContext();
4912
4913 if (context)
4914 {
4915 GLfloat vals[4] = { x, y, z, w };
4916 context->setVertexAttrib(index, vals);
4917 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004918 }
4919 catch(std::bad_alloc&)
4920 {
4921 return error(GL_OUT_OF_MEMORY);
4922 }
4923}
4924
4925void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4926{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004927 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004928
4929 try
4930 {
4931 if (index >= gl::MAX_VERTEX_ATTRIBS)
4932 {
4933 return error(GL_INVALID_VALUE);
4934 }
4935
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004936 gl::Context *context = gl::getContext();
4937
4938 if (context)
4939 {
4940 context->setVertexAttrib(index, values);
4941 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004942 }
4943 catch(std::bad_alloc&)
4944 {
4945 return error(GL_OUT_OF_MEMORY);
4946 }
4947}
4948
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004949void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004950{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004951 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004952 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004953 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004954
4955 try
4956 {
4957 if (index >= gl::MAX_VERTEX_ATTRIBS)
4958 {
4959 return error(GL_INVALID_VALUE);
4960 }
4961
4962 if (size < 1 || size > 4)
4963 {
4964 return error(GL_INVALID_VALUE);
4965 }
4966
4967 switch (type)
4968 {
4969 case GL_BYTE:
4970 case GL_UNSIGNED_BYTE:
4971 case GL_SHORT:
4972 case GL_UNSIGNED_SHORT:
4973 case GL_FIXED:
4974 case GL_FLOAT:
4975 break;
4976 default:
4977 return error(GL_INVALID_ENUM);
4978 }
4979
4980 if (stride < 0)
4981 {
4982 return error(GL_INVALID_VALUE);
4983 }
4984
4985 gl::Context *context = gl::getContext();
4986
4987 if (context)
4988 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004989 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4990 context->vertexAttribute[index].mSize = size;
4991 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004992 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004993 context->vertexAttribute[index].mStride = stride;
4994 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004995 }
4996 }
4997 catch(std::bad_alloc&)
4998 {
4999 return error(GL_OUT_OF_MEMORY);
5000 }
5001}
5002
5003void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5004{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005005 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005006
5007 try
5008 {
5009 if (width < 0 || height < 0)
5010 {
5011 return error(GL_INVALID_VALUE);
5012 }
5013
5014 gl::Context *context = gl::getContext();
5015
5016 if (context)
5017 {
5018 context->viewportX = x;
5019 context->viewportY = y;
5020 context->viewportWidth = width;
5021 context->viewportHeight = height;
5022 }
5023 }
5024 catch(std::bad_alloc&)
5025 {
5026 return error(GL_OUT_OF_MEMORY);
5027 }
5028}
5029
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005030void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5031 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005032{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005033 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5034 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005035 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005036 target, level, internalformat, width, height, depth, border, format, type, pixels);
5037
5038 try
5039 {
5040 UNIMPLEMENTED(); // FIXME
5041 }
5042 catch(std::bad_alloc&)
5043 {
5044 return error(GL_OUT_OF_MEMORY);
5045 }
5046}
5047}