blob: 9f70acec838817ae666eeefe2e6b336f0e8bd8b4 [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
1902 if (index >= programObject->getActiveAttributeCount())
1903 {
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
1929 UNIMPLEMENTED(); // FIXME
1930 }
1931 catch(std::bad_alloc&)
1932 {
1933 return error(GL_OUT_OF_MEMORY);
1934 }
1935}
1936
1937void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1938{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001939 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1940 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001941
1942 try
1943 {
1944 if (maxcount < 0)
1945 {
1946 return error(GL_INVALID_VALUE);
1947 }
1948
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001949 gl::Context *context = gl::getContext();
1950
1951 if (context)
1952 {
1953 gl::Program *programObject = context->getProgram(program);
1954
1955 if (!programObject)
1956 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001957 if (context->getShader(program))
1958 {
1959 return error(GL_INVALID_OPERATION);
1960 }
1961 else
1962 {
1963 return error(GL_INVALID_VALUE);
1964 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001965 }
1966
1967 return programObject->getAttachedShaders(maxcount, count, shaders);
1968 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001969 }
1970 catch(std::bad_alloc&)
1971 {
1972 return error(GL_OUT_OF_MEMORY);
1973 }
1974}
1975
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001976int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001977{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001978 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001979
1980 try
1981 {
1982 gl::Context *context = gl::getContext();
1983
1984 if (context)
1985 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001986
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001987 gl::Program *programObject = context->getProgram(program);
1988
1989 if (!programObject)
1990 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001991 if (context->getShader(program))
1992 {
1993 return error(GL_INVALID_OPERATION, -1);
1994 }
1995 else
1996 {
1997 return error(GL_INVALID_VALUE, -1);
1998 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001999 }
2000
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002001 if (!programObject->isLinked())
2002 {
2003 return error(GL_INVALID_OPERATION, -1);
2004 }
2005
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002006 return programObject->getAttributeLocation(name);
2007 }
2008 }
2009 catch(std::bad_alloc&)
2010 {
2011 return error(GL_OUT_OF_MEMORY, -1);
2012 }
2013
2014 return -1;
2015}
2016
2017void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2018{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002019 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002020
2021 try
2022 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002023 gl::Context *context = gl::getContext();
2024
2025 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002026 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002027 if (!(context->getBooleanv(pname, params)))
2028 {
2029 GLenum nativeType;
2030 unsigned int numParams = 0;
2031 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2032 return error(GL_INVALID_ENUM);
2033
2034 if (numParams == 0)
2035 return; // it is known that the pname is valid, but there are no parameters to return
2036
2037 if (nativeType == GL_FLOAT)
2038 {
2039 GLfloat *floatParams = NULL;
2040 floatParams = new GLfloat[numParams];
2041
2042 context->getFloatv(pname, floatParams);
2043
2044 for (unsigned int i = 0; i < numParams; ++i)
2045 {
2046 if (floatParams[i] == 0.0f)
2047 params[i] = GL_FALSE;
2048 else
2049 params[i] = GL_TRUE;
2050 }
2051
2052 delete [] floatParams;
2053 }
2054 else if (nativeType == GL_INT)
2055 {
2056 GLint *intParams = NULL;
2057 intParams = new GLint[numParams];
2058
2059 context->getIntegerv(pname, intParams);
2060
2061 for (unsigned int i = 0; i < numParams; ++i)
2062 {
2063 if (intParams[i] == 0)
2064 params[i] = GL_FALSE;
2065 else
2066 params[i] = GL_TRUE;
2067 }
2068
2069 delete [] intParams;
2070 }
2071 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002072 }
2073 }
2074 catch(std::bad_alloc&)
2075 {
2076 return error(GL_OUT_OF_MEMORY);
2077 }
2078}
2079
2080void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2081{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002082 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 +00002083
2084 try
2085 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002086 gl::Context *context = gl::getContext();
2087
2088 if (context)
2089 {
2090 gl::Buffer *buffer;
2091
2092 switch (target)
2093 {
2094 case GL_ARRAY_BUFFER:
2095 buffer = context->getArrayBuffer();
2096 break;
2097 case GL_ELEMENT_ARRAY_BUFFER:
2098 buffer = context->getElementArrayBuffer();
2099 break;
2100 default: return error(GL_INVALID_ENUM);
2101 }
2102
2103 if (!buffer)
2104 {
2105 // A null buffer means that "0" is bound to the requested buffer target
2106 return error(GL_INVALID_OPERATION);
2107 }
2108
2109 switch (pname)
2110 {
2111 case GL_BUFFER_USAGE:
2112 *params = buffer->usage();
2113 break;
2114 case GL_BUFFER_SIZE:
2115 *params = buffer->size();
2116 break;
2117 default: return error(GL_INVALID_ENUM);
2118 }
2119 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002120 }
2121 catch(std::bad_alloc&)
2122 {
2123 return error(GL_OUT_OF_MEMORY);
2124 }
2125}
2126
2127GLenum __stdcall glGetError(void)
2128{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002129 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002130
2131 gl::Context *context = gl::getContext();
2132
2133 if (context)
2134 {
2135 return context->getError();
2136 }
2137
2138 return GL_NO_ERROR;
2139}
2140
2141void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2142{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002143 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002144
2145 try
2146 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002147 gl::Context *context = gl::getContext();
2148
2149 if (context)
2150 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002151 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002152 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002153 GLenum nativeType;
2154 unsigned int numParams = 0;
2155 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2156 return error(GL_INVALID_ENUM);
2157
2158 if (numParams == 0)
2159 return; // it is known that the pname is valid, but that there are no parameters to return.
2160
2161 if (nativeType == GL_BOOL)
2162 {
2163 GLboolean *boolParams = NULL;
2164 boolParams = new GLboolean[numParams];
2165
2166 context->getBooleanv(pname, boolParams);
2167
2168 for (unsigned int i = 0; i < numParams; ++i)
2169 {
2170 if (boolParams[i] == GL_FALSE)
2171 params[i] = 0.0f;
2172 else
2173 params[i] = 1.0f;
2174 }
2175
2176 delete [] boolParams;
2177 }
2178 else if (nativeType == GL_INT)
2179 {
2180 GLint *intParams = NULL;
2181 intParams = new GLint[numParams];
2182
2183 context->getIntegerv(pname, intParams);
2184
2185 for (unsigned int i = 0; i < numParams; ++i)
2186 {
2187 params[i] = (GLfloat)intParams[i];
2188 }
2189
2190 delete [] intParams;
2191 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002192 }
2193 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002194 }
2195 catch(std::bad_alloc&)
2196 {
2197 return error(GL_OUT_OF_MEMORY);
2198 }
2199}
2200
2201void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2202{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002203 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2204 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002205
2206 try
2207 {
2208 gl::Context *context = gl::getContext();
2209
2210 if (context)
2211 {
2212 if (context->framebuffer == 0)
2213 {
2214 return error(GL_INVALID_OPERATION);
2215 }
2216
2217 UNIMPLEMENTED(); // FIXME
2218 }
2219 }
2220 catch(std::bad_alloc&)
2221 {
2222 return error(GL_OUT_OF_MEMORY);
2223 }
2224}
2225
2226void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2227{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002228 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", 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 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002236 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002237 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002238 GLenum nativeType;
2239 unsigned int numParams = 0;
2240 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2241 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002242
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002243 if (numParams == 0)
2244 return; // it is known that pname is valid, but there are no parameters to return
2245
2246 if (nativeType == GL_BOOL)
2247 {
2248 GLboolean *boolParams = NULL;
2249 boolParams = new GLboolean[numParams];
2250
2251 context->getBooleanv(pname, boolParams);
2252
2253 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002254 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002255 if (boolParams[i] == GL_FALSE)
2256 params[i] = 0;
2257 else
2258 params[i] = 1;
2259 }
2260
2261 delete [] boolParams;
2262 }
2263 else if (nativeType == GL_FLOAT)
2264 {
2265 GLfloat *floatParams = NULL;
2266 floatParams = new GLfloat[numParams];
2267
2268 context->getFloatv(pname, floatParams);
2269
2270 for (unsigned int i = 0; i < numParams; ++i)
2271 {
2272 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002273 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002274 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002275 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002276 else
2277 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 +00002278 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002279
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002280 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002281 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002282 }
2283 }
2284 }
2285 catch(std::bad_alloc&)
2286 {
2287 return error(GL_OUT_OF_MEMORY);
2288 }
2289}
2290
2291void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2292{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002293 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002294
2295 try
2296 {
2297 gl::Context *context = gl::getContext();
2298
2299 if (context)
2300 {
2301 gl::Program *programObject = context->getProgram(program);
2302
2303 if (!programObject)
2304 {
2305 return error(GL_INVALID_VALUE);
2306 }
2307
2308 switch (pname)
2309 {
2310 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002311 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002312 return;
2313 case GL_LINK_STATUS:
2314 *params = programObject->isLinked();
2315 return;
2316 case GL_VALIDATE_STATUS:
2317 UNIMPLEMENTED(); // FIXME
2318 *params = GL_TRUE;
2319 return;
2320 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002321 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002322 return;
2323 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002324 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002325 return;
2326 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002327 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002328 return;
2329 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002330 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002331 return;
2332 case GL_ACTIVE_UNIFORMS:
2333 UNIMPLEMENTED(); // FIXME
2334 *params = 0;
2335 return;
2336 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2337 UNIMPLEMENTED(); // FIXME
2338 *params = 0;
2339 return;
2340 default:
2341 return error(GL_INVALID_ENUM);
2342 }
2343 }
2344 }
2345 catch(std::bad_alloc&)
2346 {
2347 return error(GL_OUT_OF_MEMORY);
2348 }
2349}
2350
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002351void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002352{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002353 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 +00002354 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002355
2356 try
2357 {
2358 if (bufsize < 0)
2359 {
2360 return error(GL_INVALID_VALUE);
2361 }
2362
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002363 gl::Context *context = gl::getContext();
2364
2365 if (context)
2366 {
2367 gl::Program *programObject = context->getProgram(program);
2368
2369 if (!programObject)
2370 {
2371 return error(GL_INVALID_VALUE);
2372 }
2373
2374 programObject->getInfoLog(bufsize, length, infolog);
2375 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002376 }
2377 catch(std::bad_alloc&)
2378 {
2379 return error(GL_OUT_OF_MEMORY);
2380 }
2381}
2382
2383void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2384{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002385 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 +00002386
2387 try
2388 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002389 gl::Context *context = gl::getContext();
2390
2391 if (context)
2392 {
2393 if (target != GL_RENDERBUFFER)
2394 {
2395 return error(GL_INVALID_ENUM);
2396 }
2397
2398 if (context->renderbuffer == 0)
2399 {
2400 return error(GL_INVALID_OPERATION);
2401 }
2402
2403 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->renderbuffer);
2404
2405 switch (pname)
2406 {
2407 case GL_RENDERBUFFER_WIDTH:
2408 *params = renderbuffer->getWidth();
2409 break;
2410 case GL_RENDERBUFFER_HEIGHT:
2411 *params = renderbuffer->getHeight();
2412 break;
2413 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2414 *params = renderbuffer->getFormat();
2415 break;
2416 case GL_RENDERBUFFER_RED_SIZE:
2417 if (renderbuffer->isColorbuffer())
2418 {
2419 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
2420 }
2421 else
2422 {
2423 *params = 0;
2424 }
2425 break;
2426 case GL_RENDERBUFFER_GREEN_SIZE:
2427 if (renderbuffer->isColorbuffer())
2428 {
2429 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
2430 }
2431 else
2432 {
2433 *params = 0;
2434 }
2435 break;
2436 case GL_RENDERBUFFER_BLUE_SIZE:
2437 if (renderbuffer->isColorbuffer())
2438 {
2439 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
2440 }
2441 else
2442 {
2443 *params = 0;
2444 }
2445 break;
2446 case GL_RENDERBUFFER_ALPHA_SIZE:
2447 if (renderbuffer->isColorbuffer())
2448 {
2449 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
2450 }
2451 else
2452 {
2453 *params = 0;
2454 }
2455 break;
2456 case GL_RENDERBUFFER_DEPTH_SIZE:
2457 if (renderbuffer->isDepthbuffer())
2458 {
2459 *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
2460 }
2461 else
2462 {
2463 *params = 0;
2464 }
2465 break;
2466 case GL_RENDERBUFFER_STENCIL_SIZE:
2467 if (renderbuffer->isStencilbuffer())
2468 {
2469 *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
2470 }
2471 else
2472 {
2473 *params = 0;
2474 }
2475 break;
2476 default:
2477 return error(GL_INVALID_ENUM);
2478 }
2479 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002480 }
2481 catch(std::bad_alloc&)
2482 {
2483 return error(GL_OUT_OF_MEMORY);
2484 }
2485}
2486
2487void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2488{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002489 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002490
2491 try
2492 {
2493 gl::Context *context = gl::getContext();
2494
2495 if (context)
2496 {
2497 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002498
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002499 if (!shaderObject)
2500 {
2501 return error(GL_INVALID_VALUE);
2502 }
2503
2504 switch (pname)
2505 {
2506 case GL_SHADER_TYPE:
2507 *params = shaderObject->getType();
2508 return;
2509 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002510 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002511 return;
2512 case GL_COMPILE_STATUS:
2513 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2514 return;
2515 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002516 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002517 return;
2518 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002519 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002520 return;
2521 default:
2522 return error(GL_INVALID_ENUM);
2523 }
2524 }
2525 }
2526 catch(std::bad_alloc&)
2527 {
2528 return error(GL_OUT_OF_MEMORY);
2529 }
2530}
2531
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002532void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002533{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002534 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 +00002535 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002536
2537 try
2538 {
2539 if (bufsize < 0)
2540 {
2541 return error(GL_INVALID_VALUE);
2542 }
2543
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002544 gl::Context *context = gl::getContext();
2545
2546 if (context)
2547 {
2548 gl::Shader *shaderObject = context->getShader(shader);
2549
2550 if (!shaderObject)
2551 {
2552 return error(GL_INVALID_VALUE);
2553 }
2554
2555 shaderObject->getInfoLog(bufsize, length, infolog);
2556 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002557 }
2558 catch(std::bad_alloc&)
2559 {
2560 return error(GL_OUT_OF_MEMORY);
2561 }
2562}
2563
2564void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2565{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002566 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2567 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002568
2569 try
2570 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002571 switch (shadertype)
2572 {
2573 case GL_VERTEX_SHADER:
2574 case GL_FRAGMENT_SHADER:
2575 break;
2576 default:
2577 return error(GL_INVALID_ENUM);
2578 }
2579
2580 switch (precisiontype)
2581 {
2582 case GL_LOW_FLOAT:
2583 case GL_MEDIUM_FLOAT:
2584 case GL_HIGH_FLOAT:
2585 // Assume IEEE 754 precision
2586 range[0] = 127;
2587 range[1] = 127;
2588 precision[0] = 23;
2589 precision[1] = 23;
2590 break;
2591 case GL_LOW_INT:
2592 case GL_MEDIUM_INT:
2593 case GL_HIGH_INT:
2594 // Some (most) hardware only supports single-precision floating-point numbers,
2595 // which can accurately represent integers up to +/-16777216
2596 range[0] = 24;
2597 range[1] = 24;
2598 precision[0] = 0;
2599 precision[1] = 0;
2600 break;
2601 default:
2602 return error(GL_INVALID_ENUM);
2603 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002604 }
2605 catch(std::bad_alloc&)
2606 {
2607 return error(GL_OUT_OF_MEMORY);
2608 }
2609}
2610
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002611void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002612{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002613 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 +00002614 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002615
2616 try
2617 {
2618 if (bufsize < 0)
2619 {
2620 return error(GL_INVALID_VALUE);
2621 }
2622
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002623 gl::Context *context = gl::getContext();
2624
2625 if (context)
2626 {
2627 gl::Shader *shaderObject = context->getShader(shader);
2628
2629 if (!shaderObject)
2630 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002631 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002632 }
2633
2634 shaderObject->getSource(bufsize, length, source);
2635 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002636 }
2637 catch(std::bad_alloc&)
2638 {
2639 return error(GL_OUT_OF_MEMORY);
2640 }
2641}
2642
2643const GLubyte* __stdcall glGetString(GLenum name)
2644{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002645 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002646
2647 try
2648 {
2649 switch (name)
2650 {
2651 case GL_VENDOR:
2652 return (GLubyte*)"TransGaming Inc.";
2653 case GL_RENDERER:
2654 return (GLubyte*)"ANGLE";
2655 case GL_VERSION:
2656 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2657 case GL_SHADING_LANGUAGE_VERSION:
2658 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2659 case GL_EXTENSIONS:
2660 return (GLubyte*)"";
2661 default:
2662 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2663 }
2664 }
2665 catch(std::bad_alloc&)
2666 {
2667 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2668 }
2669
2670 return NULL;
2671}
2672
2673void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2674{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002675 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 +00002676
2677 try
2678 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002679 gl::Context *context = gl::getContext();
2680
2681 if (context)
2682 {
2683 gl::Texture *texture;
2684
2685 switch (target)
2686 {
2687 case GL_TEXTURE_2D:
2688 texture = context->getTexture2D();
2689 break;
2690 case GL_TEXTURE_CUBE_MAP:
2691 texture = context->getTextureCubeMap();
2692 break;
2693 default:
2694 return error(GL_INVALID_ENUM);
2695 }
2696
2697 switch (pname)
2698 {
2699 case GL_TEXTURE_MAG_FILTER:
2700 *params = (GLfloat)texture->getMagFilter();
2701 break;
2702 case GL_TEXTURE_MIN_FILTER:
2703 *params = (GLfloat)texture->getMinFilter();
2704 break;
2705 case GL_TEXTURE_WRAP_S:
2706 *params = (GLfloat)texture->getWrapS();
2707 break;
2708 case GL_TEXTURE_WRAP_T:
2709 *params = (GLfloat)texture->getWrapT();
2710 break;
2711 default:
2712 return error(GL_INVALID_ENUM);
2713 }
2714 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002715 }
2716 catch(std::bad_alloc&)
2717 {
2718 return error(GL_OUT_OF_MEMORY);
2719 }
2720}
2721
2722void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2723{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002724 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 +00002725
2726 try
2727 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002728 gl::Context *context = gl::getContext();
2729
2730 if (context)
2731 {
2732 gl::Texture *texture;
2733
2734 switch (target)
2735 {
2736 case GL_TEXTURE_2D:
2737 texture = context->getTexture2D();
2738 break;
2739 case GL_TEXTURE_CUBE_MAP:
2740 texture = context->getTextureCubeMap();
2741 break;
2742 default:
2743 return error(GL_INVALID_ENUM);
2744 }
2745
2746 switch (pname)
2747 {
2748 case GL_TEXTURE_MAG_FILTER:
2749 *params = texture->getMagFilter();
2750 break;
2751 case GL_TEXTURE_MIN_FILTER:
2752 *params = texture->getMinFilter();
2753 break;
2754 case GL_TEXTURE_WRAP_S:
2755 *params = texture->getWrapS();
2756 break;
2757 case GL_TEXTURE_WRAP_T:
2758 *params = texture->getWrapT();
2759 break;
2760 default:
2761 return error(GL_INVALID_ENUM);
2762 }
2763 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002764 }
2765 catch(std::bad_alloc&)
2766 {
2767 return error(GL_OUT_OF_MEMORY);
2768 }
2769}
2770
2771void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2772{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002773 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002774
2775 try
2776 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002777 gl::Context *context = gl::getContext();
2778
2779 if (context)
2780 {
2781 if (program == 0)
2782 {
2783 return error(GL_INVALID_VALUE);
2784 }
2785
2786 gl::Program *programObject = context->getProgram(program);
2787
2788 if (!programObject || !programObject->isLinked())
2789 {
2790 return error(GL_INVALID_OPERATION);
2791 }
2792
2793 if (!programObject->getUniformfv(location, params))
2794 {
2795 return error(GL_INVALID_OPERATION);
2796 }
2797 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002798 }
2799 catch(std::bad_alloc&)
2800 {
2801 return error(GL_OUT_OF_MEMORY);
2802 }
2803}
2804
2805void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2806{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002807 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002808
2809 try
2810 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002811 gl::Context *context = gl::getContext();
2812
2813 if (context)
2814 {
2815 if (program == 0)
2816 {
2817 return error(GL_INVALID_VALUE);
2818 }
2819
2820 gl::Program *programObject = context->getProgram(program);
2821
2822 if (!programObject || !programObject->isLinked())
2823 {
2824 return error(GL_INVALID_OPERATION);
2825 }
2826
2827 if (!programObject)
2828 {
2829 return error(GL_INVALID_OPERATION);
2830 }
2831
2832 if (!programObject->getUniformiv(location, params))
2833 {
2834 return error(GL_INVALID_OPERATION);
2835 }
2836 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002837 }
2838 catch(std::bad_alloc&)
2839 {
2840 return error(GL_OUT_OF_MEMORY);
2841 }
2842}
2843
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002844int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002845{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002846 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002847
2848 try
2849 {
2850 gl::Context *context = gl::getContext();
2851
2852 if (strstr(name, "gl_") == name)
2853 {
2854 return -1;
2855 }
2856
2857 if (context)
2858 {
2859 gl::Program *programObject = context->getProgram(program);
2860
2861 if (!programObject)
2862 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002863 if (context->getShader(program))
2864 {
2865 return error(GL_INVALID_OPERATION, -1);
2866 }
2867 else
2868 {
2869 return error(GL_INVALID_VALUE, -1);
2870 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002871 }
2872
2873 if (!programObject->isLinked())
2874 {
2875 return error(GL_INVALID_OPERATION, -1);
2876 }
2877
2878 return programObject->getUniformLocation(name);
2879 }
2880 }
2881 catch(std::bad_alloc&)
2882 {
2883 return error(GL_OUT_OF_MEMORY, -1);
2884 }
2885
2886 return -1;
2887}
2888
2889void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2890{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002891 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002892
2893 try
2894 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002895 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002896
daniel@transgaming.come0078962010-04-15 20:45:08 +00002897 if (context)
2898 {
2899 if (index >= gl::MAX_VERTEX_ATTRIBS)
2900 {
2901 return error(GL_INVALID_VALUE);
2902 }
2903
2904 switch (pname)
2905 {
2906 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2907 *params = (GLfloat)(context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2908 break;
2909 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2910 *params = (GLfloat)context->vertexAttribute[index].mSize;
2911 break;
2912 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2913 *params = (GLfloat)context->vertexAttribute[index].mStride;
2914 break;
2915 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2916 *params = (GLfloat)context->vertexAttribute[index].mType;
2917 break;
2918 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2919 *params = (GLfloat)(context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2920 break;
2921 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2922 *params = (GLfloat)context->vertexAttribute[index].mBoundBuffer;
2923 break;
2924 case GL_CURRENT_VERTEX_ATTRIB:
2925 for (int i = 0; i < 4; ++i)
2926 {
2927 params[i] = context->vertexAttribute[index].mCurrentValue[i];
2928 }
2929 break;
2930 default: return error(GL_INVALID_ENUM);
2931 }
2932 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002933 }
2934 catch(std::bad_alloc&)
2935 {
2936 return error(GL_OUT_OF_MEMORY);
2937 }
2938}
2939
2940void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2941{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002942 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002943
2944 try
2945 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002946 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002947
daniel@transgaming.come0078962010-04-15 20:45:08 +00002948 if (context)
2949 {
2950 if (index >= gl::MAX_VERTEX_ATTRIBS)
2951 {
2952 return error(GL_INVALID_VALUE);
2953 }
2954
2955 switch (pname)
2956 {
2957 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2958 *params = (context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2959 break;
2960 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2961 *params = context->vertexAttribute[index].mSize;
2962 break;
2963 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2964 *params = context->vertexAttribute[index].mStride;
2965 break;
2966 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2967 *params = context->vertexAttribute[index].mType;
2968 break;
2969 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2970 *params = (context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2971 break;
2972 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2973 *params = context->vertexAttribute[index].mBoundBuffer;
2974 break;
2975 case GL_CURRENT_VERTEX_ATTRIB:
2976 for (int i = 0; i < 4; ++i)
2977 {
2978 float currentValue = context->vertexAttribute[index].mCurrentValue[i];
2979 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
2980 }
2981 break;
2982 default: return error(GL_INVALID_ENUM);
2983 }
2984 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002985 }
2986 catch(std::bad_alloc&)
2987 {
2988 return error(GL_OUT_OF_MEMORY);
2989 }
2990}
2991
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002992void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002993{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002994 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002995
2996 try
2997 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002998 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002999
daniel@transgaming.come0078962010-04-15 20:45:08 +00003000 if (context)
3001 {
3002 if (index >= gl::MAX_VERTEX_ATTRIBS)
3003 {
3004 return error(GL_INVALID_VALUE);
3005 }
3006
3007 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3008 {
3009 return error(GL_INVALID_ENUM);
3010 }
3011
3012 *pointer = const_cast<GLvoid*>(context->vertexAttribute[index].mPointer);
3013 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003014 }
3015 catch(std::bad_alloc&)
3016 {
3017 return error(GL_OUT_OF_MEMORY);
3018 }
3019}
3020
3021void __stdcall glHint(GLenum target, GLenum mode)
3022{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003023 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003024
3025 try
3026 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003027 switch (target)
3028 {
3029 case GL_GENERATE_MIPMAP_HINT:
3030 switch (mode)
3031 {
3032 case GL_FASTEST:
3033 case GL_NICEST:
3034 case GL_DONT_CARE:
3035 break;
3036 default:
3037 return error(GL_INVALID_ENUM);
3038 }
3039 break;
3040 default:
3041 return error(GL_INVALID_ENUM);
3042 }
3043
3044 gl::Context *context = gl::getContext();
3045 if (context)
3046 {
3047 if (target == GL_GENERATE_MIPMAP_HINT)
3048 context->generateMipmapHint = mode;
3049 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003050 }
3051 catch(std::bad_alloc&)
3052 {
3053 return error(GL_OUT_OF_MEMORY);
3054 }
3055}
3056
3057GLboolean __stdcall glIsBuffer(GLuint buffer)
3058{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003059 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003060
3061 try
3062 {
3063 gl::Context *context = gl::getContext();
3064
3065 if (context && buffer)
3066 {
3067 gl::Buffer *bufferObject = context->getBuffer(buffer);
3068
3069 if (bufferObject)
3070 {
3071 return GL_TRUE;
3072 }
3073 }
3074 }
3075 catch(std::bad_alloc&)
3076 {
3077 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3078 }
3079
3080 return GL_FALSE;
3081}
3082
3083GLboolean __stdcall glIsEnabled(GLenum cap)
3084{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003085 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003086
3087 try
3088 {
3089 gl::Context *context = gl::getContext();
3090
3091 if (context)
3092 {
3093 switch (cap)
3094 {
3095 case GL_CULL_FACE: return context->cullFace;
3096 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
3097 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
3098 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
3099 case GL_SCISSOR_TEST: return context->scissorTest;
3100 case GL_STENCIL_TEST: return context->stencilTest;
3101 case GL_DEPTH_TEST: return context->depthTest;
3102 case GL_BLEND: return context->blend;
3103 case GL_DITHER: return context->dither;
3104 default:
3105 return error(GL_INVALID_ENUM, false);
3106 }
3107 }
3108 }
3109 catch(std::bad_alloc&)
3110 {
3111 return error(GL_OUT_OF_MEMORY, false);
3112 }
3113
3114 return false;
3115}
3116
3117GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3118{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003119 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003120
3121 try
3122 {
3123 gl::Context *context = gl::getContext();
3124
3125 if (context && framebuffer)
3126 {
3127 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3128
3129 if (framebufferObject)
3130 {
3131 return GL_TRUE;
3132 }
3133 }
3134 }
3135 catch(std::bad_alloc&)
3136 {
3137 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3138 }
3139
3140 return GL_FALSE;
3141}
3142
3143GLboolean __stdcall glIsProgram(GLuint program)
3144{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003145 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003146
3147 try
3148 {
3149 gl::Context *context = gl::getContext();
3150
3151 if (context && program)
3152 {
3153 gl::Program *programObject = context->getProgram(program);
3154
3155 if (programObject)
3156 {
3157 return GL_TRUE;
3158 }
3159 }
3160 }
3161 catch(std::bad_alloc&)
3162 {
3163 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3164 }
3165
3166 return GL_FALSE;
3167}
3168
3169GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3170{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003171 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003172
3173 try
3174 {
3175 gl::Context *context = gl::getContext();
3176
3177 if (context && renderbuffer)
3178 {
3179 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3180
3181 if (renderbufferObject)
3182 {
3183 return GL_TRUE;
3184 }
3185 }
3186 }
3187 catch(std::bad_alloc&)
3188 {
3189 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3190 }
3191
3192 return GL_FALSE;
3193}
3194
3195GLboolean __stdcall glIsShader(GLuint shader)
3196{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003197 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003198
3199 try
3200 {
3201 gl::Context *context = gl::getContext();
3202
3203 if (context && shader)
3204 {
3205 gl::Shader *shaderObject = context->getShader(shader);
3206
3207 if (shaderObject)
3208 {
3209 return GL_TRUE;
3210 }
3211 }
3212 }
3213 catch(std::bad_alloc&)
3214 {
3215 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3216 }
3217
3218 return GL_FALSE;
3219}
3220
3221GLboolean __stdcall glIsTexture(GLuint texture)
3222{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003223 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003224
3225 try
3226 {
3227 gl::Context *context = gl::getContext();
3228
3229 if (context && texture)
3230 {
3231 gl::Texture *textureObject = context->getTexture(texture);
3232
3233 if (textureObject)
3234 {
3235 return GL_TRUE;
3236 }
3237 }
3238 }
3239 catch(std::bad_alloc&)
3240 {
3241 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3242 }
3243
3244 return GL_FALSE;
3245}
3246
3247void __stdcall glLineWidth(GLfloat width)
3248{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003249 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003250
3251 try
3252 {
3253 if (width <= 0.0f)
3254 {
3255 return error(GL_INVALID_VALUE);
3256 }
3257
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003258 gl::Context *context = gl::getContext();
3259
3260 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003261 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003262 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003263 }
3264 }
3265 catch(std::bad_alloc&)
3266 {
3267 return error(GL_OUT_OF_MEMORY);
3268 }
3269}
3270
3271void __stdcall glLinkProgram(GLuint program)
3272{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003273 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003274
3275 try
3276 {
3277 gl::Context *context = gl::getContext();
3278
3279 if (context)
3280 {
3281 gl::Program *programObject = context->getProgram(program);
3282
3283 if (!programObject)
3284 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003285 if (context->getShader(program))
3286 {
3287 return error(GL_INVALID_OPERATION);
3288 }
3289 else
3290 {
3291 return error(GL_INVALID_VALUE);
3292 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003293 }
3294
3295 programObject->link();
3296 }
3297 }
3298 catch(std::bad_alloc&)
3299 {
3300 return error(GL_OUT_OF_MEMORY);
3301 }
3302}
3303
3304void __stdcall glPixelStorei(GLenum pname, GLint param)
3305{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003306 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003307
3308 try
3309 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003310 gl::Context *context = gl::getContext();
3311
3312 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003313 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003314 switch (pname)
3315 {
3316 case GL_UNPACK_ALIGNMENT:
3317 if (param != 1 && param != 2 && param != 4 && param != 8)
3318 {
3319 return error(GL_INVALID_VALUE);
3320 }
3321
3322 context->unpackAlignment = param;
3323 break;
3324
3325 case GL_PACK_ALIGNMENT:
3326 if (param != 1 && param != 2 && param != 4 && param != 8)
3327 {
3328 return error(GL_INVALID_VALUE);
3329 }
3330
3331 context->packAlignment = param;
3332 break;
3333
3334 default:
3335 return error(GL_INVALID_ENUM);
3336 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003337 }
3338 }
3339 catch(std::bad_alloc&)
3340 {
3341 return error(GL_OUT_OF_MEMORY);
3342 }
3343}
3344
3345void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3346{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003347 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003348
3349 try
3350 {
3351 if (factor != 0.0f || units != 0.0f)
3352 {
3353 UNIMPLEMENTED(); // FIXME
3354 }
3355 }
3356 catch(std::bad_alloc&)
3357 {
3358 return error(GL_OUT_OF_MEMORY);
3359 }
3360}
3361
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003362void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003363{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003364 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003365 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003366 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003367
3368 try
3369 {
3370 if (width < 0 || height < 0)
3371 {
3372 return error(GL_INVALID_VALUE);
3373 }
3374
3375 switch (format)
3376 {
3377 case GL_RGBA:
3378 switch (type)
3379 {
3380 case GL_UNSIGNED_BYTE:
3381 break;
3382 default:
3383 return error(GL_INVALID_OPERATION);
3384 }
3385 break;
3386 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3387 switch (type)
3388 {
3389 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3390 break;
3391 default:
3392 return error(GL_INVALID_OPERATION);
3393 }
3394 break;
3395 default:
3396 return error(GL_INVALID_OPERATION);
3397 }
3398
3399 gl::Context *context = gl::getContext();
3400
3401 if (context)
3402 {
3403 context->readPixels(x, y, width, height, format, type, pixels);
3404 }
3405 }
3406 catch(std::bad_alloc&)
3407 {
3408 return error(GL_OUT_OF_MEMORY);
3409 }
3410}
3411
3412void __stdcall glReleaseShaderCompiler(void)
3413{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003414 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003415
3416 try
3417 {
3418 gl::Shader::releaseCompiler();
3419 }
3420 catch(std::bad_alloc&)
3421 {
3422 return error(GL_OUT_OF_MEMORY);
3423 }
3424}
3425
3426void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3427{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003428 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3429 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003430
3431 try
3432 {
3433 switch (target)
3434 {
3435 case GL_RENDERBUFFER:
3436 break;
3437 default:
3438 return error(GL_INVALID_ENUM);
3439 }
3440
3441 switch (internalformat)
3442 {
3443 case GL_DEPTH_COMPONENT16:
3444 case GL_RGBA4:
3445 case GL_RGB5_A1:
3446 case GL_RGB565:
3447 case GL_STENCIL_INDEX8:
3448 break;
3449 default:
3450 return error(GL_INVALID_ENUM);
3451 }
3452
3453 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3454 {
3455 return error(GL_INVALID_VALUE);
3456 }
3457
3458 gl::Context *context = gl::getContext();
3459
3460 if (context)
3461 {
3462 if (context->framebuffer == 0 || context->renderbuffer == 0)
3463 {
3464 return error(GL_INVALID_OPERATION);
3465 }
3466
3467 switch (internalformat)
3468 {
3469 case GL_DEPTH_COMPONENT16:
3470 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3471 break;
3472 case GL_RGBA4:
3473 case GL_RGB5_A1:
3474 case GL_RGB565:
daniel@transgaming.com70d312a2010-04-20 18:52:38 +00003475 context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003476 break;
3477 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003478 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003479 break;
3480 default:
3481 return error(GL_INVALID_ENUM);
3482 }
3483 }
3484 }
3485 catch(std::bad_alloc&)
3486 {
3487 return error(GL_OUT_OF_MEMORY);
3488 }
3489}
3490
3491void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3492{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003493 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003494
3495 try
3496 {
3497 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003498
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003499 if (context)
3500 {
3501 context->sampleCoverageValue = gl::clamp01(value);
3502 context->sampleCoverageInvert = invert;
3503 }
3504 }
3505 catch(std::bad_alloc&)
3506 {
3507 return error(GL_OUT_OF_MEMORY);
3508 }
3509}
3510
3511void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3512{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003513 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 +00003514
3515 try
3516 {
3517 if (width < 0 || height < 0)
3518 {
3519 return error(GL_INVALID_VALUE);
3520 }
3521
3522 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003523
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003524 if (context)
3525 {
3526 context->scissorX = x;
3527 context->scissorY = y;
3528 context->scissorWidth = width;
3529 context->scissorHeight = height;
3530 }
3531 }
3532 catch(std::bad_alloc&)
3533 {
3534 return error(GL_OUT_OF_MEMORY);
3535 }
3536}
3537
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003538void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003539{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003540 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003541 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003542 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003543
3544 try
3545 {
3546 if (n < 0 || length < 0)
3547 {
3548 return error(GL_INVALID_VALUE);
3549 }
3550
3551 UNIMPLEMENTED(); // FIXME
3552 }
3553 catch(std::bad_alloc&)
3554 {
3555 return error(GL_OUT_OF_MEMORY);
3556 }
3557}
3558
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003559void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003560{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003561 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 +00003562 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003563
3564 try
3565 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003566 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003567 {
3568 return error(GL_INVALID_VALUE);
3569 }
3570
3571 gl::Context *context = gl::getContext();
3572
3573 if (context)
3574 {
3575 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003576
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003577 if (!shaderObject)
3578 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003579 if (context->getProgram(shader))
3580 {
3581 return error(GL_INVALID_OPERATION);
3582 }
3583 else
3584 {
3585 return error(GL_INVALID_VALUE);
3586 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003587 }
3588
3589 shaderObject->setSource(count, string, length);
3590 }
3591 }
3592 catch(std::bad_alloc&)
3593 {
3594 return error(GL_OUT_OF_MEMORY);
3595 }
3596}
3597
3598void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3599{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003600 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003601}
3602
3603void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3604{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003605 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 +00003606
3607 try
3608 {
3609 switch (face)
3610 {
3611 case GL_FRONT:
3612 case GL_BACK:
3613 case GL_FRONT_AND_BACK:
3614 break;
3615 default:
3616 return error(GL_INVALID_ENUM);
3617 }
3618
3619 switch (func)
3620 {
3621 case GL_NEVER:
3622 case GL_ALWAYS:
3623 case GL_LESS:
3624 case GL_LEQUAL:
3625 case GL_EQUAL:
3626 case GL_GEQUAL:
3627 case GL_GREATER:
3628 case GL_NOTEQUAL:
3629 break;
3630 default:
3631 return error(GL_INVALID_ENUM);
3632 }
3633
3634 gl::Context *context = gl::getContext();
3635
3636 if (context)
3637 {
3638 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3639 {
3640 context->stencilFunc = func;
3641 context->stencilRef = ref;
3642 context->stencilMask = mask;
3643 }
3644
3645 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3646 {
3647 context->stencilBackFunc = func;
3648 context->stencilBackRef = ref;
3649 context->stencilBackMask = mask;
3650 }
3651 }
3652 }
3653 catch(std::bad_alloc&)
3654 {
3655 return error(GL_OUT_OF_MEMORY);
3656 }
3657}
3658
3659void __stdcall glStencilMask(GLuint mask)
3660{
3661 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3662}
3663
3664void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3665{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003666 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003667
3668 try
3669 {
3670 switch (face)
3671 {
3672 case GL_FRONT:
3673 case GL_BACK:
3674 case GL_FRONT_AND_BACK:
3675 break;
3676 default:
3677 return error(GL_INVALID_ENUM);
3678 }
3679
3680 gl::Context *context = gl::getContext();
3681
3682 if (context)
3683 {
3684 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3685 {
3686 context->stencilWritemask = mask;
3687 }
3688
3689 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3690 {
3691 context->stencilBackWritemask = mask;
3692 }
3693 }
3694 }
3695 catch(std::bad_alloc&)
3696 {
3697 return error(GL_OUT_OF_MEMORY);
3698 }
3699}
3700
3701void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3702{
3703 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3704}
3705
3706void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3707{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003708 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3709 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003710
3711 try
3712 {
3713 switch (face)
3714 {
3715 case GL_FRONT:
3716 case GL_BACK:
3717 case GL_FRONT_AND_BACK:
3718 break;
3719 default:
3720 return error(GL_INVALID_ENUM);
3721 }
3722
3723 switch (fail)
3724 {
3725 case GL_ZERO:
3726 case GL_KEEP:
3727 case GL_REPLACE:
3728 case GL_INCR:
3729 case GL_DECR:
3730 case GL_INVERT:
3731 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003732 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003733 break;
3734 default:
3735 return error(GL_INVALID_ENUM);
3736 }
3737
3738 switch (zfail)
3739 {
3740 case GL_ZERO:
3741 case GL_KEEP:
3742 case GL_REPLACE:
3743 case GL_INCR:
3744 case GL_DECR:
3745 case GL_INVERT:
3746 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003747 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003748 break;
3749 default:
3750 return error(GL_INVALID_ENUM);
3751 }
3752
3753 switch (zpass)
3754 {
3755 case GL_ZERO:
3756 case GL_KEEP:
3757 case GL_REPLACE:
3758 case GL_INCR:
3759 case GL_DECR:
3760 case GL_INVERT:
3761 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003762 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003763 break;
3764 default:
3765 return error(GL_INVALID_ENUM);
3766 }
3767
3768 gl::Context *context = gl::getContext();
3769
3770 if (context)
3771 {
3772 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3773 {
3774 context->stencilFail = fail;
3775 context->stencilPassDepthFail = zfail;
3776 context->stencilPassDepthPass = zpass;
3777 }
3778
3779 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3780 {
3781 context->stencilBackFail = fail;
3782 context->stencilBackPassDepthFail = zfail;
3783 context->stencilBackPassDepthPass = zpass;
3784 }
3785 }
3786 }
3787 catch(std::bad_alloc&)
3788 {
3789 return error(GL_OUT_OF_MEMORY);
3790 }
3791}
3792
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003793void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3794 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003795{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003796 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 +00003797 "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 +00003798 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003799
3800 try
3801 {
3802 if (level < 0 || width < 0 || height < 0)
3803 {
3804 return error(GL_INVALID_VALUE);
3805 }
3806
3807 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3808 {
3809 return error(GL_INVALID_VALUE);
3810 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003811
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003812 switch (target)
3813 {
3814 case GL_TEXTURE_2D:
3815 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3816 {
3817 return error(GL_INVALID_VALUE);
3818 }
3819 break;
3820 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3821 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3822 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3823 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3824 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3825 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003826 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003827 {
3828 return error(GL_INVALID_VALUE);
3829 }
3830
3831 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3832 {
3833 return error(GL_INVALID_VALUE);
3834 }
3835 break;
3836 default:
3837 return error(GL_INVALID_ENUM);
3838 }
3839
3840 if (internalformat != format)
3841 {
3842 return error(GL_INVALID_OPERATION);
3843 }
3844
3845 switch (internalformat)
3846 {
3847 case GL_ALPHA:
3848 case GL_LUMINANCE:
3849 case GL_LUMINANCE_ALPHA:
3850 switch (type)
3851 {
3852 case GL_UNSIGNED_BYTE:
3853 break;
3854 default:
3855 return error(GL_INVALID_ENUM);
3856 }
3857 break;
3858 case GL_RGB:
3859 switch (type)
3860 {
3861 case GL_UNSIGNED_BYTE:
3862 case GL_UNSIGNED_SHORT_5_6_5:
3863 break;
3864 default:
3865 return error(GL_INVALID_ENUM);
3866 }
3867 break;
3868 case GL_RGBA:
3869 switch (type)
3870 {
3871 case GL_UNSIGNED_BYTE:
3872 case GL_UNSIGNED_SHORT_4_4_4_4:
3873 case GL_UNSIGNED_SHORT_5_5_5_1:
3874 break;
3875 default:
3876 return error(GL_INVALID_ENUM);
3877 }
3878 break;
3879 default:
3880 return error(GL_INVALID_VALUE);
3881 }
3882
3883 if (border != 0)
3884 {
3885 return error(GL_INVALID_VALUE);
3886 }
3887
3888 gl::Context *context = gl::getContext();
3889
3890 if (context)
3891 {
3892 if (target == GL_TEXTURE_2D)
3893 {
3894 gl::Texture2D *texture = context->getTexture2D();
3895
3896 if (!texture)
3897 {
3898 return error(GL_INVALID_OPERATION);
3899 }
3900
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003901 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003902 }
3903 else
3904 {
3905 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3906
3907 if (!texture)
3908 {
3909 return error(GL_INVALID_OPERATION);
3910 }
3911
3912 switch (target)
3913 {
3914 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003915 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003916 break;
3917 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003918 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003919 break;
3920 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003921 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003922 break;
3923 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003924 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003925 break;
3926 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003927 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003928 break;
3929 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003930 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003931 break;
3932 default: UNREACHABLE();
3933 }
3934 }
3935 }
3936 }
3937 catch(std::bad_alloc&)
3938 {
3939 return error(GL_OUT_OF_MEMORY);
3940 }
3941}
3942
3943void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3944{
3945 glTexParameteri(target, pname, (GLint)param);
3946}
3947
3948void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3949{
3950 glTexParameteri(target, pname, (GLint)*params);
3951}
3952
3953void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3954{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003955 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003956
3957 try
3958 {
3959 gl::Context *context = gl::getContext();
3960
3961 if (context)
3962 {
3963 gl::Texture *texture;
3964
3965 switch (target)
3966 {
3967 case GL_TEXTURE_2D:
3968 texture = context->getTexture2D();
3969 break;
3970 case GL_TEXTURE_CUBE_MAP:
3971 texture = context->getTextureCubeMap();
3972 break;
3973 default:
3974 return error(GL_INVALID_ENUM);
3975 }
3976
3977 switch (pname)
3978 {
3979 case GL_TEXTURE_WRAP_S:
3980 if (!texture->setWrapS((GLenum)param))
3981 {
3982 return error(GL_INVALID_ENUM);
3983 }
3984 break;
3985 case GL_TEXTURE_WRAP_T:
3986 if (!texture->setWrapT((GLenum)param))
3987 {
3988 return error(GL_INVALID_ENUM);
3989 }
3990 break;
3991 case GL_TEXTURE_MIN_FILTER:
3992 if (!texture->setMinFilter((GLenum)param))
3993 {
3994 return error(GL_INVALID_ENUM);
3995 }
3996 break;
3997 case GL_TEXTURE_MAG_FILTER:
3998 if (!texture->setMagFilter((GLenum)param))
3999 {
4000 return error(GL_INVALID_ENUM);
4001 }
4002 break;
4003 default:
4004 return error(GL_INVALID_ENUM);
4005 }
4006 }
4007 }
4008 catch(std::bad_alloc&)
4009 {
4010 return error(GL_OUT_OF_MEMORY);
4011 }
4012}
4013
4014void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4015{
4016 glTexParameteri(target, pname, *params);
4017}
4018
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004019void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4020 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004021{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004022 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4023 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004024 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004025 target, level, xoffset, yoffset, width, height, format, type, pixels);
4026
4027 try
4028 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004029 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
4030 {
4031 return error(GL_INVALID_ENUM);
4032 }
4033
4034 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004035 {
4036 return error(GL_INVALID_VALUE);
4037 }
4038
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004039 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4040 {
4041 return error(GL_INVALID_VALUE);
4042 }
4043
4044 if (!es2dx::CheckTextureFormatType(format, type))
4045 {
4046 return error(GL_INVALID_ENUM);
4047 }
4048
4049 if (width == 0 || height == 0 || pixels == NULL)
4050 {
4051 return;
4052 }
4053
4054 gl::Context *context = gl::getContext();
4055
4056 if (context)
4057 {
4058 if (target == GL_TEXTURE_2D)
4059 {
4060 gl::Texture2D *texture = context->getTexture2D();
4061
4062 if (!texture)
4063 {
4064 return error(GL_INVALID_OPERATION);
4065 }
4066
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004067 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004068 }
4069 else if (es2dx::IsCubemapTextureTarget(target))
4070 {
4071 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4072
4073 if (!texture)
4074 {
4075 return error(GL_INVALID_OPERATION);
4076 }
4077
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004078 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004079 }
4080 else
4081 {
4082 UNREACHABLE();
4083 }
4084 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004085 }
4086 catch(std::bad_alloc&)
4087 {
4088 return error(GL_OUT_OF_MEMORY);
4089 }
4090}
4091
4092void __stdcall glUniform1f(GLint location, GLfloat x)
4093{
4094 glUniform1fv(location, 1, &x);
4095}
4096
4097void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4098{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004099 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004100
4101 try
4102 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004103 if (count < 0)
4104 {
4105 return error(GL_INVALID_VALUE);
4106 }
4107
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004108 if (location == -1)
4109 {
4110 return;
4111 }
4112
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004113 gl::Context *context = gl::getContext();
4114
4115 if (context)
4116 {
4117 gl::Program *program = context->getCurrentProgram();
4118
4119 if (!program)
4120 {
4121 return error(GL_INVALID_OPERATION);
4122 }
4123
4124 if (!program->setUniform1fv(location, count, v))
4125 {
4126 return error(GL_INVALID_OPERATION);
4127 }
4128 }
4129 }
4130 catch(std::bad_alloc&)
4131 {
4132 return error(GL_OUT_OF_MEMORY);
4133 }
4134}
4135
4136void __stdcall glUniform1i(GLint location, GLint x)
4137{
4138 glUniform1iv(location, 1, &x);
4139}
4140
4141void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4142{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004143 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004144
4145 try
4146 {
4147 if (count < 0)
4148 {
4149 return error(GL_INVALID_VALUE);
4150 }
4151
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004152 if (location == -1)
4153 {
4154 return;
4155 }
4156
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004157 gl::Context *context = gl::getContext();
4158
4159 if (context)
4160 {
4161 gl::Program *program = context->getCurrentProgram();
4162
4163 if (!program)
4164 {
4165 return error(GL_INVALID_OPERATION);
4166 }
4167
4168 if (!program->setUniform1iv(location, count, v))
4169 {
4170 return error(GL_INVALID_OPERATION);
4171 }
4172 }
4173 }
4174 catch(std::bad_alloc&)
4175 {
4176 return error(GL_OUT_OF_MEMORY);
4177 }
4178}
4179
4180void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4181{
4182 GLfloat xy[2] = {x, y};
4183
4184 glUniform2fv(location, 1, (GLfloat*)&xy);
4185}
4186
4187void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4188{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004189 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004190
4191 try
4192 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004193 if (count < 0)
4194 {
4195 return error(GL_INVALID_VALUE);
4196 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004197
4198 if (location == -1)
4199 {
4200 return;
4201 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004202
4203 gl::Context *context = gl::getContext();
4204
4205 if (context)
4206 {
4207 gl::Program *program = context->getCurrentProgram();
4208
4209 if (!program)
4210 {
4211 return error(GL_INVALID_OPERATION);
4212 }
4213
4214 if (!program->setUniform2fv(location, count, v))
4215 {
4216 return error(GL_INVALID_OPERATION);
4217 }
4218 }
4219 }
4220 catch(std::bad_alloc&)
4221 {
4222 return error(GL_OUT_OF_MEMORY);
4223 }
4224}
4225
4226void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4227{
4228 GLint xy[4] = {x, y};
4229
4230 glUniform2iv(location, 1, (GLint*)&xy);
4231}
4232
4233void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4234{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004235 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004236
4237 try
4238 {
4239 if (count < 0)
4240 {
4241 return error(GL_INVALID_VALUE);
4242 }
4243
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004244 if (location == -1)
4245 {
4246 return;
4247 }
4248
4249 gl::Context *context = gl::getContext();
4250
4251 if (context)
4252 {
4253 gl::Program *program = context->getCurrentProgram();
4254
4255 if (!program)
4256 {
4257 return error(GL_INVALID_OPERATION);
4258 }
4259
4260 if (!program->setUniform2iv(location, count, v))
4261 {
4262 return error(GL_INVALID_OPERATION);
4263 }
4264 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004265 }
4266 catch(std::bad_alloc&)
4267 {
4268 return error(GL_OUT_OF_MEMORY);
4269 }
4270}
4271
4272void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4273{
4274 GLfloat xyz[3] = {x, y, z};
4275
4276 glUniform3fv(location, 1, (GLfloat*)&xyz);
4277}
4278
4279void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4280{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004281 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004282
4283 try
4284 {
4285 if (count < 0)
4286 {
4287 return error(GL_INVALID_VALUE);
4288 }
4289
4290 if (location == -1)
4291 {
4292 return;
4293 }
4294
4295 gl::Context *context = gl::getContext();
4296
4297 if (context)
4298 {
4299 gl::Program *program = context->getCurrentProgram();
4300
4301 if (!program)
4302 {
4303 return error(GL_INVALID_OPERATION);
4304 }
4305
4306 if (!program->setUniform3fv(location, count, v))
4307 {
4308 return error(GL_INVALID_OPERATION);
4309 }
4310 }
4311 }
4312 catch(std::bad_alloc&)
4313 {
4314 return error(GL_OUT_OF_MEMORY);
4315 }
4316}
4317
4318void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4319{
4320 GLint xyz[3] = {x, y, z};
4321
4322 glUniform3iv(location, 1, (GLint*)&xyz);
4323}
4324
4325void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4326{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004327 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004328
4329 try
4330 {
4331 if (count < 0)
4332 {
4333 return error(GL_INVALID_VALUE);
4334 }
4335
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004336 if (location == -1)
4337 {
4338 return;
4339 }
4340
4341 gl::Context *context = gl::getContext();
4342
4343 if (context)
4344 {
4345 gl::Program *program = context->getCurrentProgram();
4346
4347 if (!program)
4348 {
4349 return error(GL_INVALID_OPERATION);
4350 }
4351
4352 if (!program->setUniform3iv(location, count, v))
4353 {
4354 return error(GL_INVALID_OPERATION);
4355 }
4356 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004357 }
4358 catch(std::bad_alloc&)
4359 {
4360 return error(GL_OUT_OF_MEMORY);
4361 }
4362}
4363
4364void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4365{
4366 GLfloat xyzw[4] = {x, y, z, w};
4367
4368 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4369}
4370
4371void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4372{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004373 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004374
4375 try
4376 {
4377 if (count < 0)
4378 {
4379 return error(GL_INVALID_VALUE);
4380 }
4381
4382 if (location == -1)
4383 {
4384 return;
4385 }
4386
4387 gl::Context *context = gl::getContext();
4388
4389 if (context)
4390 {
4391 gl::Program *program = context->getCurrentProgram();
4392
4393 if (!program)
4394 {
4395 return error(GL_INVALID_OPERATION);
4396 }
4397
4398 if (!program->setUniform4fv(location, count, v))
4399 {
4400 return error(GL_INVALID_OPERATION);
4401 }
4402 }
4403 }
4404 catch(std::bad_alloc&)
4405 {
4406 return error(GL_OUT_OF_MEMORY);
4407 }
4408}
4409
4410void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4411{
4412 GLint xyzw[4] = {x, y, z, w};
4413
4414 glUniform4iv(location, 1, (GLint*)&xyzw);
4415}
4416
4417void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4418{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004419 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004420
4421 try
4422 {
4423 if (count < 0)
4424 {
4425 return error(GL_INVALID_VALUE);
4426 }
4427
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004428 if (location == -1)
4429 {
4430 return;
4431 }
4432
4433 gl::Context *context = gl::getContext();
4434
4435 if (context)
4436 {
4437 gl::Program *program = context->getCurrentProgram();
4438
4439 if (!program)
4440 {
4441 return error(GL_INVALID_OPERATION);
4442 }
4443
4444 if (!program->setUniform4iv(location, count, v))
4445 {
4446 return error(GL_INVALID_OPERATION);
4447 }
4448 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004449 }
4450 catch(std::bad_alloc&)
4451 {
4452 return error(GL_OUT_OF_MEMORY);
4453 }
4454}
4455
4456void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4457{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004458 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4459 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004460
4461 try
4462 {
4463 if (count < 0 || transpose != GL_FALSE)
4464 {
4465 return error(GL_INVALID_VALUE);
4466 }
4467
4468 if (location == -1)
4469 {
4470 return;
4471 }
4472
4473 gl::Context *context = gl::getContext();
4474
4475 if (context)
4476 {
4477 gl::Program *program = context->getCurrentProgram();
4478
4479 if (!program)
4480 {
4481 return error(GL_INVALID_OPERATION);
4482 }
4483
4484 if (!program->setUniformMatrix2fv(location, count, value))
4485 {
4486 return error(GL_INVALID_OPERATION);
4487 }
4488 }
4489 }
4490 catch(std::bad_alloc&)
4491 {
4492 return error(GL_OUT_OF_MEMORY);
4493 }
4494}
4495
4496void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4497{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004498 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4499 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004500
4501 try
4502 {
4503 if (count < 0 || transpose != GL_FALSE)
4504 {
4505 return error(GL_INVALID_VALUE);
4506 }
4507
4508 if (location == -1)
4509 {
4510 return;
4511 }
4512
4513 gl::Context *context = gl::getContext();
4514
4515 if (context)
4516 {
4517 gl::Program *program = context->getCurrentProgram();
4518
4519 if (!program)
4520 {
4521 return error(GL_INVALID_OPERATION);
4522 }
4523
4524 if (!program->setUniformMatrix3fv(location, count, value))
4525 {
4526 return error(GL_INVALID_OPERATION);
4527 }
4528 }
4529 }
4530 catch(std::bad_alloc&)
4531 {
4532 return error(GL_OUT_OF_MEMORY);
4533 }
4534}
4535
4536void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4537{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004538 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4539 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004540
4541 try
4542 {
4543 if (count < 0 || transpose != GL_FALSE)
4544 {
4545 return error(GL_INVALID_VALUE);
4546 }
4547
4548 if (location == -1)
4549 {
4550 return;
4551 }
4552
4553 gl::Context *context = gl::getContext();
4554
4555 if (context)
4556 {
4557 gl::Program *program = context->getCurrentProgram();
4558
4559 if (!program)
4560 {
4561 return error(GL_INVALID_OPERATION);
4562 }
4563
4564 if (!program->setUniformMatrix4fv(location, count, value))
4565 {
4566 return error(GL_INVALID_OPERATION);
4567 }
4568 }
4569 }
4570 catch(std::bad_alloc&)
4571 {
4572 return error(GL_OUT_OF_MEMORY);
4573 }
4574}
4575
4576void __stdcall glUseProgram(GLuint program)
4577{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004578 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004579
4580 try
4581 {
4582 gl::Context *context = gl::getContext();
4583
4584 if (context)
4585 {
4586 gl::Program *programObject = context->getProgram(program);
4587
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004588 if (!programObject && program != 0)
4589 {
4590 if (context->getShader(program))
4591 {
4592 return error(GL_INVALID_OPERATION);
4593 }
4594 else
4595 {
4596 return error(GL_INVALID_VALUE);
4597 }
4598 }
4599
4600 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004601 {
4602 return error(GL_INVALID_OPERATION);
4603 }
4604
4605 context->useProgram(program);
4606 }
4607 }
4608 catch(std::bad_alloc&)
4609 {
4610 return error(GL_OUT_OF_MEMORY);
4611 }
4612}
4613
4614void __stdcall glValidateProgram(GLuint program)
4615{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004616 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004617
4618 try
4619 {
4620 UNIMPLEMENTED(); // FIXME
4621 }
4622 catch(std::bad_alloc&)
4623 {
4624 return error(GL_OUT_OF_MEMORY);
4625 }
4626}
4627
4628void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4629{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004630 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004631
4632 try
4633 {
4634 if (index >= gl::MAX_VERTEX_ATTRIBS)
4635 {
4636 return error(GL_INVALID_VALUE);
4637 }
4638
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004639 gl::Context *context = gl::getContext();
4640
4641 if (context)
4642 {
4643 GLfloat vals[4] = { x, 0, 0, 1 };
4644 context->setVertexAttrib(index, vals);
4645 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004646 }
4647 catch(std::bad_alloc&)
4648 {
4649 return error(GL_OUT_OF_MEMORY);
4650 }
4651}
4652
4653void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4654{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004655 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004656
4657 try
4658 {
4659 if (index >= gl::MAX_VERTEX_ATTRIBS)
4660 {
4661 return error(GL_INVALID_VALUE);
4662 }
4663
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004664 gl::Context *context = gl::getContext();
4665
4666 if (context)
4667 {
4668 GLfloat vals[4] = { values[0], 0, 0, 1 };
4669 context->setVertexAttrib(index, vals);
4670 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004671 }
4672 catch(std::bad_alloc&)
4673 {
4674 return error(GL_OUT_OF_MEMORY);
4675 }
4676}
4677
4678void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4679{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004680 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004681
4682 try
4683 {
4684 if (index >= gl::MAX_VERTEX_ATTRIBS)
4685 {
4686 return error(GL_INVALID_VALUE);
4687 }
4688
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004689 gl::Context *context = gl::getContext();
4690
4691 if (context)
4692 {
4693 GLfloat vals[4] = { x, y, 0, 1 };
4694 context->setVertexAttrib(index, vals);
4695 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004696 }
4697 catch(std::bad_alloc&)
4698 {
4699 return error(GL_OUT_OF_MEMORY);
4700 }
4701}
4702
4703void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4704{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004705 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004706
4707 try
4708 {
4709 if (index >= gl::MAX_VERTEX_ATTRIBS)
4710 {
4711 return error(GL_INVALID_VALUE);
4712 }
4713
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004714 gl::Context *context = gl::getContext();
4715
4716 if (context)
4717 {
4718 GLfloat vals[4] = { values[0], values[1], 0, 1 };
4719 context->setVertexAttrib(index, vals);
4720 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004721 }
4722 catch(std::bad_alloc&)
4723 {
4724 return error(GL_OUT_OF_MEMORY);
4725 }
4726}
4727
4728void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4729{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004730 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 +00004731
4732 try
4733 {
4734 if (index >= gl::MAX_VERTEX_ATTRIBS)
4735 {
4736 return error(GL_INVALID_VALUE);
4737 }
4738
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004739 gl::Context *context = gl::getContext();
4740
4741 if (context)
4742 {
4743 GLfloat vals[4] = { x, y, z, 1 };
4744 context->setVertexAttrib(index, vals);
4745 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004746 }
4747 catch(std::bad_alloc&)
4748 {
4749 return error(GL_OUT_OF_MEMORY);
4750 }
4751}
4752
4753void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4754{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004755 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004756
4757 try
4758 {
4759 if (index >= gl::MAX_VERTEX_ATTRIBS)
4760 {
4761 return error(GL_INVALID_VALUE);
4762 }
4763
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004764 gl::Context *context = gl::getContext();
4765
4766 if (context)
4767 {
4768 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
4769 context->setVertexAttrib(index, vals);
4770 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004771 }
4772 catch(std::bad_alloc&)
4773 {
4774 return error(GL_OUT_OF_MEMORY);
4775 }
4776}
4777
4778void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4779{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004780 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 +00004781
4782 try
4783 {
4784 if (index >= gl::MAX_VERTEX_ATTRIBS)
4785 {
4786 return error(GL_INVALID_VALUE);
4787 }
4788
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004789 gl::Context *context = gl::getContext();
4790
4791 if (context)
4792 {
4793 GLfloat vals[4] = { x, y, z, w };
4794 context->setVertexAttrib(index, vals);
4795 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004796 }
4797 catch(std::bad_alloc&)
4798 {
4799 return error(GL_OUT_OF_MEMORY);
4800 }
4801}
4802
4803void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4804{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004805 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004806
4807 try
4808 {
4809 if (index >= gl::MAX_VERTEX_ATTRIBS)
4810 {
4811 return error(GL_INVALID_VALUE);
4812 }
4813
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004814 gl::Context *context = gl::getContext();
4815
4816 if (context)
4817 {
4818 context->setVertexAttrib(index, values);
4819 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004820 }
4821 catch(std::bad_alloc&)
4822 {
4823 return error(GL_OUT_OF_MEMORY);
4824 }
4825}
4826
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004827void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004828{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004829 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004830 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004831 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004832
4833 try
4834 {
4835 if (index >= gl::MAX_VERTEX_ATTRIBS)
4836 {
4837 return error(GL_INVALID_VALUE);
4838 }
4839
4840 if (size < 1 || size > 4)
4841 {
4842 return error(GL_INVALID_VALUE);
4843 }
4844
4845 switch (type)
4846 {
4847 case GL_BYTE:
4848 case GL_UNSIGNED_BYTE:
4849 case GL_SHORT:
4850 case GL_UNSIGNED_SHORT:
4851 case GL_FIXED:
4852 case GL_FLOAT:
4853 break;
4854 default:
4855 return error(GL_INVALID_ENUM);
4856 }
4857
4858 if (stride < 0)
4859 {
4860 return error(GL_INVALID_VALUE);
4861 }
4862
4863 gl::Context *context = gl::getContext();
4864
4865 if (context)
4866 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004867 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4868 context->vertexAttribute[index].mSize = size;
4869 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004870 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004871 context->vertexAttribute[index].mStride = stride;
4872 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004873 }
4874 }
4875 catch(std::bad_alloc&)
4876 {
4877 return error(GL_OUT_OF_MEMORY);
4878 }
4879}
4880
4881void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4882{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004883 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 +00004884
4885 try
4886 {
4887 if (width < 0 || height < 0)
4888 {
4889 return error(GL_INVALID_VALUE);
4890 }
4891
4892 gl::Context *context = gl::getContext();
4893
4894 if (context)
4895 {
4896 context->viewportX = x;
4897 context->viewportY = y;
4898 context->viewportWidth = width;
4899 context->viewportHeight = height;
4900 }
4901 }
4902 catch(std::bad_alloc&)
4903 {
4904 return error(GL_OUT_OF_MEMORY);
4905 }
4906}
4907
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004908void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4909 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004910{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004911 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4912 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004913 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004914 target, level, internalformat, width, height, depth, border, format, type, pixels);
4915
4916 try
4917 {
4918 UNIMPLEMENTED(); // FIXME
4919 }
4920 catch(std::bad_alloc&)
4921 {
4922 return error(GL_OUT_OF_MEMORY);
4923 }
4924}
4925}