blob: 5bf0d14bb26fc64d5a113bfb8dce4c6efdf5d592 [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 }
1349
1350 if (shaderObject->isDeletable())
1351 {
1352 context->deleteShader(shader);
1353 }
1354 }
1355 }
1356 catch(std::bad_alloc&)
1357 {
1358 return error(GL_OUT_OF_MEMORY);
1359 }
1360}
1361
1362void __stdcall glDisable(GLenum cap)
1363{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001364 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001365
1366 try
1367 {
1368 gl::Context *context = gl::getContext();
1369
1370 if (context)
1371 {
1372 switch (cap)
1373 {
1374 case GL_CULL_FACE: context->cullFace = false; break;
1375 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1376 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1377 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1378 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1379 case GL_STENCIL_TEST: context->stencilTest = false; break;
1380 case GL_DEPTH_TEST: context->depthTest = false; break;
1381 case GL_BLEND: context->blend = false; break;
1382 case GL_DITHER: context->dither = false; break;
1383 default:
1384 return error(GL_INVALID_ENUM);
1385 }
1386 }
1387 }
1388 catch(std::bad_alloc&)
1389 {
1390 return error(GL_OUT_OF_MEMORY);
1391 }
1392}
1393
1394void __stdcall glDisableVertexAttribArray(GLuint index)
1395{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001396 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001397
1398 try
1399 {
1400 if (index >= gl::MAX_VERTEX_ATTRIBS)
1401 {
1402 return error(GL_INVALID_VALUE);
1403 }
1404
1405 gl::Context *context = gl::getContext();
1406
1407 if (context)
1408 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001409 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001410 }
1411 }
1412 catch(std::bad_alloc&)
1413 {
1414 return error(GL_OUT_OF_MEMORY);
1415 }
1416}
1417
1418void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1419{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001420 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001421
1422 try
1423 {
1424 if (count < 0 || first < 0)
1425 {
1426 return error(GL_INVALID_VALUE);
1427 }
1428
1429 gl::Context *context = gl::getContext();
1430
1431 if (context)
1432 {
1433 context->drawArrays(mode, first, count);
1434 }
1435 }
1436 catch(std::bad_alloc&)
1437 {
1438 return error(GL_OUT_OF_MEMORY);
1439 }
1440}
1441
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001442void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001443{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001444 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 +00001445 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001446
1447 try
1448 {
1449 if (count < 0)
1450 {
1451 return error(GL_INVALID_VALUE);
1452 }
1453
1454 switch (type)
1455 {
1456 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001457 case GL_UNSIGNED_SHORT:
1458 break;
1459 default:
1460 return error(GL_INVALID_ENUM);
1461 }
1462
1463 gl::Context *context = gl::getContext();
1464
1465 if (context)
1466 {
1467 context->drawElements(mode, count, type, indices);
1468 }
1469 }
1470 catch(std::bad_alloc&)
1471 {
1472 return error(GL_OUT_OF_MEMORY);
1473 }
1474}
1475
1476void __stdcall glEnable(GLenum cap)
1477{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001478 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001479
1480 try
1481 {
1482 gl::Context *context = gl::getContext();
1483
1484 if (context)
1485 {
1486 switch (cap)
1487 {
1488 case GL_CULL_FACE: context->cullFace = true; break;
1489 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1490 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1491 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1492 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1493 case GL_STENCIL_TEST: context->stencilTest = true; break;
1494 case GL_DEPTH_TEST: context->depthTest = true; break;
1495 case GL_BLEND: context->blend = true; break;
1496 case GL_DITHER: context->dither = true; break;
1497 default:
1498 return error(GL_INVALID_ENUM);
1499 }
1500 }
1501 }
1502 catch(std::bad_alloc&)
1503 {
1504 return error(GL_OUT_OF_MEMORY);
1505 }
1506}
1507
1508void __stdcall glEnableVertexAttribArray(GLuint index)
1509{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001510 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001511
1512 try
1513 {
1514 if (index >= gl::MAX_VERTEX_ATTRIBS)
1515 {
1516 return error(GL_INVALID_VALUE);
1517 }
1518
1519 gl::Context *context = gl::getContext();
1520
1521 if (context)
1522 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001523 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001524 }
1525 }
1526 catch(std::bad_alloc&)
1527 {
1528 return error(GL_OUT_OF_MEMORY);
1529 }
1530}
1531
1532void __stdcall glFinish(void)
1533{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001534 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001535
1536 try
1537 {
1538 gl::Context *context = gl::getContext();
1539
1540 if (context)
1541 {
1542 context->finish();
1543 }
1544 }
1545 catch(std::bad_alloc&)
1546 {
1547 return error(GL_OUT_OF_MEMORY);
1548 }
1549}
1550
1551void __stdcall glFlush(void)
1552{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001553 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001554
1555 try
1556 {
1557 gl::Context *context = gl::getContext();
1558
1559 if (context)
1560 {
1561 context->flush();
1562 }
1563 }
1564 catch(std::bad_alloc&)
1565 {
1566 return error(GL_OUT_OF_MEMORY);
1567 }
1568}
1569
1570void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1571{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001572 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1573 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001574
1575 try
1576 {
1577 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1578 {
1579 return error(GL_INVALID_ENUM);
1580 }
1581
1582 gl::Context *context = gl::getContext();
1583
1584 if (context)
1585 {
1586 gl::Framebuffer *framebuffer = context->getFramebuffer();
1587
1588 if (context->framebuffer == 0 || !framebuffer)
1589 {
1590 return error(GL_INVALID_OPERATION);
1591 }
1592
1593 switch (attachment)
1594 {
1595 case GL_COLOR_ATTACHMENT0:
1596 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1597 break;
1598 case GL_DEPTH_ATTACHMENT:
1599 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1600 break;
1601 case GL_STENCIL_ATTACHMENT:
1602 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1603 break;
1604 default:
1605 return error(GL_INVALID_ENUM);
1606 }
1607 }
1608 }
1609 catch(std::bad_alloc&)
1610 {
1611 return error(GL_OUT_OF_MEMORY);
1612 }
1613}
1614
1615void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1616{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001617 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1618 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001619
1620 try
1621 {
1622 if (target != GL_FRAMEBUFFER)
1623 {
1624 return error(GL_INVALID_ENUM);
1625 }
1626
1627 switch (attachment)
1628 {
1629 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001630 case GL_DEPTH_ATTACHMENT:
1631 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001632 break;
1633 default:
1634 return error(GL_INVALID_ENUM);
1635 }
1636
1637 gl::Context *context = gl::getContext();
1638
1639 if (context)
1640 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001641 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001642 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001643 textarget = GL_NONE;
1644 }
1645 else
1646 {
1647 gl::Texture *tex = context->getTexture(texture);
1648
1649 if (tex == NULL)
1650 {
1651 return error(GL_INVALID_OPERATION);
1652 }
1653
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001654 switch (textarget)
1655 {
1656 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001657 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001658 {
1659 return error(GL_INVALID_OPERATION);
1660 }
1661 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001662
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001663 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001664 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001665 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001666 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001667 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001668 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001669 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1670 {
1671 return error(GL_INVALID_OPERATION);
1672 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001673 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001674
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001675 default:
1676 return error(GL_INVALID_ENUM);
1677 }
1678
1679 if (level != 0)
1680 {
1681 return error(GL_INVALID_VALUE);
1682 }
1683 }
1684
1685 gl::Framebuffer *framebuffer = context->getFramebuffer();
1686
1687 if (context->framebuffer == 0 || !framebuffer)
1688 {
1689 return error(GL_INVALID_OPERATION);
1690 }
1691
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001692 switch (attachment)
1693 {
1694 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
1695 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
1696 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
1697 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001698 }
1699 }
1700 catch(std::bad_alloc&)
1701 {
1702 return error(GL_OUT_OF_MEMORY);
1703 }
1704}
1705
1706void __stdcall glFrontFace(GLenum mode)
1707{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001708 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001709
1710 try
1711 {
1712 switch (mode)
1713 {
1714 case GL_CW:
1715 case GL_CCW:
1716 {
1717 gl::Context *context = gl::getContext();
1718
1719 if (context)
1720 {
1721 context->frontFace = mode;
1722 }
1723 }
1724 break;
1725 default:
1726 return error(GL_INVALID_ENUM);
1727 }
1728 }
1729 catch(std::bad_alloc&)
1730 {
1731 return error(GL_OUT_OF_MEMORY);
1732 }
1733}
1734
1735void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1736{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001737 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001738
1739 try
1740 {
1741 if (n < 0)
1742 {
1743 return error(GL_INVALID_VALUE);
1744 }
1745
1746 gl::Context *context = gl::getContext();
1747
1748 if (context)
1749 {
1750 for (int i = 0; i < n; i++)
1751 {
1752 buffers[i] = context->createBuffer();
1753 }
1754 }
1755 }
1756 catch(std::bad_alloc&)
1757 {
1758 return error(GL_OUT_OF_MEMORY);
1759 }
1760}
1761
1762void __stdcall glGenerateMipmap(GLenum target)
1763{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001764 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001765
1766 try
1767 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00001768 gl::Context *context = gl::getContext();
1769
1770 if (context)
1771 {
1772 gl::Texture *texture;
1773
1774 switch (target)
1775 {
1776 case GL_TEXTURE_2D:
1777 texture = context->getTexture2D();
1778 break;
1779
1780 case GL_TEXTURE_CUBE_MAP:
1781 texture = context->getTextureCubeMap();
1782 break;
1783
1784 default:
1785 return error(GL_INVALID_ENUM);
1786 }
1787
1788 texture->generateMipmaps();
1789 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001790 }
1791 catch(std::bad_alloc&)
1792 {
1793 return error(GL_OUT_OF_MEMORY);
1794 }
1795}
1796
1797void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1798{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001799 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001800
1801 try
1802 {
1803 if (n < 0)
1804 {
1805 return error(GL_INVALID_VALUE);
1806 }
1807
1808 gl::Context *context = gl::getContext();
1809
1810 if (context)
1811 {
1812 for (int i = 0; i < n; i++)
1813 {
1814 framebuffers[i] = context->createFramebuffer();
1815 }
1816 }
1817 }
1818 catch(std::bad_alloc&)
1819 {
1820 return error(GL_OUT_OF_MEMORY);
1821 }
1822}
1823
1824void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1825{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001826 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001827
1828 try
1829 {
1830 if (n < 0)
1831 {
1832 return error(GL_INVALID_VALUE);
1833 }
1834
1835 gl::Context *context = gl::getContext();
1836
1837 if (context)
1838 {
1839 for (int i = 0; i < n; i++)
1840 {
1841 renderbuffers[i] = context->createRenderbuffer();
1842 }
1843 }
1844 }
1845 catch(std::bad_alloc&)
1846 {
1847 return error(GL_OUT_OF_MEMORY);
1848 }
1849}
1850
1851void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1852{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001853 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001854
1855 try
1856 {
1857 if (n < 0)
1858 {
1859 return error(GL_INVALID_VALUE);
1860 }
1861
1862 gl::Context *context = gl::getContext();
1863
1864 if (context)
1865 {
1866 for (int i = 0; i < n; i++)
1867 {
1868 textures[i] = context->createTexture();
1869 }
1870 }
1871 }
1872 catch(std::bad_alloc&)
1873 {
1874 return error(GL_OUT_OF_MEMORY);
1875 }
1876}
1877
daniel@transgaming.com85423182010-04-22 13:35:27 +00001878void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001879{
daniel@transgaming.com85423182010-04-22 13:35:27 +00001880 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
1881 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001882 program, index, bufsize, length, size, type, name);
1883
1884 try
1885 {
1886 if (bufsize < 0)
1887 {
1888 return error(GL_INVALID_VALUE);
1889 }
1890
daniel@transgaming.com85423182010-04-22 13:35:27 +00001891 gl::Context *context = gl::getContext();
1892
1893 if (context)
1894 {
1895 gl::Program *programObject = context->getProgram(program);
1896
1897 if (!programObject)
1898 {
1899 if (context->getShader(program))
1900 {
1901 return error(GL_INVALID_OPERATION);
1902 }
1903 else
1904 {
1905 return error(GL_INVALID_VALUE);
1906 }
1907 }
1908
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001909 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00001910 {
1911 return error(GL_INVALID_VALUE);
1912 }
1913
1914 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
1915 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001916 }
1917 catch(std::bad_alloc&)
1918 {
1919 return error(GL_OUT_OF_MEMORY);
1920 }
1921}
1922
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001923void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001924{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001925 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001926 "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 +00001927 program, index, bufsize, length, size, type, name);
1928
1929 try
1930 {
1931 if (bufsize < 0)
1932 {
1933 return error(GL_INVALID_VALUE);
1934 }
1935
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001936 gl::Context *context = gl::getContext();
1937
1938 if (context)
1939 {
1940 gl::Program *programObject = context->getProgram(program);
1941
1942 if (!programObject)
1943 {
1944 if (context->getShader(program))
1945 {
1946 return error(GL_INVALID_OPERATION);
1947 }
1948 else
1949 {
1950 return error(GL_INVALID_VALUE);
1951 }
1952 }
1953
1954 if (index >= (GLuint)programObject->getActiveUniformCount())
1955 {
1956 return error(GL_INVALID_VALUE);
1957 }
1958
1959 programObject->getActiveUniform(index, bufsize, length, size, type, name);
1960 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001961 }
1962 catch(std::bad_alloc&)
1963 {
1964 return error(GL_OUT_OF_MEMORY);
1965 }
1966}
1967
1968void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1969{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001970 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1971 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001972
1973 try
1974 {
1975 if (maxcount < 0)
1976 {
1977 return error(GL_INVALID_VALUE);
1978 }
1979
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001980 gl::Context *context = gl::getContext();
1981
1982 if (context)
1983 {
1984 gl::Program *programObject = context->getProgram(program);
1985
1986 if (!programObject)
1987 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001988 if (context->getShader(program))
1989 {
1990 return error(GL_INVALID_OPERATION);
1991 }
1992 else
1993 {
1994 return error(GL_INVALID_VALUE);
1995 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001996 }
1997
1998 return programObject->getAttachedShaders(maxcount, count, shaders);
1999 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002000 }
2001 catch(std::bad_alloc&)
2002 {
2003 return error(GL_OUT_OF_MEMORY);
2004 }
2005}
2006
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002007int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002008{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002009 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002010
2011 try
2012 {
2013 gl::Context *context = gl::getContext();
2014
2015 if (context)
2016 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002017
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002018 gl::Program *programObject = context->getProgram(program);
2019
2020 if (!programObject)
2021 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002022 if (context->getShader(program))
2023 {
2024 return error(GL_INVALID_OPERATION, -1);
2025 }
2026 else
2027 {
2028 return error(GL_INVALID_VALUE, -1);
2029 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002030 }
2031
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002032 if (!programObject->isLinked())
2033 {
2034 return error(GL_INVALID_OPERATION, -1);
2035 }
2036
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002037 return programObject->getAttributeLocation(name);
2038 }
2039 }
2040 catch(std::bad_alloc&)
2041 {
2042 return error(GL_OUT_OF_MEMORY, -1);
2043 }
2044
2045 return -1;
2046}
2047
2048void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2049{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002050 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002051
2052 try
2053 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002054 gl::Context *context = gl::getContext();
2055
2056 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002057 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002058 if (!(context->getBooleanv(pname, params)))
2059 {
2060 GLenum nativeType;
2061 unsigned int numParams = 0;
2062 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2063 return error(GL_INVALID_ENUM);
2064
2065 if (numParams == 0)
2066 return; // it is known that the pname is valid, but there are no parameters to return
2067
2068 if (nativeType == GL_FLOAT)
2069 {
2070 GLfloat *floatParams = NULL;
2071 floatParams = new GLfloat[numParams];
2072
2073 context->getFloatv(pname, floatParams);
2074
2075 for (unsigned int i = 0; i < numParams; ++i)
2076 {
2077 if (floatParams[i] == 0.0f)
2078 params[i] = GL_FALSE;
2079 else
2080 params[i] = GL_TRUE;
2081 }
2082
2083 delete [] floatParams;
2084 }
2085 else if (nativeType == GL_INT)
2086 {
2087 GLint *intParams = NULL;
2088 intParams = new GLint[numParams];
2089
2090 context->getIntegerv(pname, intParams);
2091
2092 for (unsigned int i = 0; i < numParams; ++i)
2093 {
2094 if (intParams[i] == 0)
2095 params[i] = GL_FALSE;
2096 else
2097 params[i] = GL_TRUE;
2098 }
2099
2100 delete [] intParams;
2101 }
2102 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002103 }
2104 }
2105 catch(std::bad_alloc&)
2106 {
2107 return error(GL_OUT_OF_MEMORY);
2108 }
2109}
2110
2111void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2112{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002113 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 +00002114
2115 try
2116 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002117 gl::Context *context = gl::getContext();
2118
2119 if (context)
2120 {
2121 gl::Buffer *buffer;
2122
2123 switch (target)
2124 {
2125 case GL_ARRAY_BUFFER:
2126 buffer = context->getArrayBuffer();
2127 break;
2128 case GL_ELEMENT_ARRAY_BUFFER:
2129 buffer = context->getElementArrayBuffer();
2130 break;
2131 default: return error(GL_INVALID_ENUM);
2132 }
2133
2134 if (!buffer)
2135 {
2136 // A null buffer means that "0" is bound to the requested buffer target
2137 return error(GL_INVALID_OPERATION);
2138 }
2139
2140 switch (pname)
2141 {
2142 case GL_BUFFER_USAGE:
2143 *params = buffer->usage();
2144 break;
2145 case GL_BUFFER_SIZE:
2146 *params = buffer->size();
2147 break;
2148 default: return error(GL_INVALID_ENUM);
2149 }
2150 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002151 }
2152 catch(std::bad_alloc&)
2153 {
2154 return error(GL_OUT_OF_MEMORY);
2155 }
2156}
2157
2158GLenum __stdcall glGetError(void)
2159{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002160 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002161
2162 gl::Context *context = gl::getContext();
2163
2164 if (context)
2165 {
2166 return context->getError();
2167 }
2168
2169 return GL_NO_ERROR;
2170}
2171
2172void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2173{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002174 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002175
2176 try
2177 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002178 gl::Context *context = gl::getContext();
2179
2180 if (context)
2181 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002182 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002183 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002184 GLenum nativeType;
2185 unsigned int numParams = 0;
2186 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2187 return error(GL_INVALID_ENUM);
2188
2189 if (numParams == 0)
2190 return; // it is known that the pname is valid, but that there are no parameters to return.
2191
2192 if (nativeType == GL_BOOL)
2193 {
2194 GLboolean *boolParams = NULL;
2195 boolParams = new GLboolean[numParams];
2196
2197 context->getBooleanv(pname, boolParams);
2198
2199 for (unsigned int i = 0; i < numParams; ++i)
2200 {
2201 if (boolParams[i] == GL_FALSE)
2202 params[i] = 0.0f;
2203 else
2204 params[i] = 1.0f;
2205 }
2206
2207 delete [] boolParams;
2208 }
2209 else if (nativeType == GL_INT)
2210 {
2211 GLint *intParams = NULL;
2212 intParams = new GLint[numParams];
2213
2214 context->getIntegerv(pname, intParams);
2215
2216 for (unsigned int i = 0; i < numParams; ++i)
2217 {
2218 params[i] = (GLfloat)intParams[i];
2219 }
2220
2221 delete [] intParams;
2222 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002223 }
2224 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002225 }
2226 catch(std::bad_alloc&)
2227 {
2228 return error(GL_OUT_OF_MEMORY);
2229 }
2230}
2231
2232void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2233{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002234 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2235 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002236
2237 try
2238 {
2239 gl::Context *context = gl::getContext();
2240
2241 if (context)
2242 {
2243 if (context->framebuffer == 0)
2244 {
2245 return error(GL_INVALID_OPERATION);
2246 }
2247
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002248 if (target != GL_FRAMEBUFFER)
2249 {
2250 return error(GL_INVALID_ENUM);
2251 }
2252
2253 GLenum attachmentType;
2254 GLuint attachmentHandle;
2255 switch (attachment)
2256 {
2257 case GL_COLOR_ATTACHMENT0:
2258 attachmentType = context->getFramebuffer()->getColorbufferType();
2259 attachmentHandle = context->getFramebuffer()->getColorbufferHandle();
2260 break;
2261 case GL_DEPTH_ATTACHMENT:
2262 attachmentType = context->getFramebuffer()->getDepthbufferType();
2263 attachmentHandle = context->getFramebuffer()->getDepthbufferHandle();
2264 break;
2265 case GL_STENCIL_ATTACHMENT:
2266 attachmentType = context->getFramebuffer()->getStencilbufferType();
2267 attachmentHandle = context->getFramebuffer()->getStencilbufferHandle();
2268 break;
2269 default: return error(GL_INVALID_ENUM);
2270 }
2271
2272 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002273 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002274 {
2275 attachmentObjectType = attachmentType;
2276 }
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002277 else if (es2dx::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002278 {
2279 attachmentObjectType = GL_TEXTURE;
2280 }
2281 else UNREACHABLE();
2282
2283 switch (pname)
2284 {
2285 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2286 *params = attachmentObjectType;
2287 break;
2288 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2289 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2290 {
2291 *params = attachmentHandle;
2292 }
2293 else
2294 {
2295 return error(GL_INVALID_ENUM);
2296 }
2297 break;
2298 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2299 if (attachmentObjectType == GL_TEXTURE)
2300 {
2301 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2302 }
2303 else
2304 {
2305 return error(GL_INVALID_ENUM);
2306 }
2307 break;
2308 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2309 if (attachmentObjectType == GL_TEXTURE)
2310 {
2311 if (es2dx::IsCubemapTextureTarget(attachmentType))
2312 {
2313 *params = attachmentType;
2314 }
2315 else
2316 {
2317 *params = 0;
2318 }
2319 }
2320 else
2321 {
2322 return error(GL_INVALID_ENUM);
2323 }
2324 break;
2325 default:
2326 return error(GL_INVALID_ENUM);
2327 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002328 }
2329 }
2330 catch(std::bad_alloc&)
2331 {
2332 return error(GL_OUT_OF_MEMORY);
2333 }
2334}
2335
2336void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2337{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002338 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002339
2340 try
2341 {
2342 gl::Context *context = gl::getContext();
2343
2344 if (context)
2345 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002346 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002347 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002348 GLenum nativeType;
2349 unsigned int numParams = 0;
2350 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2351 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002352
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002353 if (numParams == 0)
2354 return; // it is known that pname is valid, but there are no parameters to return
2355
2356 if (nativeType == GL_BOOL)
2357 {
2358 GLboolean *boolParams = NULL;
2359 boolParams = new GLboolean[numParams];
2360
2361 context->getBooleanv(pname, boolParams);
2362
2363 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002364 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002365 if (boolParams[i] == GL_FALSE)
2366 params[i] = 0;
2367 else
2368 params[i] = 1;
2369 }
2370
2371 delete [] boolParams;
2372 }
2373 else if (nativeType == GL_FLOAT)
2374 {
2375 GLfloat *floatParams = NULL;
2376 floatParams = new GLfloat[numParams];
2377
2378 context->getFloatv(pname, floatParams);
2379
2380 for (unsigned int i = 0; i < numParams; ++i)
2381 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002382 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 +00002383 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002384 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002385 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002386 else
2387 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 +00002388 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002389
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002390 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002391 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002392 }
2393 }
2394 }
2395 catch(std::bad_alloc&)
2396 {
2397 return error(GL_OUT_OF_MEMORY);
2398 }
2399}
2400
2401void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2402{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002403 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002404
2405 try
2406 {
2407 gl::Context *context = gl::getContext();
2408
2409 if (context)
2410 {
2411 gl::Program *programObject = context->getProgram(program);
2412
2413 if (!programObject)
2414 {
2415 return error(GL_INVALID_VALUE);
2416 }
2417
2418 switch (pname)
2419 {
2420 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002421 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002422 return;
2423 case GL_LINK_STATUS:
2424 *params = programObject->isLinked();
2425 return;
2426 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002427 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002428 return;
2429 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002430 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002431 return;
2432 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002433 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002434 return;
2435 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002436 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002437 return;
2438 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002439 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002440 return;
2441 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002442 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002443 return;
2444 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002445 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002446 return;
2447 default:
2448 return error(GL_INVALID_ENUM);
2449 }
2450 }
2451 }
2452 catch(std::bad_alloc&)
2453 {
2454 return error(GL_OUT_OF_MEMORY);
2455 }
2456}
2457
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002458void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002459{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002460 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 +00002461 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002462
2463 try
2464 {
2465 if (bufsize < 0)
2466 {
2467 return error(GL_INVALID_VALUE);
2468 }
2469
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002470 gl::Context *context = gl::getContext();
2471
2472 if (context)
2473 {
2474 gl::Program *programObject = context->getProgram(program);
2475
2476 if (!programObject)
2477 {
2478 return error(GL_INVALID_VALUE);
2479 }
2480
2481 programObject->getInfoLog(bufsize, length, infolog);
2482 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002483 }
2484 catch(std::bad_alloc&)
2485 {
2486 return error(GL_OUT_OF_MEMORY);
2487 }
2488}
2489
2490void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2491{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002492 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 +00002493
2494 try
2495 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002496 gl::Context *context = gl::getContext();
2497
2498 if (context)
2499 {
2500 if (target != GL_RENDERBUFFER)
2501 {
2502 return error(GL_INVALID_ENUM);
2503 }
2504
2505 if (context->renderbuffer == 0)
2506 {
2507 return error(GL_INVALID_OPERATION);
2508 }
2509
2510 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->renderbuffer);
2511
2512 switch (pname)
2513 {
2514 case GL_RENDERBUFFER_WIDTH:
2515 *params = renderbuffer->getWidth();
2516 break;
2517 case GL_RENDERBUFFER_HEIGHT:
2518 *params = renderbuffer->getHeight();
2519 break;
2520 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2521 *params = renderbuffer->getFormat();
2522 break;
2523 case GL_RENDERBUFFER_RED_SIZE:
2524 if (renderbuffer->isColorbuffer())
2525 {
2526 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
2527 }
2528 else
2529 {
2530 *params = 0;
2531 }
2532 break;
2533 case GL_RENDERBUFFER_GREEN_SIZE:
2534 if (renderbuffer->isColorbuffer())
2535 {
2536 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
2537 }
2538 else
2539 {
2540 *params = 0;
2541 }
2542 break;
2543 case GL_RENDERBUFFER_BLUE_SIZE:
2544 if (renderbuffer->isColorbuffer())
2545 {
2546 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
2547 }
2548 else
2549 {
2550 *params = 0;
2551 }
2552 break;
2553 case GL_RENDERBUFFER_ALPHA_SIZE:
2554 if (renderbuffer->isColorbuffer())
2555 {
2556 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
2557 }
2558 else
2559 {
2560 *params = 0;
2561 }
2562 break;
2563 case GL_RENDERBUFFER_DEPTH_SIZE:
2564 if (renderbuffer->isDepthbuffer())
2565 {
2566 *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
2567 }
2568 else
2569 {
2570 *params = 0;
2571 }
2572 break;
2573 case GL_RENDERBUFFER_STENCIL_SIZE:
2574 if (renderbuffer->isStencilbuffer())
2575 {
2576 *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
2577 }
2578 else
2579 {
2580 *params = 0;
2581 }
2582 break;
2583 default:
2584 return error(GL_INVALID_ENUM);
2585 }
2586 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002587 }
2588 catch(std::bad_alloc&)
2589 {
2590 return error(GL_OUT_OF_MEMORY);
2591 }
2592}
2593
2594void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2595{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002596 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002597
2598 try
2599 {
2600 gl::Context *context = gl::getContext();
2601
2602 if (context)
2603 {
2604 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002605
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002606 if (!shaderObject)
2607 {
2608 return error(GL_INVALID_VALUE);
2609 }
2610
2611 switch (pname)
2612 {
2613 case GL_SHADER_TYPE:
2614 *params = shaderObject->getType();
2615 return;
2616 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002617 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002618 return;
2619 case GL_COMPILE_STATUS:
2620 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2621 return;
2622 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002623 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002624 return;
2625 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002626 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002627 return;
2628 default:
2629 return error(GL_INVALID_ENUM);
2630 }
2631 }
2632 }
2633 catch(std::bad_alloc&)
2634 {
2635 return error(GL_OUT_OF_MEMORY);
2636 }
2637}
2638
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002639void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002640{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002641 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 +00002642 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002643
2644 try
2645 {
2646 if (bufsize < 0)
2647 {
2648 return error(GL_INVALID_VALUE);
2649 }
2650
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002651 gl::Context *context = gl::getContext();
2652
2653 if (context)
2654 {
2655 gl::Shader *shaderObject = context->getShader(shader);
2656
2657 if (!shaderObject)
2658 {
2659 return error(GL_INVALID_VALUE);
2660 }
2661
2662 shaderObject->getInfoLog(bufsize, length, infolog);
2663 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002664 }
2665 catch(std::bad_alloc&)
2666 {
2667 return error(GL_OUT_OF_MEMORY);
2668 }
2669}
2670
2671void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2672{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002673 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2674 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002675
2676 try
2677 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002678 switch (shadertype)
2679 {
2680 case GL_VERTEX_SHADER:
2681 case GL_FRAGMENT_SHADER:
2682 break;
2683 default:
2684 return error(GL_INVALID_ENUM);
2685 }
2686
2687 switch (precisiontype)
2688 {
2689 case GL_LOW_FLOAT:
2690 case GL_MEDIUM_FLOAT:
2691 case GL_HIGH_FLOAT:
2692 // Assume IEEE 754 precision
2693 range[0] = 127;
2694 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002695 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002696 break;
2697 case GL_LOW_INT:
2698 case GL_MEDIUM_INT:
2699 case GL_HIGH_INT:
2700 // Some (most) hardware only supports single-precision floating-point numbers,
2701 // which can accurately represent integers up to +/-16777216
2702 range[0] = 24;
2703 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002704 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002705 break;
2706 default:
2707 return error(GL_INVALID_ENUM);
2708 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002709 }
2710 catch(std::bad_alloc&)
2711 {
2712 return error(GL_OUT_OF_MEMORY);
2713 }
2714}
2715
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002716void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002717{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002718 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 +00002719 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002720
2721 try
2722 {
2723 if (bufsize < 0)
2724 {
2725 return error(GL_INVALID_VALUE);
2726 }
2727
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002728 gl::Context *context = gl::getContext();
2729
2730 if (context)
2731 {
2732 gl::Shader *shaderObject = context->getShader(shader);
2733
2734 if (!shaderObject)
2735 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002736 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002737 }
2738
2739 shaderObject->getSource(bufsize, length, source);
2740 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002741 }
2742 catch(std::bad_alloc&)
2743 {
2744 return error(GL_OUT_OF_MEMORY);
2745 }
2746}
2747
2748const GLubyte* __stdcall glGetString(GLenum name)
2749{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002750 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002751
2752 try
2753 {
2754 switch (name)
2755 {
2756 case GL_VENDOR:
2757 return (GLubyte*)"TransGaming Inc.";
2758 case GL_RENDERER:
2759 return (GLubyte*)"ANGLE";
2760 case GL_VERSION:
2761 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2762 case GL_SHADING_LANGUAGE_VERSION:
2763 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2764 case GL_EXTENSIONS:
2765 return (GLubyte*)"";
2766 default:
2767 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2768 }
2769 }
2770 catch(std::bad_alloc&)
2771 {
2772 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2773 }
2774
2775 return NULL;
2776}
2777
2778void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2779{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002780 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 +00002781
2782 try
2783 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002784 gl::Context *context = gl::getContext();
2785
2786 if (context)
2787 {
2788 gl::Texture *texture;
2789
2790 switch (target)
2791 {
2792 case GL_TEXTURE_2D:
2793 texture = context->getTexture2D();
2794 break;
2795 case GL_TEXTURE_CUBE_MAP:
2796 texture = context->getTextureCubeMap();
2797 break;
2798 default:
2799 return error(GL_INVALID_ENUM);
2800 }
2801
2802 switch (pname)
2803 {
2804 case GL_TEXTURE_MAG_FILTER:
2805 *params = (GLfloat)texture->getMagFilter();
2806 break;
2807 case GL_TEXTURE_MIN_FILTER:
2808 *params = (GLfloat)texture->getMinFilter();
2809 break;
2810 case GL_TEXTURE_WRAP_S:
2811 *params = (GLfloat)texture->getWrapS();
2812 break;
2813 case GL_TEXTURE_WRAP_T:
2814 *params = (GLfloat)texture->getWrapT();
2815 break;
2816 default:
2817 return error(GL_INVALID_ENUM);
2818 }
2819 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002820 }
2821 catch(std::bad_alloc&)
2822 {
2823 return error(GL_OUT_OF_MEMORY);
2824 }
2825}
2826
2827void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2828{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002829 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 +00002830
2831 try
2832 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002833 gl::Context *context = gl::getContext();
2834
2835 if (context)
2836 {
2837 gl::Texture *texture;
2838
2839 switch (target)
2840 {
2841 case GL_TEXTURE_2D:
2842 texture = context->getTexture2D();
2843 break;
2844 case GL_TEXTURE_CUBE_MAP:
2845 texture = context->getTextureCubeMap();
2846 break;
2847 default:
2848 return error(GL_INVALID_ENUM);
2849 }
2850
2851 switch (pname)
2852 {
2853 case GL_TEXTURE_MAG_FILTER:
2854 *params = texture->getMagFilter();
2855 break;
2856 case GL_TEXTURE_MIN_FILTER:
2857 *params = texture->getMinFilter();
2858 break;
2859 case GL_TEXTURE_WRAP_S:
2860 *params = texture->getWrapS();
2861 break;
2862 case GL_TEXTURE_WRAP_T:
2863 *params = texture->getWrapT();
2864 break;
2865 default:
2866 return error(GL_INVALID_ENUM);
2867 }
2868 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002869 }
2870 catch(std::bad_alloc&)
2871 {
2872 return error(GL_OUT_OF_MEMORY);
2873 }
2874}
2875
2876void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2877{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002878 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002879
2880 try
2881 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002882 gl::Context *context = gl::getContext();
2883
2884 if (context)
2885 {
2886 if (program == 0)
2887 {
2888 return error(GL_INVALID_VALUE);
2889 }
2890
2891 gl::Program *programObject = context->getProgram(program);
2892
2893 if (!programObject || !programObject->isLinked())
2894 {
2895 return error(GL_INVALID_OPERATION);
2896 }
2897
2898 if (!programObject->getUniformfv(location, params))
2899 {
2900 return error(GL_INVALID_OPERATION);
2901 }
2902 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002903 }
2904 catch(std::bad_alloc&)
2905 {
2906 return error(GL_OUT_OF_MEMORY);
2907 }
2908}
2909
2910void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2911{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002912 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002913
2914 try
2915 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002916 gl::Context *context = gl::getContext();
2917
2918 if (context)
2919 {
2920 if (program == 0)
2921 {
2922 return error(GL_INVALID_VALUE);
2923 }
2924
2925 gl::Program *programObject = context->getProgram(program);
2926
2927 if (!programObject || !programObject->isLinked())
2928 {
2929 return error(GL_INVALID_OPERATION);
2930 }
2931
2932 if (!programObject)
2933 {
2934 return error(GL_INVALID_OPERATION);
2935 }
2936
2937 if (!programObject->getUniformiv(location, params))
2938 {
2939 return error(GL_INVALID_OPERATION);
2940 }
2941 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002942 }
2943 catch(std::bad_alloc&)
2944 {
2945 return error(GL_OUT_OF_MEMORY);
2946 }
2947}
2948
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002949int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002950{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002951 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002952
2953 try
2954 {
2955 gl::Context *context = gl::getContext();
2956
2957 if (strstr(name, "gl_") == name)
2958 {
2959 return -1;
2960 }
2961
2962 if (context)
2963 {
2964 gl::Program *programObject = context->getProgram(program);
2965
2966 if (!programObject)
2967 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002968 if (context->getShader(program))
2969 {
2970 return error(GL_INVALID_OPERATION, -1);
2971 }
2972 else
2973 {
2974 return error(GL_INVALID_VALUE, -1);
2975 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002976 }
2977
2978 if (!programObject->isLinked())
2979 {
2980 return error(GL_INVALID_OPERATION, -1);
2981 }
2982
2983 return programObject->getUniformLocation(name);
2984 }
2985 }
2986 catch(std::bad_alloc&)
2987 {
2988 return error(GL_OUT_OF_MEMORY, -1);
2989 }
2990
2991 return -1;
2992}
2993
2994void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2995{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002996 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002997
2998 try
2999 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003000 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003001
daniel@transgaming.come0078962010-04-15 20:45:08 +00003002 if (context)
3003 {
3004 if (index >= gl::MAX_VERTEX_ATTRIBS)
3005 {
3006 return error(GL_INVALID_VALUE);
3007 }
3008
3009 switch (pname)
3010 {
3011 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3012 *params = (GLfloat)(context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
3013 break;
3014 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3015 *params = (GLfloat)context->vertexAttribute[index].mSize;
3016 break;
3017 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3018 *params = (GLfloat)context->vertexAttribute[index].mStride;
3019 break;
3020 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3021 *params = (GLfloat)context->vertexAttribute[index].mType;
3022 break;
3023 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3024 *params = (GLfloat)(context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
3025 break;
3026 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
3027 *params = (GLfloat)context->vertexAttribute[index].mBoundBuffer;
3028 break;
3029 case GL_CURRENT_VERTEX_ATTRIB:
3030 for (int i = 0; i < 4; ++i)
3031 {
3032 params[i] = context->vertexAttribute[index].mCurrentValue[i];
3033 }
3034 break;
3035 default: return error(GL_INVALID_ENUM);
3036 }
3037 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003038 }
3039 catch(std::bad_alloc&)
3040 {
3041 return error(GL_OUT_OF_MEMORY);
3042 }
3043}
3044
3045void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3046{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003047 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003048
3049 try
3050 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003051 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003052
daniel@transgaming.come0078962010-04-15 20:45:08 +00003053 if (context)
3054 {
3055 if (index >= gl::MAX_VERTEX_ATTRIBS)
3056 {
3057 return error(GL_INVALID_VALUE);
3058 }
3059
3060 switch (pname)
3061 {
3062 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3063 *params = (context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
3064 break;
3065 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3066 *params = context->vertexAttribute[index].mSize;
3067 break;
3068 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3069 *params = context->vertexAttribute[index].mStride;
3070 break;
3071 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3072 *params = context->vertexAttribute[index].mType;
3073 break;
3074 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3075 *params = (context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
3076 break;
3077 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
3078 *params = context->vertexAttribute[index].mBoundBuffer;
3079 break;
3080 case GL_CURRENT_VERTEX_ATTRIB:
3081 for (int i = 0; i < 4; ++i)
3082 {
3083 float currentValue = context->vertexAttribute[index].mCurrentValue[i];
3084 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3085 }
3086 break;
3087 default: return error(GL_INVALID_ENUM);
3088 }
3089 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003090 }
3091 catch(std::bad_alloc&)
3092 {
3093 return error(GL_OUT_OF_MEMORY);
3094 }
3095}
3096
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003097void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003098{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003099 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003100
3101 try
3102 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003103 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003104
daniel@transgaming.come0078962010-04-15 20:45:08 +00003105 if (context)
3106 {
3107 if (index >= gl::MAX_VERTEX_ATTRIBS)
3108 {
3109 return error(GL_INVALID_VALUE);
3110 }
3111
3112 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3113 {
3114 return error(GL_INVALID_ENUM);
3115 }
3116
3117 *pointer = const_cast<GLvoid*>(context->vertexAttribute[index].mPointer);
3118 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003119 }
3120 catch(std::bad_alloc&)
3121 {
3122 return error(GL_OUT_OF_MEMORY);
3123 }
3124}
3125
3126void __stdcall glHint(GLenum target, GLenum mode)
3127{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003128 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003129
3130 try
3131 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003132 switch (target)
3133 {
3134 case GL_GENERATE_MIPMAP_HINT:
3135 switch (mode)
3136 {
3137 case GL_FASTEST:
3138 case GL_NICEST:
3139 case GL_DONT_CARE:
3140 break;
3141 default:
3142 return error(GL_INVALID_ENUM);
3143 }
3144 break;
3145 default:
3146 return error(GL_INVALID_ENUM);
3147 }
3148
3149 gl::Context *context = gl::getContext();
3150 if (context)
3151 {
3152 if (target == GL_GENERATE_MIPMAP_HINT)
3153 context->generateMipmapHint = mode;
3154 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003155 }
3156 catch(std::bad_alloc&)
3157 {
3158 return error(GL_OUT_OF_MEMORY);
3159 }
3160}
3161
3162GLboolean __stdcall glIsBuffer(GLuint buffer)
3163{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003164 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003165
3166 try
3167 {
3168 gl::Context *context = gl::getContext();
3169
3170 if (context && buffer)
3171 {
3172 gl::Buffer *bufferObject = context->getBuffer(buffer);
3173
3174 if (bufferObject)
3175 {
3176 return GL_TRUE;
3177 }
3178 }
3179 }
3180 catch(std::bad_alloc&)
3181 {
3182 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3183 }
3184
3185 return GL_FALSE;
3186}
3187
3188GLboolean __stdcall glIsEnabled(GLenum cap)
3189{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003190 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003191
3192 try
3193 {
3194 gl::Context *context = gl::getContext();
3195
3196 if (context)
3197 {
3198 switch (cap)
3199 {
3200 case GL_CULL_FACE: return context->cullFace;
3201 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
3202 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
3203 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
3204 case GL_SCISSOR_TEST: return context->scissorTest;
3205 case GL_STENCIL_TEST: return context->stencilTest;
3206 case GL_DEPTH_TEST: return context->depthTest;
3207 case GL_BLEND: return context->blend;
3208 case GL_DITHER: return context->dither;
3209 default:
3210 return error(GL_INVALID_ENUM, false);
3211 }
3212 }
3213 }
3214 catch(std::bad_alloc&)
3215 {
3216 return error(GL_OUT_OF_MEMORY, false);
3217 }
3218
3219 return false;
3220}
3221
3222GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3223{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003224 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003225
3226 try
3227 {
3228 gl::Context *context = gl::getContext();
3229
3230 if (context && framebuffer)
3231 {
3232 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3233
3234 if (framebufferObject)
3235 {
3236 return GL_TRUE;
3237 }
3238 }
3239 }
3240 catch(std::bad_alloc&)
3241 {
3242 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3243 }
3244
3245 return GL_FALSE;
3246}
3247
3248GLboolean __stdcall glIsProgram(GLuint program)
3249{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003250 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003251
3252 try
3253 {
3254 gl::Context *context = gl::getContext();
3255
3256 if (context && program)
3257 {
3258 gl::Program *programObject = context->getProgram(program);
3259
3260 if (programObject)
3261 {
3262 return GL_TRUE;
3263 }
3264 }
3265 }
3266 catch(std::bad_alloc&)
3267 {
3268 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3269 }
3270
3271 return GL_FALSE;
3272}
3273
3274GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3275{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003276 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003277
3278 try
3279 {
3280 gl::Context *context = gl::getContext();
3281
3282 if (context && renderbuffer)
3283 {
3284 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3285
3286 if (renderbufferObject)
3287 {
3288 return GL_TRUE;
3289 }
3290 }
3291 }
3292 catch(std::bad_alloc&)
3293 {
3294 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3295 }
3296
3297 return GL_FALSE;
3298}
3299
3300GLboolean __stdcall glIsShader(GLuint shader)
3301{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003302 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003303
3304 try
3305 {
3306 gl::Context *context = gl::getContext();
3307
3308 if (context && shader)
3309 {
3310 gl::Shader *shaderObject = context->getShader(shader);
3311
3312 if (shaderObject)
3313 {
3314 return GL_TRUE;
3315 }
3316 }
3317 }
3318 catch(std::bad_alloc&)
3319 {
3320 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3321 }
3322
3323 return GL_FALSE;
3324}
3325
3326GLboolean __stdcall glIsTexture(GLuint texture)
3327{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003328 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003329
3330 try
3331 {
3332 gl::Context *context = gl::getContext();
3333
3334 if (context && texture)
3335 {
3336 gl::Texture *textureObject = context->getTexture(texture);
3337
3338 if (textureObject)
3339 {
3340 return GL_TRUE;
3341 }
3342 }
3343 }
3344 catch(std::bad_alloc&)
3345 {
3346 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3347 }
3348
3349 return GL_FALSE;
3350}
3351
3352void __stdcall glLineWidth(GLfloat width)
3353{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003354 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003355
3356 try
3357 {
3358 if (width <= 0.0f)
3359 {
3360 return error(GL_INVALID_VALUE);
3361 }
3362
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003363 gl::Context *context = gl::getContext();
3364
3365 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003366 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003367 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003368 }
3369 }
3370 catch(std::bad_alloc&)
3371 {
3372 return error(GL_OUT_OF_MEMORY);
3373 }
3374}
3375
3376void __stdcall glLinkProgram(GLuint program)
3377{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003378 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003379
3380 try
3381 {
3382 gl::Context *context = gl::getContext();
3383
3384 if (context)
3385 {
3386 gl::Program *programObject = context->getProgram(program);
3387
3388 if (!programObject)
3389 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003390 if (context->getShader(program))
3391 {
3392 return error(GL_INVALID_OPERATION);
3393 }
3394 else
3395 {
3396 return error(GL_INVALID_VALUE);
3397 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003398 }
3399
3400 programObject->link();
3401 }
3402 }
3403 catch(std::bad_alloc&)
3404 {
3405 return error(GL_OUT_OF_MEMORY);
3406 }
3407}
3408
3409void __stdcall glPixelStorei(GLenum pname, GLint param)
3410{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003411 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003412
3413 try
3414 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003415 gl::Context *context = gl::getContext();
3416
3417 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003418 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003419 switch (pname)
3420 {
3421 case GL_UNPACK_ALIGNMENT:
3422 if (param != 1 && param != 2 && param != 4 && param != 8)
3423 {
3424 return error(GL_INVALID_VALUE);
3425 }
3426
3427 context->unpackAlignment = param;
3428 break;
3429
3430 case GL_PACK_ALIGNMENT:
3431 if (param != 1 && param != 2 && param != 4 && param != 8)
3432 {
3433 return error(GL_INVALID_VALUE);
3434 }
3435
3436 context->packAlignment = param;
3437 break;
3438
3439 default:
3440 return error(GL_INVALID_ENUM);
3441 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003442 }
3443 }
3444 catch(std::bad_alloc&)
3445 {
3446 return error(GL_OUT_OF_MEMORY);
3447 }
3448}
3449
3450void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3451{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003452 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003453
3454 try
3455 {
3456 if (factor != 0.0f || units != 0.0f)
3457 {
3458 UNIMPLEMENTED(); // FIXME
3459 }
3460 }
3461 catch(std::bad_alloc&)
3462 {
3463 return error(GL_OUT_OF_MEMORY);
3464 }
3465}
3466
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003467void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003468{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003469 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003470 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003471 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003472
3473 try
3474 {
3475 if (width < 0 || height < 0)
3476 {
3477 return error(GL_INVALID_VALUE);
3478 }
3479
3480 switch (format)
3481 {
3482 case GL_RGBA:
3483 switch (type)
3484 {
3485 case GL_UNSIGNED_BYTE:
3486 break;
3487 default:
3488 return error(GL_INVALID_OPERATION);
3489 }
3490 break;
3491 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3492 switch (type)
3493 {
3494 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3495 break;
3496 default:
3497 return error(GL_INVALID_OPERATION);
3498 }
3499 break;
3500 default:
3501 return error(GL_INVALID_OPERATION);
3502 }
3503
3504 gl::Context *context = gl::getContext();
3505
3506 if (context)
3507 {
3508 context->readPixels(x, y, width, height, format, type, pixels);
3509 }
3510 }
3511 catch(std::bad_alloc&)
3512 {
3513 return error(GL_OUT_OF_MEMORY);
3514 }
3515}
3516
3517void __stdcall glReleaseShaderCompiler(void)
3518{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003519 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003520
3521 try
3522 {
3523 gl::Shader::releaseCompiler();
3524 }
3525 catch(std::bad_alloc&)
3526 {
3527 return error(GL_OUT_OF_MEMORY);
3528 }
3529}
3530
3531void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3532{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003533 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3534 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003535
3536 try
3537 {
3538 switch (target)
3539 {
3540 case GL_RENDERBUFFER:
3541 break;
3542 default:
3543 return error(GL_INVALID_ENUM);
3544 }
3545
3546 switch (internalformat)
3547 {
3548 case GL_DEPTH_COMPONENT16:
3549 case GL_RGBA4:
3550 case GL_RGB5_A1:
3551 case GL_RGB565:
3552 case GL_STENCIL_INDEX8:
3553 break;
3554 default:
3555 return error(GL_INVALID_ENUM);
3556 }
3557
3558 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3559 {
3560 return error(GL_INVALID_VALUE);
3561 }
3562
3563 gl::Context *context = gl::getContext();
3564
3565 if (context)
3566 {
3567 if (context->framebuffer == 0 || context->renderbuffer == 0)
3568 {
3569 return error(GL_INVALID_OPERATION);
3570 }
3571
3572 switch (internalformat)
3573 {
3574 case GL_DEPTH_COMPONENT16:
3575 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3576 break;
3577 case GL_RGBA4:
3578 case GL_RGB5_A1:
3579 case GL_RGB565:
daniel@transgaming.com70d312a2010-04-20 18:52:38 +00003580 context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003581 break;
3582 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003583 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003584 break;
3585 default:
3586 return error(GL_INVALID_ENUM);
3587 }
3588 }
3589 }
3590 catch(std::bad_alloc&)
3591 {
3592 return error(GL_OUT_OF_MEMORY);
3593 }
3594}
3595
3596void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3597{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003598 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003599
3600 try
3601 {
3602 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003603
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003604 if (context)
3605 {
3606 context->sampleCoverageValue = gl::clamp01(value);
3607 context->sampleCoverageInvert = invert;
3608 }
3609 }
3610 catch(std::bad_alloc&)
3611 {
3612 return error(GL_OUT_OF_MEMORY);
3613 }
3614}
3615
3616void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3617{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003618 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 +00003619
3620 try
3621 {
3622 if (width < 0 || height < 0)
3623 {
3624 return error(GL_INVALID_VALUE);
3625 }
3626
3627 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003628
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003629 if (context)
3630 {
3631 context->scissorX = x;
3632 context->scissorY = y;
3633 context->scissorWidth = width;
3634 context->scissorHeight = height;
3635 }
3636 }
3637 catch(std::bad_alloc&)
3638 {
3639 return error(GL_OUT_OF_MEMORY);
3640 }
3641}
3642
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003643void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003644{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003645 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003646 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003647 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003648
3649 try
3650 {
3651 if (n < 0 || length < 0)
3652 {
3653 return error(GL_INVALID_VALUE);
3654 }
3655
3656 UNIMPLEMENTED(); // FIXME
3657 }
3658 catch(std::bad_alloc&)
3659 {
3660 return error(GL_OUT_OF_MEMORY);
3661 }
3662}
3663
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003664void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003665{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003666 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 +00003667 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003668
3669 try
3670 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003671 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003672 {
3673 return error(GL_INVALID_VALUE);
3674 }
3675
3676 gl::Context *context = gl::getContext();
3677
3678 if (context)
3679 {
3680 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003681
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003682 if (!shaderObject)
3683 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003684 if (context->getProgram(shader))
3685 {
3686 return error(GL_INVALID_OPERATION);
3687 }
3688 else
3689 {
3690 return error(GL_INVALID_VALUE);
3691 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003692 }
3693
3694 shaderObject->setSource(count, string, length);
3695 }
3696 }
3697 catch(std::bad_alloc&)
3698 {
3699 return error(GL_OUT_OF_MEMORY);
3700 }
3701}
3702
3703void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3704{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003705 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003706}
3707
3708void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3709{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003710 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 +00003711
3712 try
3713 {
3714 switch (face)
3715 {
3716 case GL_FRONT:
3717 case GL_BACK:
3718 case GL_FRONT_AND_BACK:
3719 break;
3720 default:
3721 return error(GL_INVALID_ENUM);
3722 }
3723
3724 switch (func)
3725 {
3726 case GL_NEVER:
3727 case GL_ALWAYS:
3728 case GL_LESS:
3729 case GL_LEQUAL:
3730 case GL_EQUAL:
3731 case GL_GEQUAL:
3732 case GL_GREATER:
3733 case GL_NOTEQUAL:
3734 break;
3735 default:
3736 return error(GL_INVALID_ENUM);
3737 }
3738
3739 gl::Context *context = gl::getContext();
3740
3741 if (context)
3742 {
3743 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3744 {
3745 context->stencilFunc = func;
3746 context->stencilRef = ref;
3747 context->stencilMask = mask;
3748 }
3749
3750 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3751 {
3752 context->stencilBackFunc = func;
3753 context->stencilBackRef = ref;
3754 context->stencilBackMask = mask;
3755 }
3756 }
3757 }
3758 catch(std::bad_alloc&)
3759 {
3760 return error(GL_OUT_OF_MEMORY);
3761 }
3762}
3763
3764void __stdcall glStencilMask(GLuint mask)
3765{
3766 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3767}
3768
3769void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3770{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003771 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003772
3773 try
3774 {
3775 switch (face)
3776 {
3777 case GL_FRONT:
3778 case GL_BACK:
3779 case GL_FRONT_AND_BACK:
3780 break;
3781 default:
3782 return error(GL_INVALID_ENUM);
3783 }
3784
3785 gl::Context *context = gl::getContext();
3786
3787 if (context)
3788 {
3789 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3790 {
3791 context->stencilWritemask = mask;
3792 }
3793
3794 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3795 {
3796 context->stencilBackWritemask = mask;
3797 }
3798 }
3799 }
3800 catch(std::bad_alloc&)
3801 {
3802 return error(GL_OUT_OF_MEMORY);
3803 }
3804}
3805
3806void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3807{
3808 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3809}
3810
3811void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3812{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003813 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3814 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003815
3816 try
3817 {
3818 switch (face)
3819 {
3820 case GL_FRONT:
3821 case GL_BACK:
3822 case GL_FRONT_AND_BACK:
3823 break;
3824 default:
3825 return error(GL_INVALID_ENUM);
3826 }
3827
3828 switch (fail)
3829 {
3830 case GL_ZERO:
3831 case GL_KEEP:
3832 case GL_REPLACE:
3833 case GL_INCR:
3834 case GL_DECR:
3835 case GL_INVERT:
3836 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003837 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003838 break;
3839 default:
3840 return error(GL_INVALID_ENUM);
3841 }
3842
3843 switch (zfail)
3844 {
3845 case GL_ZERO:
3846 case GL_KEEP:
3847 case GL_REPLACE:
3848 case GL_INCR:
3849 case GL_DECR:
3850 case GL_INVERT:
3851 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003852 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003853 break;
3854 default:
3855 return error(GL_INVALID_ENUM);
3856 }
3857
3858 switch (zpass)
3859 {
3860 case GL_ZERO:
3861 case GL_KEEP:
3862 case GL_REPLACE:
3863 case GL_INCR:
3864 case GL_DECR:
3865 case GL_INVERT:
3866 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003867 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003868 break;
3869 default:
3870 return error(GL_INVALID_ENUM);
3871 }
3872
3873 gl::Context *context = gl::getContext();
3874
3875 if (context)
3876 {
3877 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3878 {
3879 context->stencilFail = fail;
3880 context->stencilPassDepthFail = zfail;
3881 context->stencilPassDepthPass = zpass;
3882 }
3883
3884 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3885 {
3886 context->stencilBackFail = fail;
3887 context->stencilBackPassDepthFail = zfail;
3888 context->stencilBackPassDepthPass = zpass;
3889 }
3890 }
3891 }
3892 catch(std::bad_alloc&)
3893 {
3894 return error(GL_OUT_OF_MEMORY);
3895 }
3896}
3897
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003898void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3899 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003900{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003901 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 +00003902 "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 +00003903 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003904
3905 try
3906 {
3907 if (level < 0 || width < 0 || height < 0)
3908 {
3909 return error(GL_INVALID_VALUE);
3910 }
3911
3912 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3913 {
3914 return error(GL_INVALID_VALUE);
3915 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003916
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003917 switch (target)
3918 {
3919 case GL_TEXTURE_2D:
3920 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3921 {
3922 return error(GL_INVALID_VALUE);
3923 }
3924 break;
3925 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3926 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3927 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3928 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3929 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3930 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003931 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003932 {
3933 return error(GL_INVALID_VALUE);
3934 }
3935
3936 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3937 {
3938 return error(GL_INVALID_VALUE);
3939 }
3940 break;
3941 default:
3942 return error(GL_INVALID_ENUM);
3943 }
3944
3945 if (internalformat != format)
3946 {
3947 return error(GL_INVALID_OPERATION);
3948 }
3949
3950 switch (internalformat)
3951 {
3952 case GL_ALPHA:
3953 case GL_LUMINANCE:
3954 case GL_LUMINANCE_ALPHA:
3955 switch (type)
3956 {
3957 case GL_UNSIGNED_BYTE:
3958 break;
3959 default:
3960 return error(GL_INVALID_ENUM);
3961 }
3962 break;
3963 case GL_RGB:
3964 switch (type)
3965 {
3966 case GL_UNSIGNED_BYTE:
3967 case GL_UNSIGNED_SHORT_5_6_5:
3968 break;
3969 default:
3970 return error(GL_INVALID_ENUM);
3971 }
3972 break;
3973 case GL_RGBA:
3974 switch (type)
3975 {
3976 case GL_UNSIGNED_BYTE:
3977 case GL_UNSIGNED_SHORT_4_4_4_4:
3978 case GL_UNSIGNED_SHORT_5_5_5_1:
3979 break;
3980 default:
3981 return error(GL_INVALID_ENUM);
3982 }
3983 break;
3984 default:
3985 return error(GL_INVALID_VALUE);
3986 }
3987
3988 if (border != 0)
3989 {
3990 return error(GL_INVALID_VALUE);
3991 }
3992
3993 gl::Context *context = gl::getContext();
3994
3995 if (context)
3996 {
3997 if (target == GL_TEXTURE_2D)
3998 {
3999 gl::Texture2D *texture = context->getTexture2D();
4000
4001 if (!texture)
4002 {
4003 return error(GL_INVALID_OPERATION);
4004 }
4005
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004006 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004007 }
4008 else
4009 {
4010 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4011
4012 if (!texture)
4013 {
4014 return error(GL_INVALID_OPERATION);
4015 }
4016
4017 switch (target)
4018 {
4019 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004020 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004021 break;
4022 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004023 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004024 break;
4025 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004026 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004027 break;
4028 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004029 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004030 break;
4031 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004032 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004033 break;
4034 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004035 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004036 break;
4037 default: UNREACHABLE();
4038 }
4039 }
4040 }
4041 }
4042 catch(std::bad_alloc&)
4043 {
4044 return error(GL_OUT_OF_MEMORY);
4045 }
4046}
4047
4048void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4049{
4050 glTexParameteri(target, pname, (GLint)param);
4051}
4052
4053void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4054{
4055 glTexParameteri(target, pname, (GLint)*params);
4056}
4057
4058void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4059{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004060 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004061
4062 try
4063 {
4064 gl::Context *context = gl::getContext();
4065
4066 if (context)
4067 {
4068 gl::Texture *texture;
4069
4070 switch (target)
4071 {
4072 case GL_TEXTURE_2D:
4073 texture = context->getTexture2D();
4074 break;
4075 case GL_TEXTURE_CUBE_MAP:
4076 texture = context->getTextureCubeMap();
4077 break;
4078 default:
4079 return error(GL_INVALID_ENUM);
4080 }
4081
4082 switch (pname)
4083 {
4084 case GL_TEXTURE_WRAP_S:
4085 if (!texture->setWrapS((GLenum)param))
4086 {
4087 return error(GL_INVALID_ENUM);
4088 }
4089 break;
4090 case GL_TEXTURE_WRAP_T:
4091 if (!texture->setWrapT((GLenum)param))
4092 {
4093 return error(GL_INVALID_ENUM);
4094 }
4095 break;
4096 case GL_TEXTURE_MIN_FILTER:
4097 if (!texture->setMinFilter((GLenum)param))
4098 {
4099 return error(GL_INVALID_ENUM);
4100 }
4101 break;
4102 case GL_TEXTURE_MAG_FILTER:
4103 if (!texture->setMagFilter((GLenum)param))
4104 {
4105 return error(GL_INVALID_ENUM);
4106 }
4107 break;
4108 default:
4109 return error(GL_INVALID_ENUM);
4110 }
4111 }
4112 }
4113 catch(std::bad_alloc&)
4114 {
4115 return error(GL_OUT_OF_MEMORY);
4116 }
4117}
4118
4119void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4120{
4121 glTexParameteri(target, pname, *params);
4122}
4123
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004124void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4125 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004126{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004127 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4128 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004129 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004130 target, level, xoffset, yoffset, width, height, format, type, pixels);
4131
4132 try
4133 {
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00004134 if (!es2dx::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004135 {
4136 return error(GL_INVALID_ENUM);
4137 }
4138
4139 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004140 {
4141 return error(GL_INVALID_VALUE);
4142 }
4143
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004144 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4145 {
4146 return error(GL_INVALID_VALUE);
4147 }
4148
4149 if (!es2dx::CheckTextureFormatType(format, type))
4150 {
4151 return error(GL_INVALID_ENUM);
4152 }
4153
4154 if (width == 0 || height == 0 || pixels == NULL)
4155 {
4156 return;
4157 }
4158
4159 gl::Context *context = gl::getContext();
4160
4161 if (context)
4162 {
4163 if (target == GL_TEXTURE_2D)
4164 {
4165 gl::Texture2D *texture = context->getTexture2D();
4166
4167 if (!texture)
4168 {
4169 return error(GL_INVALID_OPERATION);
4170 }
4171
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004172 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004173 }
4174 else if (es2dx::IsCubemapTextureTarget(target))
4175 {
4176 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4177
4178 if (!texture)
4179 {
4180 return error(GL_INVALID_OPERATION);
4181 }
4182
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004183 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004184 }
4185 else
4186 {
4187 UNREACHABLE();
4188 }
4189 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004190 }
4191 catch(std::bad_alloc&)
4192 {
4193 return error(GL_OUT_OF_MEMORY);
4194 }
4195}
4196
4197void __stdcall glUniform1f(GLint location, GLfloat x)
4198{
4199 glUniform1fv(location, 1, &x);
4200}
4201
4202void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4203{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004204 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004205
4206 try
4207 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004208 if (count < 0)
4209 {
4210 return error(GL_INVALID_VALUE);
4211 }
4212
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004213 if (location == -1)
4214 {
4215 return;
4216 }
4217
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004218 gl::Context *context = gl::getContext();
4219
4220 if (context)
4221 {
4222 gl::Program *program = context->getCurrentProgram();
4223
4224 if (!program)
4225 {
4226 return error(GL_INVALID_OPERATION);
4227 }
4228
4229 if (!program->setUniform1fv(location, count, v))
4230 {
4231 return error(GL_INVALID_OPERATION);
4232 }
4233 }
4234 }
4235 catch(std::bad_alloc&)
4236 {
4237 return error(GL_OUT_OF_MEMORY);
4238 }
4239}
4240
4241void __stdcall glUniform1i(GLint location, GLint x)
4242{
4243 glUniform1iv(location, 1, &x);
4244}
4245
4246void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4247{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004248 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004249
4250 try
4251 {
4252 if (count < 0)
4253 {
4254 return error(GL_INVALID_VALUE);
4255 }
4256
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004257 if (location == -1)
4258 {
4259 return;
4260 }
4261
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004262 gl::Context *context = gl::getContext();
4263
4264 if (context)
4265 {
4266 gl::Program *program = context->getCurrentProgram();
4267
4268 if (!program)
4269 {
4270 return error(GL_INVALID_OPERATION);
4271 }
4272
4273 if (!program->setUniform1iv(location, count, v))
4274 {
4275 return error(GL_INVALID_OPERATION);
4276 }
4277 }
4278 }
4279 catch(std::bad_alloc&)
4280 {
4281 return error(GL_OUT_OF_MEMORY);
4282 }
4283}
4284
4285void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4286{
4287 GLfloat xy[2] = {x, y};
4288
4289 glUniform2fv(location, 1, (GLfloat*)&xy);
4290}
4291
4292void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4293{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004294 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004295
4296 try
4297 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004298 if (count < 0)
4299 {
4300 return error(GL_INVALID_VALUE);
4301 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004302
4303 if (location == -1)
4304 {
4305 return;
4306 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004307
4308 gl::Context *context = gl::getContext();
4309
4310 if (context)
4311 {
4312 gl::Program *program = context->getCurrentProgram();
4313
4314 if (!program)
4315 {
4316 return error(GL_INVALID_OPERATION);
4317 }
4318
4319 if (!program->setUniform2fv(location, count, v))
4320 {
4321 return error(GL_INVALID_OPERATION);
4322 }
4323 }
4324 }
4325 catch(std::bad_alloc&)
4326 {
4327 return error(GL_OUT_OF_MEMORY);
4328 }
4329}
4330
4331void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4332{
4333 GLint xy[4] = {x, y};
4334
4335 glUniform2iv(location, 1, (GLint*)&xy);
4336}
4337
4338void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4339{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004340 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004341
4342 try
4343 {
4344 if (count < 0)
4345 {
4346 return error(GL_INVALID_VALUE);
4347 }
4348
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004349 if (location == -1)
4350 {
4351 return;
4352 }
4353
4354 gl::Context *context = gl::getContext();
4355
4356 if (context)
4357 {
4358 gl::Program *program = context->getCurrentProgram();
4359
4360 if (!program)
4361 {
4362 return error(GL_INVALID_OPERATION);
4363 }
4364
4365 if (!program->setUniform2iv(location, count, v))
4366 {
4367 return error(GL_INVALID_OPERATION);
4368 }
4369 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004370 }
4371 catch(std::bad_alloc&)
4372 {
4373 return error(GL_OUT_OF_MEMORY);
4374 }
4375}
4376
4377void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4378{
4379 GLfloat xyz[3] = {x, y, z};
4380
4381 glUniform3fv(location, 1, (GLfloat*)&xyz);
4382}
4383
4384void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4385{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004386 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004387
4388 try
4389 {
4390 if (count < 0)
4391 {
4392 return error(GL_INVALID_VALUE);
4393 }
4394
4395 if (location == -1)
4396 {
4397 return;
4398 }
4399
4400 gl::Context *context = gl::getContext();
4401
4402 if (context)
4403 {
4404 gl::Program *program = context->getCurrentProgram();
4405
4406 if (!program)
4407 {
4408 return error(GL_INVALID_OPERATION);
4409 }
4410
4411 if (!program->setUniform3fv(location, count, v))
4412 {
4413 return error(GL_INVALID_OPERATION);
4414 }
4415 }
4416 }
4417 catch(std::bad_alloc&)
4418 {
4419 return error(GL_OUT_OF_MEMORY);
4420 }
4421}
4422
4423void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4424{
4425 GLint xyz[3] = {x, y, z};
4426
4427 glUniform3iv(location, 1, (GLint*)&xyz);
4428}
4429
4430void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4431{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004432 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004433
4434 try
4435 {
4436 if (count < 0)
4437 {
4438 return error(GL_INVALID_VALUE);
4439 }
4440
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004441 if (location == -1)
4442 {
4443 return;
4444 }
4445
4446 gl::Context *context = gl::getContext();
4447
4448 if (context)
4449 {
4450 gl::Program *program = context->getCurrentProgram();
4451
4452 if (!program)
4453 {
4454 return error(GL_INVALID_OPERATION);
4455 }
4456
4457 if (!program->setUniform3iv(location, count, v))
4458 {
4459 return error(GL_INVALID_OPERATION);
4460 }
4461 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004462 }
4463 catch(std::bad_alloc&)
4464 {
4465 return error(GL_OUT_OF_MEMORY);
4466 }
4467}
4468
4469void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4470{
4471 GLfloat xyzw[4] = {x, y, z, w};
4472
4473 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4474}
4475
4476void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4477{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004478 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004479
4480 try
4481 {
4482 if (count < 0)
4483 {
4484 return error(GL_INVALID_VALUE);
4485 }
4486
4487 if (location == -1)
4488 {
4489 return;
4490 }
4491
4492 gl::Context *context = gl::getContext();
4493
4494 if (context)
4495 {
4496 gl::Program *program = context->getCurrentProgram();
4497
4498 if (!program)
4499 {
4500 return error(GL_INVALID_OPERATION);
4501 }
4502
4503 if (!program->setUniform4fv(location, count, v))
4504 {
4505 return error(GL_INVALID_OPERATION);
4506 }
4507 }
4508 }
4509 catch(std::bad_alloc&)
4510 {
4511 return error(GL_OUT_OF_MEMORY);
4512 }
4513}
4514
4515void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4516{
4517 GLint xyzw[4] = {x, y, z, w};
4518
4519 glUniform4iv(location, 1, (GLint*)&xyzw);
4520}
4521
4522void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4523{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004524 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004525
4526 try
4527 {
4528 if (count < 0)
4529 {
4530 return error(GL_INVALID_VALUE);
4531 }
4532
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004533 if (location == -1)
4534 {
4535 return;
4536 }
4537
4538 gl::Context *context = gl::getContext();
4539
4540 if (context)
4541 {
4542 gl::Program *program = context->getCurrentProgram();
4543
4544 if (!program)
4545 {
4546 return error(GL_INVALID_OPERATION);
4547 }
4548
4549 if (!program->setUniform4iv(location, count, v))
4550 {
4551 return error(GL_INVALID_OPERATION);
4552 }
4553 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004554 }
4555 catch(std::bad_alloc&)
4556 {
4557 return error(GL_OUT_OF_MEMORY);
4558 }
4559}
4560
4561void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4562{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004563 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4564 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004565
4566 try
4567 {
4568 if (count < 0 || transpose != GL_FALSE)
4569 {
4570 return error(GL_INVALID_VALUE);
4571 }
4572
4573 if (location == -1)
4574 {
4575 return;
4576 }
4577
4578 gl::Context *context = gl::getContext();
4579
4580 if (context)
4581 {
4582 gl::Program *program = context->getCurrentProgram();
4583
4584 if (!program)
4585 {
4586 return error(GL_INVALID_OPERATION);
4587 }
4588
4589 if (!program->setUniformMatrix2fv(location, count, value))
4590 {
4591 return error(GL_INVALID_OPERATION);
4592 }
4593 }
4594 }
4595 catch(std::bad_alloc&)
4596 {
4597 return error(GL_OUT_OF_MEMORY);
4598 }
4599}
4600
4601void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4602{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004603 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4604 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004605
4606 try
4607 {
4608 if (count < 0 || transpose != GL_FALSE)
4609 {
4610 return error(GL_INVALID_VALUE);
4611 }
4612
4613 if (location == -1)
4614 {
4615 return;
4616 }
4617
4618 gl::Context *context = gl::getContext();
4619
4620 if (context)
4621 {
4622 gl::Program *program = context->getCurrentProgram();
4623
4624 if (!program)
4625 {
4626 return error(GL_INVALID_OPERATION);
4627 }
4628
4629 if (!program->setUniformMatrix3fv(location, count, value))
4630 {
4631 return error(GL_INVALID_OPERATION);
4632 }
4633 }
4634 }
4635 catch(std::bad_alloc&)
4636 {
4637 return error(GL_OUT_OF_MEMORY);
4638 }
4639}
4640
4641void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4642{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004643 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4644 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004645
4646 try
4647 {
4648 if (count < 0 || transpose != GL_FALSE)
4649 {
4650 return error(GL_INVALID_VALUE);
4651 }
4652
4653 if (location == -1)
4654 {
4655 return;
4656 }
4657
4658 gl::Context *context = gl::getContext();
4659
4660 if (context)
4661 {
4662 gl::Program *program = context->getCurrentProgram();
4663
4664 if (!program)
4665 {
4666 return error(GL_INVALID_OPERATION);
4667 }
4668
4669 if (!program->setUniformMatrix4fv(location, count, value))
4670 {
4671 return error(GL_INVALID_OPERATION);
4672 }
4673 }
4674 }
4675 catch(std::bad_alloc&)
4676 {
4677 return error(GL_OUT_OF_MEMORY);
4678 }
4679}
4680
4681void __stdcall glUseProgram(GLuint program)
4682{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004683 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004684
4685 try
4686 {
4687 gl::Context *context = gl::getContext();
4688
4689 if (context)
4690 {
4691 gl::Program *programObject = context->getProgram(program);
4692
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004693 if (!programObject && program != 0)
4694 {
4695 if (context->getShader(program))
4696 {
4697 return error(GL_INVALID_OPERATION);
4698 }
4699 else
4700 {
4701 return error(GL_INVALID_VALUE);
4702 }
4703 }
4704
4705 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004706 {
4707 return error(GL_INVALID_OPERATION);
4708 }
4709
4710 context->useProgram(program);
4711 }
4712 }
4713 catch(std::bad_alloc&)
4714 {
4715 return error(GL_OUT_OF_MEMORY);
4716 }
4717}
4718
4719void __stdcall glValidateProgram(GLuint program)
4720{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004721 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004722
4723 try
4724 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00004725 gl::Context *context = gl::getContext();
4726
4727 if (context)
4728 {
4729 gl::Program *programObject = context->getProgram(program);
4730
4731 if (!programObject)
4732 {
4733 if (context->getShader(program))
4734 {
4735 return error(GL_INVALID_OPERATION);
4736 }
4737 else
4738 {
4739 return error(GL_INVALID_VALUE);
4740 }
4741 }
4742
4743 programObject->validate();
4744 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004745 }
4746 catch(std::bad_alloc&)
4747 {
4748 return error(GL_OUT_OF_MEMORY);
4749 }
4750}
4751
4752void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4753{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004754 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004755
4756 try
4757 {
4758 if (index >= gl::MAX_VERTEX_ATTRIBS)
4759 {
4760 return error(GL_INVALID_VALUE);
4761 }
4762
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004763 gl::Context *context = gl::getContext();
4764
4765 if (context)
4766 {
4767 GLfloat vals[4] = { x, 0, 0, 1 };
4768 context->setVertexAttrib(index, vals);
4769 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004770 }
4771 catch(std::bad_alloc&)
4772 {
4773 return error(GL_OUT_OF_MEMORY);
4774 }
4775}
4776
4777void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4778{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004779 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004780
4781 try
4782 {
4783 if (index >= gl::MAX_VERTEX_ATTRIBS)
4784 {
4785 return error(GL_INVALID_VALUE);
4786 }
4787
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004788 gl::Context *context = gl::getContext();
4789
4790 if (context)
4791 {
4792 GLfloat vals[4] = { values[0], 0, 0, 1 };
4793 context->setVertexAttrib(index, vals);
4794 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004795 }
4796 catch(std::bad_alloc&)
4797 {
4798 return error(GL_OUT_OF_MEMORY);
4799 }
4800}
4801
4802void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4803{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004804 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004805
4806 try
4807 {
4808 if (index >= gl::MAX_VERTEX_ATTRIBS)
4809 {
4810 return error(GL_INVALID_VALUE);
4811 }
4812
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004813 gl::Context *context = gl::getContext();
4814
4815 if (context)
4816 {
4817 GLfloat vals[4] = { x, y, 0, 1 };
4818 context->setVertexAttrib(index, vals);
4819 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004820 }
4821 catch(std::bad_alloc&)
4822 {
4823 return error(GL_OUT_OF_MEMORY);
4824 }
4825}
4826
4827void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4828{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004829 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004830
4831 try
4832 {
4833 if (index >= gl::MAX_VERTEX_ATTRIBS)
4834 {
4835 return error(GL_INVALID_VALUE);
4836 }
4837
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004838 gl::Context *context = gl::getContext();
4839
4840 if (context)
4841 {
4842 GLfloat vals[4] = { values[0], values[1], 0, 1 };
4843 context->setVertexAttrib(index, vals);
4844 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004845 }
4846 catch(std::bad_alloc&)
4847 {
4848 return error(GL_OUT_OF_MEMORY);
4849 }
4850}
4851
4852void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4853{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004854 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 +00004855
4856 try
4857 {
4858 if (index >= gl::MAX_VERTEX_ATTRIBS)
4859 {
4860 return error(GL_INVALID_VALUE);
4861 }
4862
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004863 gl::Context *context = gl::getContext();
4864
4865 if (context)
4866 {
4867 GLfloat vals[4] = { x, y, z, 1 };
4868 context->setVertexAttrib(index, vals);
4869 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004870 }
4871 catch(std::bad_alloc&)
4872 {
4873 return error(GL_OUT_OF_MEMORY);
4874 }
4875}
4876
4877void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4878{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004879 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004880
4881 try
4882 {
4883 if (index >= gl::MAX_VERTEX_ATTRIBS)
4884 {
4885 return error(GL_INVALID_VALUE);
4886 }
4887
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004888 gl::Context *context = gl::getContext();
4889
4890 if (context)
4891 {
4892 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
4893 context->setVertexAttrib(index, vals);
4894 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004895 }
4896 catch(std::bad_alloc&)
4897 {
4898 return error(GL_OUT_OF_MEMORY);
4899 }
4900}
4901
4902void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4903{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004904 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 +00004905
4906 try
4907 {
4908 if (index >= gl::MAX_VERTEX_ATTRIBS)
4909 {
4910 return error(GL_INVALID_VALUE);
4911 }
4912
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004913 gl::Context *context = gl::getContext();
4914
4915 if (context)
4916 {
4917 GLfloat vals[4] = { x, y, z, w };
4918 context->setVertexAttrib(index, vals);
4919 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004920 }
4921 catch(std::bad_alloc&)
4922 {
4923 return error(GL_OUT_OF_MEMORY);
4924 }
4925}
4926
4927void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4928{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004929 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004930
4931 try
4932 {
4933 if (index >= gl::MAX_VERTEX_ATTRIBS)
4934 {
4935 return error(GL_INVALID_VALUE);
4936 }
4937
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004938 gl::Context *context = gl::getContext();
4939
4940 if (context)
4941 {
4942 context->setVertexAttrib(index, values);
4943 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004944 }
4945 catch(std::bad_alloc&)
4946 {
4947 return error(GL_OUT_OF_MEMORY);
4948 }
4949}
4950
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004951void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004952{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004953 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004954 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004955 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004956
4957 try
4958 {
4959 if (index >= gl::MAX_VERTEX_ATTRIBS)
4960 {
4961 return error(GL_INVALID_VALUE);
4962 }
4963
4964 if (size < 1 || size > 4)
4965 {
4966 return error(GL_INVALID_VALUE);
4967 }
4968
4969 switch (type)
4970 {
4971 case GL_BYTE:
4972 case GL_UNSIGNED_BYTE:
4973 case GL_SHORT:
4974 case GL_UNSIGNED_SHORT:
4975 case GL_FIXED:
4976 case GL_FLOAT:
4977 break;
4978 default:
4979 return error(GL_INVALID_ENUM);
4980 }
4981
4982 if (stride < 0)
4983 {
4984 return error(GL_INVALID_VALUE);
4985 }
4986
4987 gl::Context *context = gl::getContext();
4988
4989 if (context)
4990 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004991 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4992 context->vertexAttribute[index].mSize = size;
4993 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004994 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004995 context->vertexAttribute[index].mStride = stride;
4996 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004997 }
4998 }
4999 catch(std::bad_alloc&)
5000 {
5001 return error(GL_OUT_OF_MEMORY);
5002 }
5003}
5004
5005void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5006{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005007 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 +00005008
5009 try
5010 {
5011 if (width < 0 || height < 0)
5012 {
5013 return error(GL_INVALID_VALUE);
5014 }
5015
5016 gl::Context *context = gl::getContext();
5017
5018 if (context)
5019 {
5020 context->viewportX = x;
5021 context->viewportY = y;
5022 context->viewportWidth = width;
5023 context->viewportHeight = height;
5024 }
5025 }
5026 catch(std::bad_alloc&)
5027 {
5028 return error(GL_OUT_OF_MEMORY);
5029 }
5030}
5031
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005032void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5033 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005034{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005035 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5036 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005037 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005038 target, level, internalformat, width, height, depth, border, format, type, pixels);
5039
5040 try
5041 {
5042 UNIMPLEMENTED(); // FIXME
5043 }
5044 catch(std::bad_alloc&)
5045 {
5046 return error(GL_OUT_OF_MEMORY);
5047 }
5048}
5049}