blob: 163a74f85b7d31949aa470381602263ad281d7ee [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.com41430492010-03-11 20:36:18 +0000733 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
734 {
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.com41430492010-03-11 20:36:18 +0000766 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
767 {
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.comb8c28ed2010-04-13 03:26:32 +0000905 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
906 {
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:
1630 break;
1631 default:
1632 return error(GL_INVALID_ENUM);
1633 }
1634
1635 gl::Context *context = gl::getContext();
1636
1637 if (context)
1638 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001639 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001640 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001641 textarget = GL_NONE;
1642 }
1643 else
1644 {
1645 gl::Texture *tex = context->getTexture(texture);
1646
1647 if (tex == NULL)
1648 {
1649 return error(GL_INVALID_OPERATION);
1650 }
1651
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001652 switch (textarget)
1653 {
1654 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001655 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001656 {
1657 return error(GL_INVALID_OPERATION);
1658 }
1659 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001660
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001661 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001662 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001663 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001664 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001665 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001666 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001667 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1668 {
1669 return error(GL_INVALID_OPERATION);
1670 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001671 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001672
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001673 default:
1674 return error(GL_INVALID_ENUM);
1675 }
1676
1677 if (level != 0)
1678 {
1679 return error(GL_INVALID_VALUE);
1680 }
1681 }
1682
1683 gl::Framebuffer *framebuffer = context->getFramebuffer();
1684
1685 if (context->framebuffer == 0 || !framebuffer)
1686 {
1687 return error(GL_INVALID_OPERATION);
1688 }
1689
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001690 framebuffer->setColorbuffer(textarget, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001691 }
1692 }
1693 catch(std::bad_alloc&)
1694 {
1695 return error(GL_OUT_OF_MEMORY);
1696 }
1697}
1698
1699void __stdcall glFrontFace(GLenum mode)
1700{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001701 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001702
1703 try
1704 {
1705 switch (mode)
1706 {
1707 case GL_CW:
1708 case GL_CCW:
1709 {
1710 gl::Context *context = gl::getContext();
1711
1712 if (context)
1713 {
1714 context->frontFace = mode;
1715 }
1716 }
1717 break;
1718 default:
1719 return error(GL_INVALID_ENUM);
1720 }
1721 }
1722 catch(std::bad_alloc&)
1723 {
1724 return error(GL_OUT_OF_MEMORY);
1725 }
1726}
1727
1728void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1729{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001730 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001731
1732 try
1733 {
1734 if (n < 0)
1735 {
1736 return error(GL_INVALID_VALUE);
1737 }
1738
1739 gl::Context *context = gl::getContext();
1740
1741 if (context)
1742 {
1743 for (int i = 0; i < n; i++)
1744 {
1745 buffers[i] = context->createBuffer();
1746 }
1747 }
1748 }
1749 catch(std::bad_alloc&)
1750 {
1751 return error(GL_OUT_OF_MEMORY);
1752 }
1753}
1754
1755void __stdcall glGenerateMipmap(GLenum target)
1756{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001757 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001758
1759 try
1760 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00001761 gl::Context *context = gl::getContext();
1762
1763 if (context)
1764 {
1765 gl::Texture *texture;
1766
1767 switch (target)
1768 {
1769 case GL_TEXTURE_2D:
1770 texture = context->getTexture2D();
1771 break;
1772
1773 case GL_TEXTURE_CUBE_MAP:
1774 texture = context->getTextureCubeMap();
1775 break;
1776
1777 default:
1778 return error(GL_INVALID_ENUM);
1779 }
1780
1781 texture->generateMipmaps();
1782 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001783 }
1784 catch(std::bad_alloc&)
1785 {
1786 return error(GL_OUT_OF_MEMORY);
1787 }
1788}
1789
1790void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1791{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001792 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001793
1794 try
1795 {
1796 if (n < 0)
1797 {
1798 return error(GL_INVALID_VALUE);
1799 }
1800
1801 gl::Context *context = gl::getContext();
1802
1803 if (context)
1804 {
1805 for (int i = 0; i < n; i++)
1806 {
1807 framebuffers[i] = context->createFramebuffer();
1808 }
1809 }
1810 }
1811 catch(std::bad_alloc&)
1812 {
1813 return error(GL_OUT_OF_MEMORY);
1814 }
1815}
1816
1817void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1818{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001819 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001820
1821 try
1822 {
1823 if (n < 0)
1824 {
1825 return error(GL_INVALID_VALUE);
1826 }
1827
1828 gl::Context *context = gl::getContext();
1829
1830 if (context)
1831 {
1832 for (int i = 0; i < n; i++)
1833 {
1834 renderbuffers[i] = context->createRenderbuffer();
1835 }
1836 }
1837 }
1838 catch(std::bad_alloc&)
1839 {
1840 return error(GL_OUT_OF_MEMORY);
1841 }
1842}
1843
1844void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1845{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001846 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001847
1848 try
1849 {
1850 if (n < 0)
1851 {
1852 return error(GL_INVALID_VALUE);
1853 }
1854
1855 gl::Context *context = gl::getContext();
1856
1857 if (context)
1858 {
1859 for (int i = 0; i < n; i++)
1860 {
1861 textures[i] = context->createTexture();
1862 }
1863 }
1864 }
1865 catch(std::bad_alloc&)
1866 {
1867 return error(GL_OUT_OF_MEMORY);
1868 }
1869}
1870
daniel@transgaming.com85423182010-04-22 13:35:27 +00001871void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001872{
daniel@transgaming.com85423182010-04-22 13:35:27 +00001873 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
1874 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001875 program, index, bufsize, length, size, type, name);
1876
1877 try
1878 {
1879 if (bufsize < 0)
1880 {
1881 return error(GL_INVALID_VALUE);
1882 }
1883
daniel@transgaming.com85423182010-04-22 13:35:27 +00001884 gl::Context *context = gl::getContext();
1885
1886 if (context)
1887 {
1888 gl::Program *programObject = context->getProgram(program);
1889
1890 if (!programObject)
1891 {
1892 if (context->getShader(program))
1893 {
1894 return error(GL_INVALID_OPERATION);
1895 }
1896 else
1897 {
1898 return error(GL_INVALID_VALUE);
1899 }
1900 }
1901
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001902 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00001903 {
1904 return error(GL_INVALID_VALUE);
1905 }
1906
1907 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
1908 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001909 }
1910 catch(std::bad_alloc&)
1911 {
1912 return error(GL_OUT_OF_MEMORY);
1913 }
1914}
1915
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001916void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001917{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001918 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001919 "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 +00001920 program, index, bufsize, length, size, type, name);
1921
1922 try
1923 {
1924 if (bufsize < 0)
1925 {
1926 return error(GL_INVALID_VALUE);
1927 }
1928
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001929 gl::Context *context = gl::getContext();
1930
1931 if (context)
1932 {
1933 gl::Program *programObject = context->getProgram(program);
1934
1935 if (!programObject)
1936 {
1937 if (context->getShader(program))
1938 {
1939 return error(GL_INVALID_OPERATION);
1940 }
1941 else
1942 {
1943 return error(GL_INVALID_VALUE);
1944 }
1945 }
1946
1947 if (index >= (GLuint)programObject->getActiveUniformCount())
1948 {
1949 return error(GL_INVALID_VALUE);
1950 }
1951
1952 programObject->getActiveUniform(index, bufsize, length, size, type, name);
1953 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001954 }
1955 catch(std::bad_alloc&)
1956 {
1957 return error(GL_OUT_OF_MEMORY);
1958 }
1959}
1960
1961void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1962{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001963 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1964 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001965
1966 try
1967 {
1968 if (maxcount < 0)
1969 {
1970 return error(GL_INVALID_VALUE);
1971 }
1972
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001973 gl::Context *context = gl::getContext();
1974
1975 if (context)
1976 {
1977 gl::Program *programObject = context->getProgram(program);
1978
1979 if (!programObject)
1980 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001981 if (context->getShader(program))
1982 {
1983 return error(GL_INVALID_OPERATION);
1984 }
1985 else
1986 {
1987 return error(GL_INVALID_VALUE);
1988 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001989 }
1990
1991 return programObject->getAttachedShaders(maxcount, count, shaders);
1992 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001993 }
1994 catch(std::bad_alloc&)
1995 {
1996 return error(GL_OUT_OF_MEMORY);
1997 }
1998}
1999
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002000int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002001{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002002 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002003
2004 try
2005 {
2006 gl::Context *context = gl::getContext();
2007
2008 if (context)
2009 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002010
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002011 gl::Program *programObject = context->getProgram(program);
2012
2013 if (!programObject)
2014 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002015 if (context->getShader(program))
2016 {
2017 return error(GL_INVALID_OPERATION, -1);
2018 }
2019 else
2020 {
2021 return error(GL_INVALID_VALUE, -1);
2022 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002023 }
2024
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002025 if (!programObject->isLinked())
2026 {
2027 return error(GL_INVALID_OPERATION, -1);
2028 }
2029
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002030 return programObject->getAttributeLocation(name);
2031 }
2032 }
2033 catch(std::bad_alloc&)
2034 {
2035 return error(GL_OUT_OF_MEMORY, -1);
2036 }
2037
2038 return -1;
2039}
2040
2041void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2042{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002043 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002044
2045 try
2046 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002047 gl::Context *context = gl::getContext();
2048
2049 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002050 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002051 if (!(context->getBooleanv(pname, params)))
2052 {
2053 GLenum nativeType;
2054 unsigned int numParams = 0;
2055 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2056 return error(GL_INVALID_ENUM);
2057
2058 if (numParams == 0)
2059 return; // it is known that the pname is valid, but there are no parameters to return
2060
2061 if (nativeType == GL_FLOAT)
2062 {
2063 GLfloat *floatParams = NULL;
2064 floatParams = new GLfloat[numParams];
2065
2066 context->getFloatv(pname, floatParams);
2067
2068 for (unsigned int i = 0; i < numParams; ++i)
2069 {
2070 if (floatParams[i] == 0.0f)
2071 params[i] = GL_FALSE;
2072 else
2073 params[i] = GL_TRUE;
2074 }
2075
2076 delete [] floatParams;
2077 }
2078 else if (nativeType == GL_INT)
2079 {
2080 GLint *intParams = NULL;
2081 intParams = new GLint[numParams];
2082
2083 context->getIntegerv(pname, intParams);
2084
2085 for (unsigned int i = 0; i < numParams; ++i)
2086 {
2087 if (intParams[i] == 0)
2088 params[i] = GL_FALSE;
2089 else
2090 params[i] = GL_TRUE;
2091 }
2092
2093 delete [] intParams;
2094 }
2095 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002096 }
2097 }
2098 catch(std::bad_alloc&)
2099 {
2100 return error(GL_OUT_OF_MEMORY);
2101 }
2102}
2103
2104void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2105{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002106 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 +00002107
2108 try
2109 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002110 gl::Context *context = gl::getContext();
2111
2112 if (context)
2113 {
2114 gl::Buffer *buffer;
2115
2116 switch (target)
2117 {
2118 case GL_ARRAY_BUFFER:
2119 buffer = context->getArrayBuffer();
2120 break;
2121 case GL_ELEMENT_ARRAY_BUFFER:
2122 buffer = context->getElementArrayBuffer();
2123 break;
2124 default: return error(GL_INVALID_ENUM);
2125 }
2126
2127 if (!buffer)
2128 {
2129 // A null buffer means that "0" is bound to the requested buffer target
2130 return error(GL_INVALID_OPERATION);
2131 }
2132
2133 switch (pname)
2134 {
2135 case GL_BUFFER_USAGE:
2136 *params = buffer->usage();
2137 break;
2138 case GL_BUFFER_SIZE:
2139 *params = buffer->size();
2140 break;
2141 default: return error(GL_INVALID_ENUM);
2142 }
2143 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002144 }
2145 catch(std::bad_alloc&)
2146 {
2147 return error(GL_OUT_OF_MEMORY);
2148 }
2149}
2150
2151GLenum __stdcall glGetError(void)
2152{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002153 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002154
2155 gl::Context *context = gl::getContext();
2156
2157 if (context)
2158 {
2159 return context->getError();
2160 }
2161
2162 return GL_NO_ERROR;
2163}
2164
2165void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2166{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002167 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002168
2169 try
2170 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002171 gl::Context *context = gl::getContext();
2172
2173 if (context)
2174 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002175 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002176 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002177 GLenum nativeType;
2178 unsigned int numParams = 0;
2179 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2180 return error(GL_INVALID_ENUM);
2181
2182 if (numParams == 0)
2183 return; // it is known that the pname is valid, but that there are no parameters to return.
2184
2185 if (nativeType == GL_BOOL)
2186 {
2187 GLboolean *boolParams = NULL;
2188 boolParams = new GLboolean[numParams];
2189
2190 context->getBooleanv(pname, boolParams);
2191
2192 for (unsigned int i = 0; i < numParams; ++i)
2193 {
2194 if (boolParams[i] == GL_FALSE)
2195 params[i] = 0.0f;
2196 else
2197 params[i] = 1.0f;
2198 }
2199
2200 delete [] boolParams;
2201 }
2202 else if (nativeType == GL_INT)
2203 {
2204 GLint *intParams = NULL;
2205 intParams = new GLint[numParams];
2206
2207 context->getIntegerv(pname, intParams);
2208
2209 for (unsigned int i = 0; i < numParams; ++i)
2210 {
2211 params[i] = (GLfloat)intParams[i];
2212 }
2213
2214 delete [] intParams;
2215 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002216 }
2217 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002218 }
2219 catch(std::bad_alloc&)
2220 {
2221 return error(GL_OUT_OF_MEMORY);
2222 }
2223}
2224
2225void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2226{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002227 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2228 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002229
2230 try
2231 {
2232 gl::Context *context = gl::getContext();
2233
2234 if (context)
2235 {
2236 if (context->framebuffer == 0)
2237 {
2238 return error(GL_INVALID_OPERATION);
2239 }
2240
2241 UNIMPLEMENTED(); // FIXME
2242 }
2243 }
2244 catch(std::bad_alloc&)
2245 {
2246 return error(GL_OUT_OF_MEMORY);
2247 }
2248}
2249
2250void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2251{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002252 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002253
2254 try
2255 {
2256 gl::Context *context = gl::getContext();
2257
2258 if (context)
2259 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002260 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002261 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002262 GLenum nativeType;
2263 unsigned int numParams = 0;
2264 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2265 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002266
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002267 if (numParams == 0)
2268 return; // it is known that pname is valid, but there are no parameters to return
2269
2270 if (nativeType == GL_BOOL)
2271 {
2272 GLboolean *boolParams = NULL;
2273 boolParams = new GLboolean[numParams];
2274
2275 context->getBooleanv(pname, boolParams);
2276
2277 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002278 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002279 if (boolParams[i] == GL_FALSE)
2280 params[i] = 0;
2281 else
2282 params[i] = 1;
2283 }
2284
2285 delete [] boolParams;
2286 }
2287 else if (nativeType == GL_FLOAT)
2288 {
2289 GLfloat *floatParams = NULL;
2290 floatParams = new GLfloat[numParams];
2291
2292 context->getFloatv(pname, floatParams);
2293
2294 for (unsigned int i = 0; i < numParams; ++i)
2295 {
2296 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002297 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002298 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002299 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002300 else
2301 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 +00002302 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002303
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002304 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002305 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002306 }
2307 }
2308 }
2309 catch(std::bad_alloc&)
2310 {
2311 return error(GL_OUT_OF_MEMORY);
2312 }
2313}
2314
2315void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2316{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002317 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002318
2319 try
2320 {
2321 gl::Context *context = gl::getContext();
2322
2323 if (context)
2324 {
2325 gl::Program *programObject = context->getProgram(program);
2326
2327 if (!programObject)
2328 {
2329 return error(GL_INVALID_VALUE);
2330 }
2331
2332 switch (pname)
2333 {
2334 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002335 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002336 return;
2337 case GL_LINK_STATUS:
2338 *params = programObject->isLinked();
2339 return;
2340 case GL_VALIDATE_STATUS:
2341 UNIMPLEMENTED(); // FIXME
2342 *params = GL_TRUE;
2343 return;
2344 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002345 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002346 return;
2347 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002348 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002349 return;
2350 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002351 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002352 return;
2353 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002354 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002355 return;
2356 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002357 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002358 return;
2359 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002360 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002361 return;
2362 default:
2363 return error(GL_INVALID_ENUM);
2364 }
2365 }
2366 }
2367 catch(std::bad_alloc&)
2368 {
2369 return error(GL_OUT_OF_MEMORY);
2370 }
2371}
2372
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002373void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002374{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002375 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 +00002376 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002377
2378 try
2379 {
2380 if (bufsize < 0)
2381 {
2382 return error(GL_INVALID_VALUE);
2383 }
2384
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002385 gl::Context *context = gl::getContext();
2386
2387 if (context)
2388 {
2389 gl::Program *programObject = context->getProgram(program);
2390
2391 if (!programObject)
2392 {
2393 return error(GL_INVALID_VALUE);
2394 }
2395
2396 programObject->getInfoLog(bufsize, length, infolog);
2397 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002398 }
2399 catch(std::bad_alloc&)
2400 {
2401 return error(GL_OUT_OF_MEMORY);
2402 }
2403}
2404
2405void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2406{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002407 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 +00002408
2409 try
2410 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002411 gl::Context *context = gl::getContext();
2412
2413 if (context)
2414 {
2415 if (target != GL_RENDERBUFFER)
2416 {
2417 return error(GL_INVALID_ENUM);
2418 }
2419
2420 if (context->renderbuffer == 0)
2421 {
2422 return error(GL_INVALID_OPERATION);
2423 }
2424
2425 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->renderbuffer);
2426
2427 switch (pname)
2428 {
2429 case GL_RENDERBUFFER_WIDTH:
2430 *params = renderbuffer->getWidth();
2431 break;
2432 case GL_RENDERBUFFER_HEIGHT:
2433 *params = renderbuffer->getHeight();
2434 break;
2435 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2436 *params = renderbuffer->getFormat();
2437 break;
2438 case GL_RENDERBUFFER_RED_SIZE:
2439 if (renderbuffer->isColorbuffer())
2440 {
2441 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
2442 }
2443 else
2444 {
2445 *params = 0;
2446 }
2447 break;
2448 case GL_RENDERBUFFER_GREEN_SIZE:
2449 if (renderbuffer->isColorbuffer())
2450 {
2451 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
2452 }
2453 else
2454 {
2455 *params = 0;
2456 }
2457 break;
2458 case GL_RENDERBUFFER_BLUE_SIZE:
2459 if (renderbuffer->isColorbuffer())
2460 {
2461 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
2462 }
2463 else
2464 {
2465 *params = 0;
2466 }
2467 break;
2468 case GL_RENDERBUFFER_ALPHA_SIZE:
2469 if (renderbuffer->isColorbuffer())
2470 {
2471 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
2472 }
2473 else
2474 {
2475 *params = 0;
2476 }
2477 break;
2478 case GL_RENDERBUFFER_DEPTH_SIZE:
2479 if (renderbuffer->isDepthbuffer())
2480 {
2481 *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
2482 }
2483 else
2484 {
2485 *params = 0;
2486 }
2487 break;
2488 case GL_RENDERBUFFER_STENCIL_SIZE:
2489 if (renderbuffer->isStencilbuffer())
2490 {
2491 *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
2492 }
2493 else
2494 {
2495 *params = 0;
2496 }
2497 break;
2498 default:
2499 return error(GL_INVALID_ENUM);
2500 }
2501 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002502 }
2503 catch(std::bad_alloc&)
2504 {
2505 return error(GL_OUT_OF_MEMORY);
2506 }
2507}
2508
2509void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2510{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002511 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002512
2513 try
2514 {
2515 gl::Context *context = gl::getContext();
2516
2517 if (context)
2518 {
2519 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002520
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002521 if (!shaderObject)
2522 {
2523 return error(GL_INVALID_VALUE);
2524 }
2525
2526 switch (pname)
2527 {
2528 case GL_SHADER_TYPE:
2529 *params = shaderObject->getType();
2530 return;
2531 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002532 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002533 return;
2534 case GL_COMPILE_STATUS:
2535 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2536 return;
2537 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002538 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002539 return;
2540 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002541 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002542 return;
2543 default:
2544 return error(GL_INVALID_ENUM);
2545 }
2546 }
2547 }
2548 catch(std::bad_alloc&)
2549 {
2550 return error(GL_OUT_OF_MEMORY);
2551 }
2552}
2553
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002554void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002555{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002556 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 +00002557 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002558
2559 try
2560 {
2561 if (bufsize < 0)
2562 {
2563 return error(GL_INVALID_VALUE);
2564 }
2565
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002566 gl::Context *context = gl::getContext();
2567
2568 if (context)
2569 {
2570 gl::Shader *shaderObject = context->getShader(shader);
2571
2572 if (!shaderObject)
2573 {
2574 return error(GL_INVALID_VALUE);
2575 }
2576
2577 shaderObject->getInfoLog(bufsize, length, infolog);
2578 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002579 }
2580 catch(std::bad_alloc&)
2581 {
2582 return error(GL_OUT_OF_MEMORY);
2583 }
2584}
2585
2586void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2587{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002588 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2589 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002590
2591 try
2592 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002593 switch (shadertype)
2594 {
2595 case GL_VERTEX_SHADER:
2596 case GL_FRAGMENT_SHADER:
2597 break;
2598 default:
2599 return error(GL_INVALID_ENUM);
2600 }
2601
2602 switch (precisiontype)
2603 {
2604 case GL_LOW_FLOAT:
2605 case GL_MEDIUM_FLOAT:
2606 case GL_HIGH_FLOAT:
2607 // Assume IEEE 754 precision
2608 range[0] = 127;
2609 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002610 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002611 break;
2612 case GL_LOW_INT:
2613 case GL_MEDIUM_INT:
2614 case GL_HIGH_INT:
2615 // Some (most) hardware only supports single-precision floating-point numbers,
2616 // which can accurately represent integers up to +/-16777216
2617 range[0] = 24;
2618 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002619 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002620 break;
2621 default:
2622 return error(GL_INVALID_ENUM);
2623 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002624 }
2625 catch(std::bad_alloc&)
2626 {
2627 return error(GL_OUT_OF_MEMORY);
2628 }
2629}
2630
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002631void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002632{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002633 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 +00002634 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002635
2636 try
2637 {
2638 if (bufsize < 0)
2639 {
2640 return error(GL_INVALID_VALUE);
2641 }
2642
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002643 gl::Context *context = gl::getContext();
2644
2645 if (context)
2646 {
2647 gl::Shader *shaderObject = context->getShader(shader);
2648
2649 if (!shaderObject)
2650 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002651 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002652 }
2653
2654 shaderObject->getSource(bufsize, length, source);
2655 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002656 }
2657 catch(std::bad_alloc&)
2658 {
2659 return error(GL_OUT_OF_MEMORY);
2660 }
2661}
2662
2663const GLubyte* __stdcall glGetString(GLenum name)
2664{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002665 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002666
2667 try
2668 {
2669 switch (name)
2670 {
2671 case GL_VENDOR:
2672 return (GLubyte*)"TransGaming Inc.";
2673 case GL_RENDERER:
2674 return (GLubyte*)"ANGLE";
2675 case GL_VERSION:
2676 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2677 case GL_SHADING_LANGUAGE_VERSION:
2678 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2679 case GL_EXTENSIONS:
2680 return (GLubyte*)"";
2681 default:
2682 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2683 }
2684 }
2685 catch(std::bad_alloc&)
2686 {
2687 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2688 }
2689
2690 return NULL;
2691}
2692
2693void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2694{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002695 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 +00002696
2697 try
2698 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002699 gl::Context *context = gl::getContext();
2700
2701 if (context)
2702 {
2703 gl::Texture *texture;
2704
2705 switch (target)
2706 {
2707 case GL_TEXTURE_2D:
2708 texture = context->getTexture2D();
2709 break;
2710 case GL_TEXTURE_CUBE_MAP:
2711 texture = context->getTextureCubeMap();
2712 break;
2713 default:
2714 return error(GL_INVALID_ENUM);
2715 }
2716
2717 switch (pname)
2718 {
2719 case GL_TEXTURE_MAG_FILTER:
2720 *params = (GLfloat)texture->getMagFilter();
2721 break;
2722 case GL_TEXTURE_MIN_FILTER:
2723 *params = (GLfloat)texture->getMinFilter();
2724 break;
2725 case GL_TEXTURE_WRAP_S:
2726 *params = (GLfloat)texture->getWrapS();
2727 break;
2728 case GL_TEXTURE_WRAP_T:
2729 *params = (GLfloat)texture->getWrapT();
2730 break;
2731 default:
2732 return error(GL_INVALID_ENUM);
2733 }
2734 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002735 }
2736 catch(std::bad_alloc&)
2737 {
2738 return error(GL_OUT_OF_MEMORY);
2739 }
2740}
2741
2742void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2743{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002744 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 +00002745
2746 try
2747 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002748 gl::Context *context = gl::getContext();
2749
2750 if (context)
2751 {
2752 gl::Texture *texture;
2753
2754 switch (target)
2755 {
2756 case GL_TEXTURE_2D:
2757 texture = context->getTexture2D();
2758 break;
2759 case GL_TEXTURE_CUBE_MAP:
2760 texture = context->getTextureCubeMap();
2761 break;
2762 default:
2763 return error(GL_INVALID_ENUM);
2764 }
2765
2766 switch (pname)
2767 {
2768 case GL_TEXTURE_MAG_FILTER:
2769 *params = texture->getMagFilter();
2770 break;
2771 case GL_TEXTURE_MIN_FILTER:
2772 *params = texture->getMinFilter();
2773 break;
2774 case GL_TEXTURE_WRAP_S:
2775 *params = texture->getWrapS();
2776 break;
2777 case GL_TEXTURE_WRAP_T:
2778 *params = texture->getWrapT();
2779 break;
2780 default:
2781 return error(GL_INVALID_ENUM);
2782 }
2783 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002784 }
2785 catch(std::bad_alloc&)
2786 {
2787 return error(GL_OUT_OF_MEMORY);
2788 }
2789}
2790
2791void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2792{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002793 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002794
2795 try
2796 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002797 gl::Context *context = gl::getContext();
2798
2799 if (context)
2800 {
2801 if (program == 0)
2802 {
2803 return error(GL_INVALID_VALUE);
2804 }
2805
2806 gl::Program *programObject = context->getProgram(program);
2807
2808 if (!programObject || !programObject->isLinked())
2809 {
2810 return error(GL_INVALID_OPERATION);
2811 }
2812
2813 if (!programObject->getUniformfv(location, params))
2814 {
2815 return error(GL_INVALID_OPERATION);
2816 }
2817 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002818 }
2819 catch(std::bad_alloc&)
2820 {
2821 return error(GL_OUT_OF_MEMORY);
2822 }
2823}
2824
2825void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2826{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002827 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002828
2829 try
2830 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002831 gl::Context *context = gl::getContext();
2832
2833 if (context)
2834 {
2835 if (program == 0)
2836 {
2837 return error(GL_INVALID_VALUE);
2838 }
2839
2840 gl::Program *programObject = context->getProgram(program);
2841
2842 if (!programObject || !programObject->isLinked())
2843 {
2844 return error(GL_INVALID_OPERATION);
2845 }
2846
2847 if (!programObject)
2848 {
2849 return error(GL_INVALID_OPERATION);
2850 }
2851
2852 if (!programObject->getUniformiv(location, params))
2853 {
2854 return error(GL_INVALID_OPERATION);
2855 }
2856 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002857 }
2858 catch(std::bad_alloc&)
2859 {
2860 return error(GL_OUT_OF_MEMORY);
2861 }
2862}
2863
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002864int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002865{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002866 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002867
2868 try
2869 {
2870 gl::Context *context = gl::getContext();
2871
2872 if (strstr(name, "gl_") == name)
2873 {
2874 return -1;
2875 }
2876
2877 if (context)
2878 {
2879 gl::Program *programObject = context->getProgram(program);
2880
2881 if (!programObject)
2882 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002883 if (context->getShader(program))
2884 {
2885 return error(GL_INVALID_OPERATION, -1);
2886 }
2887 else
2888 {
2889 return error(GL_INVALID_VALUE, -1);
2890 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002891 }
2892
2893 if (!programObject->isLinked())
2894 {
2895 return error(GL_INVALID_OPERATION, -1);
2896 }
2897
2898 return programObject->getUniformLocation(name);
2899 }
2900 }
2901 catch(std::bad_alloc&)
2902 {
2903 return error(GL_OUT_OF_MEMORY, -1);
2904 }
2905
2906 return -1;
2907}
2908
2909void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2910{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002911 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002912
2913 try
2914 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002915 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002916
daniel@transgaming.come0078962010-04-15 20:45:08 +00002917 if (context)
2918 {
2919 if (index >= gl::MAX_VERTEX_ATTRIBS)
2920 {
2921 return error(GL_INVALID_VALUE);
2922 }
2923
2924 switch (pname)
2925 {
2926 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2927 *params = (GLfloat)(context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2928 break;
2929 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2930 *params = (GLfloat)context->vertexAttribute[index].mSize;
2931 break;
2932 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2933 *params = (GLfloat)context->vertexAttribute[index].mStride;
2934 break;
2935 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2936 *params = (GLfloat)context->vertexAttribute[index].mType;
2937 break;
2938 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2939 *params = (GLfloat)(context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2940 break;
2941 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2942 *params = (GLfloat)context->vertexAttribute[index].mBoundBuffer;
2943 break;
2944 case GL_CURRENT_VERTEX_ATTRIB:
2945 for (int i = 0; i < 4; ++i)
2946 {
2947 params[i] = context->vertexAttribute[index].mCurrentValue[i];
2948 }
2949 break;
2950 default: return error(GL_INVALID_ENUM);
2951 }
2952 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002953 }
2954 catch(std::bad_alloc&)
2955 {
2956 return error(GL_OUT_OF_MEMORY);
2957 }
2958}
2959
2960void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2961{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002962 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002963
2964 try
2965 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002966 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002967
daniel@transgaming.come0078962010-04-15 20:45:08 +00002968 if (context)
2969 {
2970 if (index >= gl::MAX_VERTEX_ATTRIBS)
2971 {
2972 return error(GL_INVALID_VALUE);
2973 }
2974
2975 switch (pname)
2976 {
2977 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2978 *params = (context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2979 break;
2980 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2981 *params = context->vertexAttribute[index].mSize;
2982 break;
2983 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2984 *params = context->vertexAttribute[index].mStride;
2985 break;
2986 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2987 *params = context->vertexAttribute[index].mType;
2988 break;
2989 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2990 *params = (context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2991 break;
2992 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2993 *params = context->vertexAttribute[index].mBoundBuffer;
2994 break;
2995 case GL_CURRENT_VERTEX_ATTRIB:
2996 for (int i = 0; i < 4; ++i)
2997 {
2998 float currentValue = context->vertexAttribute[index].mCurrentValue[i];
2999 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3000 }
3001 break;
3002 default: return error(GL_INVALID_ENUM);
3003 }
3004 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003005 }
3006 catch(std::bad_alloc&)
3007 {
3008 return error(GL_OUT_OF_MEMORY);
3009 }
3010}
3011
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003012void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003013{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003014 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003015
3016 try
3017 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003018 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003019
daniel@transgaming.come0078962010-04-15 20:45:08 +00003020 if (context)
3021 {
3022 if (index >= gl::MAX_VERTEX_ATTRIBS)
3023 {
3024 return error(GL_INVALID_VALUE);
3025 }
3026
3027 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3028 {
3029 return error(GL_INVALID_ENUM);
3030 }
3031
3032 *pointer = const_cast<GLvoid*>(context->vertexAttribute[index].mPointer);
3033 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003034 }
3035 catch(std::bad_alloc&)
3036 {
3037 return error(GL_OUT_OF_MEMORY);
3038 }
3039}
3040
3041void __stdcall glHint(GLenum target, GLenum mode)
3042{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003043 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003044
3045 try
3046 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003047 switch (target)
3048 {
3049 case GL_GENERATE_MIPMAP_HINT:
3050 switch (mode)
3051 {
3052 case GL_FASTEST:
3053 case GL_NICEST:
3054 case GL_DONT_CARE:
3055 break;
3056 default:
3057 return error(GL_INVALID_ENUM);
3058 }
3059 break;
3060 default:
3061 return error(GL_INVALID_ENUM);
3062 }
3063
3064 gl::Context *context = gl::getContext();
3065 if (context)
3066 {
3067 if (target == GL_GENERATE_MIPMAP_HINT)
3068 context->generateMipmapHint = mode;
3069 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003070 }
3071 catch(std::bad_alloc&)
3072 {
3073 return error(GL_OUT_OF_MEMORY);
3074 }
3075}
3076
3077GLboolean __stdcall glIsBuffer(GLuint buffer)
3078{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003079 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003080
3081 try
3082 {
3083 gl::Context *context = gl::getContext();
3084
3085 if (context && buffer)
3086 {
3087 gl::Buffer *bufferObject = context->getBuffer(buffer);
3088
3089 if (bufferObject)
3090 {
3091 return GL_TRUE;
3092 }
3093 }
3094 }
3095 catch(std::bad_alloc&)
3096 {
3097 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3098 }
3099
3100 return GL_FALSE;
3101}
3102
3103GLboolean __stdcall glIsEnabled(GLenum cap)
3104{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003105 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003106
3107 try
3108 {
3109 gl::Context *context = gl::getContext();
3110
3111 if (context)
3112 {
3113 switch (cap)
3114 {
3115 case GL_CULL_FACE: return context->cullFace;
3116 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
3117 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
3118 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
3119 case GL_SCISSOR_TEST: return context->scissorTest;
3120 case GL_STENCIL_TEST: return context->stencilTest;
3121 case GL_DEPTH_TEST: return context->depthTest;
3122 case GL_BLEND: return context->blend;
3123 case GL_DITHER: return context->dither;
3124 default:
3125 return error(GL_INVALID_ENUM, false);
3126 }
3127 }
3128 }
3129 catch(std::bad_alloc&)
3130 {
3131 return error(GL_OUT_OF_MEMORY, false);
3132 }
3133
3134 return false;
3135}
3136
3137GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3138{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003139 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003140
3141 try
3142 {
3143 gl::Context *context = gl::getContext();
3144
3145 if (context && framebuffer)
3146 {
3147 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3148
3149 if (framebufferObject)
3150 {
3151 return GL_TRUE;
3152 }
3153 }
3154 }
3155 catch(std::bad_alloc&)
3156 {
3157 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3158 }
3159
3160 return GL_FALSE;
3161}
3162
3163GLboolean __stdcall glIsProgram(GLuint program)
3164{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003165 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003166
3167 try
3168 {
3169 gl::Context *context = gl::getContext();
3170
3171 if (context && program)
3172 {
3173 gl::Program *programObject = context->getProgram(program);
3174
3175 if (programObject)
3176 {
3177 return GL_TRUE;
3178 }
3179 }
3180 }
3181 catch(std::bad_alloc&)
3182 {
3183 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3184 }
3185
3186 return GL_FALSE;
3187}
3188
3189GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3190{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003191 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003192
3193 try
3194 {
3195 gl::Context *context = gl::getContext();
3196
3197 if (context && renderbuffer)
3198 {
3199 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3200
3201 if (renderbufferObject)
3202 {
3203 return GL_TRUE;
3204 }
3205 }
3206 }
3207 catch(std::bad_alloc&)
3208 {
3209 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3210 }
3211
3212 return GL_FALSE;
3213}
3214
3215GLboolean __stdcall glIsShader(GLuint shader)
3216{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003217 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003218
3219 try
3220 {
3221 gl::Context *context = gl::getContext();
3222
3223 if (context && shader)
3224 {
3225 gl::Shader *shaderObject = context->getShader(shader);
3226
3227 if (shaderObject)
3228 {
3229 return GL_TRUE;
3230 }
3231 }
3232 }
3233 catch(std::bad_alloc&)
3234 {
3235 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3236 }
3237
3238 return GL_FALSE;
3239}
3240
3241GLboolean __stdcall glIsTexture(GLuint texture)
3242{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003243 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003244
3245 try
3246 {
3247 gl::Context *context = gl::getContext();
3248
3249 if (context && texture)
3250 {
3251 gl::Texture *textureObject = context->getTexture(texture);
3252
3253 if (textureObject)
3254 {
3255 return GL_TRUE;
3256 }
3257 }
3258 }
3259 catch(std::bad_alloc&)
3260 {
3261 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3262 }
3263
3264 return GL_FALSE;
3265}
3266
3267void __stdcall glLineWidth(GLfloat width)
3268{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003269 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003270
3271 try
3272 {
3273 if (width <= 0.0f)
3274 {
3275 return error(GL_INVALID_VALUE);
3276 }
3277
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003278 gl::Context *context = gl::getContext();
3279
3280 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003281 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003282 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003283 }
3284 }
3285 catch(std::bad_alloc&)
3286 {
3287 return error(GL_OUT_OF_MEMORY);
3288 }
3289}
3290
3291void __stdcall glLinkProgram(GLuint program)
3292{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003293 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003294
3295 try
3296 {
3297 gl::Context *context = gl::getContext();
3298
3299 if (context)
3300 {
3301 gl::Program *programObject = context->getProgram(program);
3302
3303 if (!programObject)
3304 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003305 if (context->getShader(program))
3306 {
3307 return error(GL_INVALID_OPERATION);
3308 }
3309 else
3310 {
3311 return error(GL_INVALID_VALUE);
3312 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003313 }
3314
3315 programObject->link();
3316 }
3317 }
3318 catch(std::bad_alloc&)
3319 {
3320 return error(GL_OUT_OF_MEMORY);
3321 }
3322}
3323
3324void __stdcall glPixelStorei(GLenum pname, GLint param)
3325{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003326 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003327
3328 try
3329 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003330 gl::Context *context = gl::getContext();
3331
3332 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003333 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003334 switch (pname)
3335 {
3336 case GL_UNPACK_ALIGNMENT:
3337 if (param != 1 && param != 2 && param != 4 && param != 8)
3338 {
3339 return error(GL_INVALID_VALUE);
3340 }
3341
3342 context->unpackAlignment = param;
3343 break;
3344
3345 case GL_PACK_ALIGNMENT:
3346 if (param != 1 && param != 2 && param != 4 && param != 8)
3347 {
3348 return error(GL_INVALID_VALUE);
3349 }
3350
3351 context->packAlignment = param;
3352 break;
3353
3354 default:
3355 return error(GL_INVALID_ENUM);
3356 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003357 }
3358 }
3359 catch(std::bad_alloc&)
3360 {
3361 return error(GL_OUT_OF_MEMORY);
3362 }
3363}
3364
3365void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3366{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003367 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003368
3369 try
3370 {
3371 if (factor != 0.0f || units != 0.0f)
3372 {
3373 UNIMPLEMENTED(); // FIXME
3374 }
3375 }
3376 catch(std::bad_alloc&)
3377 {
3378 return error(GL_OUT_OF_MEMORY);
3379 }
3380}
3381
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003382void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003383{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003384 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003385 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003386 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003387
3388 try
3389 {
3390 if (width < 0 || height < 0)
3391 {
3392 return error(GL_INVALID_VALUE);
3393 }
3394
3395 switch (format)
3396 {
3397 case GL_RGBA:
3398 switch (type)
3399 {
3400 case GL_UNSIGNED_BYTE:
3401 break;
3402 default:
3403 return error(GL_INVALID_OPERATION);
3404 }
3405 break;
3406 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3407 switch (type)
3408 {
3409 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3410 break;
3411 default:
3412 return error(GL_INVALID_OPERATION);
3413 }
3414 break;
3415 default:
3416 return error(GL_INVALID_OPERATION);
3417 }
3418
3419 gl::Context *context = gl::getContext();
3420
3421 if (context)
3422 {
3423 context->readPixels(x, y, width, height, format, type, pixels);
3424 }
3425 }
3426 catch(std::bad_alloc&)
3427 {
3428 return error(GL_OUT_OF_MEMORY);
3429 }
3430}
3431
3432void __stdcall glReleaseShaderCompiler(void)
3433{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003434 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003435
3436 try
3437 {
3438 gl::Shader::releaseCompiler();
3439 }
3440 catch(std::bad_alloc&)
3441 {
3442 return error(GL_OUT_OF_MEMORY);
3443 }
3444}
3445
3446void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3447{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003448 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3449 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003450
3451 try
3452 {
3453 switch (target)
3454 {
3455 case GL_RENDERBUFFER:
3456 break;
3457 default:
3458 return error(GL_INVALID_ENUM);
3459 }
3460
3461 switch (internalformat)
3462 {
3463 case GL_DEPTH_COMPONENT16:
3464 case GL_RGBA4:
3465 case GL_RGB5_A1:
3466 case GL_RGB565:
3467 case GL_STENCIL_INDEX8:
3468 break;
3469 default:
3470 return error(GL_INVALID_ENUM);
3471 }
3472
3473 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3474 {
3475 return error(GL_INVALID_VALUE);
3476 }
3477
3478 gl::Context *context = gl::getContext();
3479
3480 if (context)
3481 {
3482 if (context->framebuffer == 0 || context->renderbuffer == 0)
3483 {
3484 return error(GL_INVALID_OPERATION);
3485 }
3486
3487 switch (internalformat)
3488 {
3489 case GL_DEPTH_COMPONENT16:
3490 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3491 break;
3492 case GL_RGBA4:
3493 case GL_RGB5_A1:
3494 case GL_RGB565:
daniel@transgaming.com70d312a2010-04-20 18:52:38 +00003495 context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003496 break;
3497 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003498 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003499 break;
3500 default:
3501 return error(GL_INVALID_ENUM);
3502 }
3503 }
3504 }
3505 catch(std::bad_alloc&)
3506 {
3507 return error(GL_OUT_OF_MEMORY);
3508 }
3509}
3510
3511void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3512{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003513 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003514
3515 try
3516 {
3517 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003518
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003519 if (context)
3520 {
3521 context->sampleCoverageValue = gl::clamp01(value);
3522 context->sampleCoverageInvert = invert;
3523 }
3524 }
3525 catch(std::bad_alloc&)
3526 {
3527 return error(GL_OUT_OF_MEMORY);
3528 }
3529}
3530
3531void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3532{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003533 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 +00003534
3535 try
3536 {
3537 if (width < 0 || height < 0)
3538 {
3539 return error(GL_INVALID_VALUE);
3540 }
3541
3542 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003543
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003544 if (context)
3545 {
3546 context->scissorX = x;
3547 context->scissorY = y;
3548 context->scissorWidth = width;
3549 context->scissorHeight = height;
3550 }
3551 }
3552 catch(std::bad_alloc&)
3553 {
3554 return error(GL_OUT_OF_MEMORY);
3555 }
3556}
3557
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003558void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003559{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003560 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003561 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003562 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003563
3564 try
3565 {
3566 if (n < 0 || length < 0)
3567 {
3568 return error(GL_INVALID_VALUE);
3569 }
3570
3571 UNIMPLEMENTED(); // FIXME
3572 }
3573 catch(std::bad_alloc&)
3574 {
3575 return error(GL_OUT_OF_MEMORY);
3576 }
3577}
3578
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003579void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003580{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003581 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 +00003582 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003583
3584 try
3585 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003586 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003587 {
3588 return error(GL_INVALID_VALUE);
3589 }
3590
3591 gl::Context *context = gl::getContext();
3592
3593 if (context)
3594 {
3595 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003596
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003597 if (!shaderObject)
3598 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003599 if (context->getProgram(shader))
3600 {
3601 return error(GL_INVALID_OPERATION);
3602 }
3603 else
3604 {
3605 return error(GL_INVALID_VALUE);
3606 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003607 }
3608
3609 shaderObject->setSource(count, string, length);
3610 }
3611 }
3612 catch(std::bad_alloc&)
3613 {
3614 return error(GL_OUT_OF_MEMORY);
3615 }
3616}
3617
3618void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3619{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003620 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003621}
3622
3623void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3624{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003625 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 +00003626
3627 try
3628 {
3629 switch (face)
3630 {
3631 case GL_FRONT:
3632 case GL_BACK:
3633 case GL_FRONT_AND_BACK:
3634 break;
3635 default:
3636 return error(GL_INVALID_ENUM);
3637 }
3638
3639 switch (func)
3640 {
3641 case GL_NEVER:
3642 case GL_ALWAYS:
3643 case GL_LESS:
3644 case GL_LEQUAL:
3645 case GL_EQUAL:
3646 case GL_GEQUAL:
3647 case GL_GREATER:
3648 case GL_NOTEQUAL:
3649 break;
3650 default:
3651 return error(GL_INVALID_ENUM);
3652 }
3653
3654 gl::Context *context = gl::getContext();
3655
3656 if (context)
3657 {
3658 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3659 {
3660 context->stencilFunc = func;
3661 context->stencilRef = ref;
3662 context->stencilMask = mask;
3663 }
3664
3665 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3666 {
3667 context->stencilBackFunc = func;
3668 context->stencilBackRef = ref;
3669 context->stencilBackMask = mask;
3670 }
3671 }
3672 }
3673 catch(std::bad_alloc&)
3674 {
3675 return error(GL_OUT_OF_MEMORY);
3676 }
3677}
3678
3679void __stdcall glStencilMask(GLuint mask)
3680{
3681 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3682}
3683
3684void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3685{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003686 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003687
3688 try
3689 {
3690 switch (face)
3691 {
3692 case GL_FRONT:
3693 case GL_BACK:
3694 case GL_FRONT_AND_BACK:
3695 break;
3696 default:
3697 return error(GL_INVALID_ENUM);
3698 }
3699
3700 gl::Context *context = gl::getContext();
3701
3702 if (context)
3703 {
3704 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3705 {
3706 context->stencilWritemask = mask;
3707 }
3708
3709 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3710 {
3711 context->stencilBackWritemask = mask;
3712 }
3713 }
3714 }
3715 catch(std::bad_alloc&)
3716 {
3717 return error(GL_OUT_OF_MEMORY);
3718 }
3719}
3720
3721void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3722{
3723 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3724}
3725
3726void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3727{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003728 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3729 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003730
3731 try
3732 {
3733 switch (face)
3734 {
3735 case GL_FRONT:
3736 case GL_BACK:
3737 case GL_FRONT_AND_BACK:
3738 break;
3739 default:
3740 return error(GL_INVALID_ENUM);
3741 }
3742
3743 switch (fail)
3744 {
3745 case GL_ZERO:
3746 case GL_KEEP:
3747 case GL_REPLACE:
3748 case GL_INCR:
3749 case GL_DECR:
3750 case GL_INVERT:
3751 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003752 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003753 break;
3754 default:
3755 return error(GL_INVALID_ENUM);
3756 }
3757
3758 switch (zfail)
3759 {
3760 case GL_ZERO:
3761 case GL_KEEP:
3762 case GL_REPLACE:
3763 case GL_INCR:
3764 case GL_DECR:
3765 case GL_INVERT:
3766 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003767 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003768 break;
3769 default:
3770 return error(GL_INVALID_ENUM);
3771 }
3772
3773 switch (zpass)
3774 {
3775 case GL_ZERO:
3776 case GL_KEEP:
3777 case GL_REPLACE:
3778 case GL_INCR:
3779 case GL_DECR:
3780 case GL_INVERT:
3781 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003782 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003783 break;
3784 default:
3785 return error(GL_INVALID_ENUM);
3786 }
3787
3788 gl::Context *context = gl::getContext();
3789
3790 if (context)
3791 {
3792 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3793 {
3794 context->stencilFail = fail;
3795 context->stencilPassDepthFail = zfail;
3796 context->stencilPassDepthPass = zpass;
3797 }
3798
3799 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3800 {
3801 context->stencilBackFail = fail;
3802 context->stencilBackPassDepthFail = zfail;
3803 context->stencilBackPassDepthPass = zpass;
3804 }
3805 }
3806 }
3807 catch(std::bad_alloc&)
3808 {
3809 return error(GL_OUT_OF_MEMORY);
3810 }
3811}
3812
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003813void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3814 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003815{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003816 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 +00003817 "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 +00003818 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003819
3820 try
3821 {
3822 if (level < 0 || width < 0 || height < 0)
3823 {
3824 return error(GL_INVALID_VALUE);
3825 }
3826
3827 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3828 {
3829 return error(GL_INVALID_VALUE);
3830 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003831
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003832 switch (target)
3833 {
3834 case GL_TEXTURE_2D:
3835 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3836 {
3837 return error(GL_INVALID_VALUE);
3838 }
3839 break;
3840 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3841 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3842 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3843 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3844 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3845 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003846 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003847 {
3848 return error(GL_INVALID_VALUE);
3849 }
3850
3851 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3852 {
3853 return error(GL_INVALID_VALUE);
3854 }
3855 break;
3856 default:
3857 return error(GL_INVALID_ENUM);
3858 }
3859
3860 if (internalformat != format)
3861 {
3862 return error(GL_INVALID_OPERATION);
3863 }
3864
3865 switch (internalformat)
3866 {
3867 case GL_ALPHA:
3868 case GL_LUMINANCE:
3869 case GL_LUMINANCE_ALPHA:
3870 switch (type)
3871 {
3872 case GL_UNSIGNED_BYTE:
3873 break;
3874 default:
3875 return error(GL_INVALID_ENUM);
3876 }
3877 break;
3878 case GL_RGB:
3879 switch (type)
3880 {
3881 case GL_UNSIGNED_BYTE:
3882 case GL_UNSIGNED_SHORT_5_6_5:
3883 break;
3884 default:
3885 return error(GL_INVALID_ENUM);
3886 }
3887 break;
3888 case GL_RGBA:
3889 switch (type)
3890 {
3891 case GL_UNSIGNED_BYTE:
3892 case GL_UNSIGNED_SHORT_4_4_4_4:
3893 case GL_UNSIGNED_SHORT_5_5_5_1:
3894 break;
3895 default:
3896 return error(GL_INVALID_ENUM);
3897 }
3898 break;
3899 default:
3900 return error(GL_INVALID_VALUE);
3901 }
3902
3903 if (border != 0)
3904 {
3905 return error(GL_INVALID_VALUE);
3906 }
3907
3908 gl::Context *context = gl::getContext();
3909
3910 if (context)
3911 {
3912 if (target == GL_TEXTURE_2D)
3913 {
3914 gl::Texture2D *texture = context->getTexture2D();
3915
3916 if (!texture)
3917 {
3918 return error(GL_INVALID_OPERATION);
3919 }
3920
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003921 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003922 }
3923 else
3924 {
3925 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3926
3927 if (!texture)
3928 {
3929 return error(GL_INVALID_OPERATION);
3930 }
3931
3932 switch (target)
3933 {
3934 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003935 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003936 break;
3937 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003938 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003939 break;
3940 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003941 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003942 break;
3943 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003944 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003945 break;
3946 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003947 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003948 break;
3949 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003950 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003951 break;
3952 default: UNREACHABLE();
3953 }
3954 }
3955 }
3956 }
3957 catch(std::bad_alloc&)
3958 {
3959 return error(GL_OUT_OF_MEMORY);
3960 }
3961}
3962
3963void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3964{
3965 glTexParameteri(target, pname, (GLint)param);
3966}
3967
3968void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3969{
3970 glTexParameteri(target, pname, (GLint)*params);
3971}
3972
3973void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3974{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003975 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003976
3977 try
3978 {
3979 gl::Context *context = gl::getContext();
3980
3981 if (context)
3982 {
3983 gl::Texture *texture;
3984
3985 switch (target)
3986 {
3987 case GL_TEXTURE_2D:
3988 texture = context->getTexture2D();
3989 break;
3990 case GL_TEXTURE_CUBE_MAP:
3991 texture = context->getTextureCubeMap();
3992 break;
3993 default:
3994 return error(GL_INVALID_ENUM);
3995 }
3996
3997 switch (pname)
3998 {
3999 case GL_TEXTURE_WRAP_S:
4000 if (!texture->setWrapS((GLenum)param))
4001 {
4002 return error(GL_INVALID_ENUM);
4003 }
4004 break;
4005 case GL_TEXTURE_WRAP_T:
4006 if (!texture->setWrapT((GLenum)param))
4007 {
4008 return error(GL_INVALID_ENUM);
4009 }
4010 break;
4011 case GL_TEXTURE_MIN_FILTER:
4012 if (!texture->setMinFilter((GLenum)param))
4013 {
4014 return error(GL_INVALID_ENUM);
4015 }
4016 break;
4017 case GL_TEXTURE_MAG_FILTER:
4018 if (!texture->setMagFilter((GLenum)param))
4019 {
4020 return error(GL_INVALID_ENUM);
4021 }
4022 break;
4023 default:
4024 return error(GL_INVALID_ENUM);
4025 }
4026 }
4027 }
4028 catch(std::bad_alloc&)
4029 {
4030 return error(GL_OUT_OF_MEMORY);
4031 }
4032}
4033
4034void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4035{
4036 glTexParameteri(target, pname, *params);
4037}
4038
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004039void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4040 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004041{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004042 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4043 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004044 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004045 target, level, xoffset, yoffset, width, height, format, type, pixels);
4046
4047 try
4048 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004049 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
4050 {
4051 return error(GL_INVALID_ENUM);
4052 }
4053
4054 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004055 {
4056 return error(GL_INVALID_VALUE);
4057 }
4058
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004059 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4060 {
4061 return error(GL_INVALID_VALUE);
4062 }
4063
4064 if (!es2dx::CheckTextureFormatType(format, type))
4065 {
4066 return error(GL_INVALID_ENUM);
4067 }
4068
4069 if (width == 0 || height == 0 || pixels == NULL)
4070 {
4071 return;
4072 }
4073
4074 gl::Context *context = gl::getContext();
4075
4076 if (context)
4077 {
4078 if (target == GL_TEXTURE_2D)
4079 {
4080 gl::Texture2D *texture = context->getTexture2D();
4081
4082 if (!texture)
4083 {
4084 return error(GL_INVALID_OPERATION);
4085 }
4086
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004087 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004088 }
4089 else if (es2dx::IsCubemapTextureTarget(target))
4090 {
4091 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4092
4093 if (!texture)
4094 {
4095 return error(GL_INVALID_OPERATION);
4096 }
4097
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004098 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004099 }
4100 else
4101 {
4102 UNREACHABLE();
4103 }
4104 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004105 }
4106 catch(std::bad_alloc&)
4107 {
4108 return error(GL_OUT_OF_MEMORY);
4109 }
4110}
4111
4112void __stdcall glUniform1f(GLint location, GLfloat x)
4113{
4114 glUniform1fv(location, 1, &x);
4115}
4116
4117void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4118{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004119 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004120
4121 try
4122 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004123 if (count < 0)
4124 {
4125 return error(GL_INVALID_VALUE);
4126 }
4127
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004128 if (location == -1)
4129 {
4130 return;
4131 }
4132
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004133 gl::Context *context = gl::getContext();
4134
4135 if (context)
4136 {
4137 gl::Program *program = context->getCurrentProgram();
4138
4139 if (!program)
4140 {
4141 return error(GL_INVALID_OPERATION);
4142 }
4143
4144 if (!program->setUniform1fv(location, count, v))
4145 {
4146 return error(GL_INVALID_OPERATION);
4147 }
4148 }
4149 }
4150 catch(std::bad_alloc&)
4151 {
4152 return error(GL_OUT_OF_MEMORY);
4153 }
4154}
4155
4156void __stdcall glUniform1i(GLint location, GLint x)
4157{
4158 glUniform1iv(location, 1, &x);
4159}
4160
4161void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4162{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004163 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004164
4165 try
4166 {
4167 if (count < 0)
4168 {
4169 return error(GL_INVALID_VALUE);
4170 }
4171
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004172 if (location == -1)
4173 {
4174 return;
4175 }
4176
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004177 gl::Context *context = gl::getContext();
4178
4179 if (context)
4180 {
4181 gl::Program *program = context->getCurrentProgram();
4182
4183 if (!program)
4184 {
4185 return error(GL_INVALID_OPERATION);
4186 }
4187
4188 if (!program->setUniform1iv(location, count, v))
4189 {
4190 return error(GL_INVALID_OPERATION);
4191 }
4192 }
4193 }
4194 catch(std::bad_alloc&)
4195 {
4196 return error(GL_OUT_OF_MEMORY);
4197 }
4198}
4199
4200void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4201{
4202 GLfloat xy[2] = {x, y};
4203
4204 glUniform2fv(location, 1, (GLfloat*)&xy);
4205}
4206
4207void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4208{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004209 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004210
4211 try
4212 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004213 if (count < 0)
4214 {
4215 return error(GL_INVALID_VALUE);
4216 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004217
4218 if (location == -1)
4219 {
4220 return;
4221 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004222
4223 gl::Context *context = gl::getContext();
4224
4225 if (context)
4226 {
4227 gl::Program *program = context->getCurrentProgram();
4228
4229 if (!program)
4230 {
4231 return error(GL_INVALID_OPERATION);
4232 }
4233
4234 if (!program->setUniform2fv(location, count, v))
4235 {
4236 return error(GL_INVALID_OPERATION);
4237 }
4238 }
4239 }
4240 catch(std::bad_alloc&)
4241 {
4242 return error(GL_OUT_OF_MEMORY);
4243 }
4244}
4245
4246void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4247{
4248 GLint xy[4] = {x, y};
4249
4250 glUniform2iv(location, 1, (GLint*)&xy);
4251}
4252
4253void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4254{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004255 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004256
4257 try
4258 {
4259 if (count < 0)
4260 {
4261 return error(GL_INVALID_VALUE);
4262 }
4263
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004264 if (location == -1)
4265 {
4266 return;
4267 }
4268
4269 gl::Context *context = gl::getContext();
4270
4271 if (context)
4272 {
4273 gl::Program *program = context->getCurrentProgram();
4274
4275 if (!program)
4276 {
4277 return error(GL_INVALID_OPERATION);
4278 }
4279
4280 if (!program->setUniform2iv(location, count, v))
4281 {
4282 return error(GL_INVALID_OPERATION);
4283 }
4284 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004285 }
4286 catch(std::bad_alloc&)
4287 {
4288 return error(GL_OUT_OF_MEMORY);
4289 }
4290}
4291
4292void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4293{
4294 GLfloat xyz[3] = {x, y, z};
4295
4296 glUniform3fv(location, 1, (GLfloat*)&xyz);
4297}
4298
4299void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4300{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004301 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004302
4303 try
4304 {
4305 if (count < 0)
4306 {
4307 return error(GL_INVALID_VALUE);
4308 }
4309
4310 if (location == -1)
4311 {
4312 return;
4313 }
4314
4315 gl::Context *context = gl::getContext();
4316
4317 if (context)
4318 {
4319 gl::Program *program = context->getCurrentProgram();
4320
4321 if (!program)
4322 {
4323 return error(GL_INVALID_OPERATION);
4324 }
4325
4326 if (!program->setUniform3fv(location, count, v))
4327 {
4328 return error(GL_INVALID_OPERATION);
4329 }
4330 }
4331 }
4332 catch(std::bad_alloc&)
4333 {
4334 return error(GL_OUT_OF_MEMORY);
4335 }
4336}
4337
4338void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4339{
4340 GLint xyz[3] = {x, y, z};
4341
4342 glUniform3iv(location, 1, (GLint*)&xyz);
4343}
4344
4345void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4346{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004347 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004348
4349 try
4350 {
4351 if (count < 0)
4352 {
4353 return error(GL_INVALID_VALUE);
4354 }
4355
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004356 if (location == -1)
4357 {
4358 return;
4359 }
4360
4361 gl::Context *context = gl::getContext();
4362
4363 if (context)
4364 {
4365 gl::Program *program = context->getCurrentProgram();
4366
4367 if (!program)
4368 {
4369 return error(GL_INVALID_OPERATION);
4370 }
4371
4372 if (!program->setUniform3iv(location, count, v))
4373 {
4374 return error(GL_INVALID_OPERATION);
4375 }
4376 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004377 }
4378 catch(std::bad_alloc&)
4379 {
4380 return error(GL_OUT_OF_MEMORY);
4381 }
4382}
4383
4384void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4385{
4386 GLfloat xyzw[4] = {x, y, z, w};
4387
4388 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4389}
4390
4391void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4392{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004393 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004394
4395 try
4396 {
4397 if (count < 0)
4398 {
4399 return error(GL_INVALID_VALUE);
4400 }
4401
4402 if (location == -1)
4403 {
4404 return;
4405 }
4406
4407 gl::Context *context = gl::getContext();
4408
4409 if (context)
4410 {
4411 gl::Program *program = context->getCurrentProgram();
4412
4413 if (!program)
4414 {
4415 return error(GL_INVALID_OPERATION);
4416 }
4417
4418 if (!program->setUniform4fv(location, count, v))
4419 {
4420 return error(GL_INVALID_OPERATION);
4421 }
4422 }
4423 }
4424 catch(std::bad_alloc&)
4425 {
4426 return error(GL_OUT_OF_MEMORY);
4427 }
4428}
4429
4430void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4431{
4432 GLint xyzw[4] = {x, y, z, w};
4433
4434 glUniform4iv(location, 1, (GLint*)&xyzw);
4435}
4436
4437void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4438{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004439 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004440
4441 try
4442 {
4443 if (count < 0)
4444 {
4445 return error(GL_INVALID_VALUE);
4446 }
4447
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004448 if (location == -1)
4449 {
4450 return;
4451 }
4452
4453 gl::Context *context = gl::getContext();
4454
4455 if (context)
4456 {
4457 gl::Program *program = context->getCurrentProgram();
4458
4459 if (!program)
4460 {
4461 return error(GL_INVALID_OPERATION);
4462 }
4463
4464 if (!program->setUniform4iv(location, count, v))
4465 {
4466 return error(GL_INVALID_OPERATION);
4467 }
4468 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004469 }
4470 catch(std::bad_alloc&)
4471 {
4472 return error(GL_OUT_OF_MEMORY);
4473 }
4474}
4475
4476void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4477{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004478 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4479 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004480
4481 try
4482 {
4483 if (count < 0 || transpose != GL_FALSE)
4484 {
4485 return error(GL_INVALID_VALUE);
4486 }
4487
4488 if (location == -1)
4489 {
4490 return;
4491 }
4492
4493 gl::Context *context = gl::getContext();
4494
4495 if (context)
4496 {
4497 gl::Program *program = context->getCurrentProgram();
4498
4499 if (!program)
4500 {
4501 return error(GL_INVALID_OPERATION);
4502 }
4503
4504 if (!program->setUniformMatrix2fv(location, count, value))
4505 {
4506 return error(GL_INVALID_OPERATION);
4507 }
4508 }
4509 }
4510 catch(std::bad_alloc&)
4511 {
4512 return error(GL_OUT_OF_MEMORY);
4513 }
4514}
4515
4516void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4517{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004518 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4519 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004520
4521 try
4522 {
4523 if (count < 0 || transpose != GL_FALSE)
4524 {
4525 return error(GL_INVALID_VALUE);
4526 }
4527
4528 if (location == -1)
4529 {
4530 return;
4531 }
4532
4533 gl::Context *context = gl::getContext();
4534
4535 if (context)
4536 {
4537 gl::Program *program = context->getCurrentProgram();
4538
4539 if (!program)
4540 {
4541 return error(GL_INVALID_OPERATION);
4542 }
4543
4544 if (!program->setUniformMatrix3fv(location, count, value))
4545 {
4546 return error(GL_INVALID_OPERATION);
4547 }
4548 }
4549 }
4550 catch(std::bad_alloc&)
4551 {
4552 return error(GL_OUT_OF_MEMORY);
4553 }
4554}
4555
4556void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4557{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004558 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4559 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004560
4561 try
4562 {
4563 if (count < 0 || transpose != GL_FALSE)
4564 {
4565 return error(GL_INVALID_VALUE);
4566 }
4567
4568 if (location == -1)
4569 {
4570 return;
4571 }
4572
4573 gl::Context *context = gl::getContext();
4574
4575 if (context)
4576 {
4577 gl::Program *program = context->getCurrentProgram();
4578
4579 if (!program)
4580 {
4581 return error(GL_INVALID_OPERATION);
4582 }
4583
4584 if (!program->setUniformMatrix4fv(location, count, value))
4585 {
4586 return error(GL_INVALID_OPERATION);
4587 }
4588 }
4589 }
4590 catch(std::bad_alloc&)
4591 {
4592 return error(GL_OUT_OF_MEMORY);
4593 }
4594}
4595
4596void __stdcall glUseProgram(GLuint program)
4597{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004598 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004599
4600 try
4601 {
4602 gl::Context *context = gl::getContext();
4603
4604 if (context)
4605 {
4606 gl::Program *programObject = context->getProgram(program);
4607
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004608 if (!programObject && program != 0)
4609 {
4610 if (context->getShader(program))
4611 {
4612 return error(GL_INVALID_OPERATION);
4613 }
4614 else
4615 {
4616 return error(GL_INVALID_VALUE);
4617 }
4618 }
4619
4620 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004621 {
4622 return error(GL_INVALID_OPERATION);
4623 }
4624
4625 context->useProgram(program);
4626 }
4627 }
4628 catch(std::bad_alloc&)
4629 {
4630 return error(GL_OUT_OF_MEMORY);
4631 }
4632}
4633
4634void __stdcall glValidateProgram(GLuint program)
4635{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004636 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004637
4638 try
4639 {
4640 UNIMPLEMENTED(); // FIXME
4641 }
4642 catch(std::bad_alloc&)
4643 {
4644 return error(GL_OUT_OF_MEMORY);
4645 }
4646}
4647
4648void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004650 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004651
4652 try
4653 {
4654 if (index >= gl::MAX_VERTEX_ATTRIBS)
4655 {
4656 return error(GL_INVALID_VALUE);
4657 }
4658
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004659 gl::Context *context = gl::getContext();
4660
4661 if (context)
4662 {
4663 GLfloat vals[4] = { x, 0, 0, 1 };
4664 context->setVertexAttrib(index, vals);
4665 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004666 }
4667 catch(std::bad_alloc&)
4668 {
4669 return error(GL_OUT_OF_MEMORY);
4670 }
4671}
4672
4673void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4674{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004675 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004676
4677 try
4678 {
4679 if (index >= gl::MAX_VERTEX_ATTRIBS)
4680 {
4681 return error(GL_INVALID_VALUE);
4682 }
4683
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004684 gl::Context *context = gl::getContext();
4685
4686 if (context)
4687 {
4688 GLfloat vals[4] = { values[0], 0, 0, 1 };
4689 context->setVertexAttrib(index, vals);
4690 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004691 }
4692 catch(std::bad_alloc&)
4693 {
4694 return error(GL_OUT_OF_MEMORY);
4695 }
4696}
4697
4698void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4699{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004700 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004701
4702 try
4703 {
4704 if (index >= gl::MAX_VERTEX_ATTRIBS)
4705 {
4706 return error(GL_INVALID_VALUE);
4707 }
4708
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004709 gl::Context *context = gl::getContext();
4710
4711 if (context)
4712 {
4713 GLfloat vals[4] = { x, y, 0, 1 };
4714 context->setVertexAttrib(index, vals);
4715 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004716 }
4717 catch(std::bad_alloc&)
4718 {
4719 return error(GL_OUT_OF_MEMORY);
4720 }
4721}
4722
4723void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4724{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004725 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004726
4727 try
4728 {
4729 if (index >= gl::MAX_VERTEX_ATTRIBS)
4730 {
4731 return error(GL_INVALID_VALUE);
4732 }
4733
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004734 gl::Context *context = gl::getContext();
4735
4736 if (context)
4737 {
4738 GLfloat vals[4] = { values[0], values[1], 0, 1 };
4739 context->setVertexAttrib(index, vals);
4740 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004741 }
4742 catch(std::bad_alloc&)
4743 {
4744 return error(GL_OUT_OF_MEMORY);
4745 }
4746}
4747
4748void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4749{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004750 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 +00004751
4752 try
4753 {
4754 if (index >= gl::MAX_VERTEX_ATTRIBS)
4755 {
4756 return error(GL_INVALID_VALUE);
4757 }
4758
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004759 gl::Context *context = gl::getContext();
4760
4761 if (context)
4762 {
4763 GLfloat vals[4] = { x, y, z, 1 };
4764 context->setVertexAttrib(index, vals);
4765 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004766 }
4767 catch(std::bad_alloc&)
4768 {
4769 return error(GL_OUT_OF_MEMORY);
4770 }
4771}
4772
4773void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4774{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004775 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004776
4777 try
4778 {
4779 if (index >= gl::MAX_VERTEX_ATTRIBS)
4780 {
4781 return error(GL_INVALID_VALUE);
4782 }
4783
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004784 gl::Context *context = gl::getContext();
4785
4786 if (context)
4787 {
4788 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
4789 context->setVertexAttrib(index, vals);
4790 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004791 }
4792 catch(std::bad_alloc&)
4793 {
4794 return error(GL_OUT_OF_MEMORY);
4795 }
4796}
4797
4798void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4799{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004800 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 +00004801
4802 try
4803 {
4804 if (index >= gl::MAX_VERTEX_ATTRIBS)
4805 {
4806 return error(GL_INVALID_VALUE);
4807 }
4808
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004809 gl::Context *context = gl::getContext();
4810
4811 if (context)
4812 {
4813 GLfloat vals[4] = { x, y, z, w };
4814 context->setVertexAttrib(index, vals);
4815 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004816 }
4817 catch(std::bad_alloc&)
4818 {
4819 return error(GL_OUT_OF_MEMORY);
4820 }
4821}
4822
4823void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4824{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004825 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004826
4827 try
4828 {
4829 if (index >= gl::MAX_VERTEX_ATTRIBS)
4830 {
4831 return error(GL_INVALID_VALUE);
4832 }
4833
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004834 gl::Context *context = gl::getContext();
4835
4836 if (context)
4837 {
4838 context->setVertexAttrib(index, values);
4839 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004840 }
4841 catch(std::bad_alloc&)
4842 {
4843 return error(GL_OUT_OF_MEMORY);
4844 }
4845}
4846
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004847void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004848{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004849 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004850 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004851 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004852
4853 try
4854 {
4855 if (index >= gl::MAX_VERTEX_ATTRIBS)
4856 {
4857 return error(GL_INVALID_VALUE);
4858 }
4859
4860 if (size < 1 || size > 4)
4861 {
4862 return error(GL_INVALID_VALUE);
4863 }
4864
4865 switch (type)
4866 {
4867 case GL_BYTE:
4868 case GL_UNSIGNED_BYTE:
4869 case GL_SHORT:
4870 case GL_UNSIGNED_SHORT:
4871 case GL_FIXED:
4872 case GL_FLOAT:
4873 break;
4874 default:
4875 return error(GL_INVALID_ENUM);
4876 }
4877
4878 if (stride < 0)
4879 {
4880 return error(GL_INVALID_VALUE);
4881 }
4882
4883 gl::Context *context = gl::getContext();
4884
4885 if (context)
4886 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004887 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4888 context->vertexAttribute[index].mSize = size;
4889 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004890 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004891 context->vertexAttribute[index].mStride = stride;
4892 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004893 }
4894 }
4895 catch(std::bad_alloc&)
4896 {
4897 return error(GL_OUT_OF_MEMORY);
4898 }
4899}
4900
4901void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4902{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004903 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 +00004904
4905 try
4906 {
4907 if (width < 0 || height < 0)
4908 {
4909 return error(GL_INVALID_VALUE);
4910 }
4911
4912 gl::Context *context = gl::getContext();
4913
4914 if (context)
4915 {
4916 context->viewportX = x;
4917 context->viewportY = y;
4918 context->viewportWidth = width;
4919 context->viewportHeight = height;
4920 }
4921 }
4922 catch(std::bad_alloc&)
4923 {
4924 return error(GL_OUT_OF_MEMORY);
4925 }
4926}
4927
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004928void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4929 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004930{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004931 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4932 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004933 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004934 target, level, internalformat, width, height, depth, border, format, type, pixels);
4935
4936 try
4937 {
4938 UNIMPLEMENTED(); // FIXME
4939 }
4940 catch(std::bad_alloc&)
4941 {
4942 return error(GL_OUT_OF_MEMORY);
4943 }
4944}
4945}