blob: 1edbfa18b037600738c07d2124eef9ffca8c78c5 [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.comfe4b8272010-04-08 03:51:20 +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.comb5b06162010-03-21 04:31:32 +00001873 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001874 "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
1884 UNIMPLEMENTED(); // FIXME
1885 }
1886 catch(std::bad_alloc&)
1887 {
1888 return error(GL_OUT_OF_MEMORY);
1889 }
1890}
1891
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001892void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001893{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001894 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001895 "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 +00001896 program, index, bufsize, length, size, type, name);
1897
1898 try
1899 {
1900 if (bufsize < 0)
1901 {
1902 return error(GL_INVALID_VALUE);
1903 }
1904
1905 UNIMPLEMENTED(); // FIXME
1906 }
1907 catch(std::bad_alloc&)
1908 {
1909 return error(GL_OUT_OF_MEMORY);
1910 }
1911}
1912
1913void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1914{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001915 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1916 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001917
1918 try
1919 {
1920 if (maxcount < 0)
1921 {
1922 return error(GL_INVALID_VALUE);
1923 }
1924
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001925 gl::Context *context = gl::getContext();
1926
1927 if (context)
1928 {
1929 gl::Program *programObject = context->getProgram(program);
1930
1931 if (!programObject)
1932 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001933 if (context->getShader(program))
1934 {
1935 return error(GL_INVALID_OPERATION);
1936 }
1937 else
1938 {
1939 return error(GL_INVALID_VALUE);
1940 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001941 }
1942
1943 return programObject->getAttachedShaders(maxcount, count, shaders);
1944 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001945 }
1946 catch(std::bad_alloc&)
1947 {
1948 return error(GL_OUT_OF_MEMORY);
1949 }
1950}
1951
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001952int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001953{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001954 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001955
1956 try
1957 {
1958 gl::Context *context = gl::getContext();
1959
1960 if (context)
1961 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001962
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001963 gl::Program *programObject = context->getProgram(program);
1964
1965 if (!programObject)
1966 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001967 if (context->getShader(program))
1968 {
1969 return error(GL_INVALID_OPERATION, -1);
1970 }
1971 else
1972 {
1973 return error(GL_INVALID_VALUE, -1);
1974 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001975 }
1976
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00001977 if (!programObject->isLinked())
1978 {
1979 return error(GL_INVALID_OPERATION, -1);
1980 }
1981
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001982 return programObject->getAttributeLocation(name);
1983 }
1984 }
1985 catch(std::bad_alloc&)
1986 {
1987 return error(GL_OUT_OF_MEMORY, -1);
1988 }
1989
1990 return -1;
1991}
1992
1993void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1994{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001995 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001996
1997 try
1998 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001999 gl::Context *context = gl::getContext();
2000
2001 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002002 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002003 if (!(context->getBooleanv(pname, params)))
2004 {
2005 GLenum nativeType;
2006 unsigned int numParams = 0;
2007 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2008 return error(GL_INVALID_ENUM);
2009
2010 if (numParams == 0)
2011 return; // it is known that the pname is valid, but there are no parameters to return
2012
2013 if (nativeType == GL_FLOAT)
2014 {
2015 GLfloat *floatParams = NULL;
2016 floatParams = new GLfloat[numParams];
2017
2018 context->getFloatv(pname, floatParams);
2019
2020 for (unsigned int i = 0; i < numParams; ++i)
2021 {
2022 if (floatParams[i] == 0.0f)
2023 params[i] = GL_FALSE;
2024 else
2025 params[i] = GL_TRUE;
2026 }
2027
2028 delete [] floatParams;
2029 }
2030 else if (nativeType == GL_INT)
2031 {
2032 GLint *intParams = NULL;
2033 intParams = new GLint[numParams];
2034
2035 context->getIntegerv(pname, intParams);
2036
2037 for (unsigned int i = 0; i < numParams; ++i)
2038 {
2039 if (intParams[i] == 0)
2040 params[i] = GL_FALSE;
2041 else
2042 params[i] = GL_TRUE;
2043 }
2044
2045 delete [] intParams;
2046 }
2047 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002048 }
2049 }
2050 catch(std::bad_alloc&)
2051 {
2052 return error(GL_OUT_OF_MEMORY);
2053 }
2054}
2055
2056void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2057{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002058 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 +00002059
2060 try
2061 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002062 gl::Context *context = gl::getContext();
2063
2064 if (context)
2065 {
2066 gl::Buffer *buffer;
2067
2068 switch (target)
2069 {
2070 case GL_ARRAY_BUFFER:
2071 buffer = context->getArrayBuffer();
2072 break;
2073 case GL_ELEMENT_ARRAY_BUFFER:
2074 buffer = context->getElementArrayBuffer();
2075 break;
2076 default: return error(GL_INVALID_ENUM);
2077 }
2078
2079 if (!buffer)
2080 {
2081 // A null buffer means that "0" is bound to the requested buffer target
2082 return error(GL_INVALID_OPERATION);
2083 }
2084
2085 switch (pname)
2086 {
2087 case GL_BUFFER_USAGE:
2088 *params = buffer->usage();
2089 break;
2090 case GL_BUFFER_SIZE:
2091 *params = buffer->size();
2092 break;
2093 default: return error(GL_INVALID_ENUM);
2094 }
2095 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002096 }
2097 catch(std::bad_alloc&)
2098 {
2099 return error(GL_OUT_OF_MEMORY);
2100 }
2101}
2102
2103GLenum __stdcall glGetError(void)
2104{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002105 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002106
2107 gl::Context *context = gl::getContext();
2108
2109 if (context)
2110 {
2111 return context->getError();
2112 }
2113
2114 return GL_NO_ERROR;
2115}
2116
2117void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2118{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002119 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002120
2121 try
2122 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002123 gl::Context *context = gl::getContext();
2124
2125 if (context)
2126 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002127 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002128 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002129 GLenum nativeType;
2130 unsigned int numParams = 0;
2131 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2132 return error(GL_INVALID_ENUM);
2133
2134 if (numParams == 0)
2135 return; // it is known that the pname is valid, but that there are no parameters to return.
2136
2137 if (nativeType == GL_BOOL)
2138 {
2139 GLboolean *boolParams = NULL;
2140 boolParams = new GLboolean[numParams];
2141
2142 context->getBooleanv(pname, boolParams);
2143
2144 for (unsigned int i = 0; i < numParams; ++i)
2145 {
2146 if (boolParams[i] == GL_FALSE)
2147 params[i] = 0.0f;
2148 else
2149 params[i] = 1.0f;
2150 }
2151
2152 delete [] boolParams;
2153 }
2154 else if (nativeType == GL_INT)
2155 {
2156 GLint *intParams = NULL;
2157 intParams = new GLint[numParams];
2158
2159 context->getIntegerv(pname, intParams);
2160
2161 for (unsigned int i = 0; i < numParams; ++i)
2162 {
2163 params[i] = (GLfloat)intParams[i];
2164 }
2165
2166 delete [] intParams;
2167 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002168 }
2169 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002170 }
2171 catch(std::bad_alloc&)
2172 {
2173 return error(GL_OUT_OF_MEMORY);
2174 }
2175}
2176
2177void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2178{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002179 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2180 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002181
2182 try
2183 {
2184 gl::Context *context = gl::getContext();
2185
2186 if (context)
2187 {
2188 if (context->framebuffer == 0)
2189 {
2190 return error(GL_INVALID_OPERATION);
2191 }
2192
2193 UNIMPLEMENTED(); // FIXME
2194 }
2195 }
2196 catch(std::bad_alloc&)
2197 {
2198 return error(GL_OUT_OF_MEMORY);
2199 }
2200}
2201
2202void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2203{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002204 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", 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 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002212 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002213 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002214 GLenum nativeType;
2215 unsigned int numParams = 0;
2216 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2217 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002218
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002219 if (numParams == 0)
2220 return; // it is known that pname is valid, but there are no parameters to return
2221
2222 if (nativeType == GL_BOOL)
2223 {
2224 GLboolean *boolParams = NULL;
2225 boolParams = new GLboolean[numParams];
2226
2227 context->getBooleanv(pname, boolParams);
2228
2229 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002230 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002231 if (boolParams[i] == GL_FALSE)
2232 params[i] = 0;
2233 else
2234 params[i] = 1;
2235 }
2236
2237 delete [] boolParams;
2238 }
2239 else if (nativeType == GL_FLOAT)
2240 {
2241 GLfloat *floatParams = NULL;
2242 floatParams = new GLfloat[numParams];
2243
2244 context->getFloatv(pname, floatParams);
2245
2246 for (unsigned int i = 0; i < numParams; ++i)
2247 {
2248 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002249 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002250 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002251 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002252 else
2253 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 +00002254 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002255
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002256 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002257 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002258 }
2259 }
2260 }
2261 catch(std::bad_alloc&)
2262 {
2263 return error(GL_OUT_OF_MEMORY);
2264 }
2265}
2266
2267void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2268{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002269 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002270
2271 try
2272 {
2273 gl::Context *context = gl::getContext();
2274
2275 if (context)
2276 {
2277 gl::Program *programObject = context->getProgram(program);
2278
2279 if (!programObject)
2280 {
2281 return error(GL_INVALID_VALUE);
2282 }
2283
2284 switch (pname)
2285 {
2286 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002287 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002288 return;
2289 case GL_LINK_STATUS:
2290 *params = programObject->isLinked();
2291 return;
2292 case GL_VALIDATE_STATUS:
2293 UNIMPLEMENTED(); // FIXME
2294 *params = GL_TRUE;
2295 return;
2296 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002297 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002298 return;
2299 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002300 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002301 return;
2302 case GL_ACTIVE_ATTRIBUTES:
2303 UNIMPLEMENTED(); // FIXME
2304 *params = 0;
2305 return;
2306 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2307 UNIMPLEMENTED(); // FIXME
2308 *params = 0;
2309 return;
2310 case GL_ACTIVE_UNIFORMS:
2311 UNIMPLEMENTED(); // FIXME
2312 *params = 0;
2313 return;
2314 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2315 UNIMPLEMENTED(); // FIXME
2316 *params = 0;
2317 return;
2318 default:
2319 return error(GL_INVALID_ENUM);
2320 }
2321 }
2322 }
2323 catch(std::bad_alloc&)
2324 {
2325 return error(GL_OUT_OF_MEMORY);
2326 }
2327}
2328
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002329void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002330{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002331 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 +00002332 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002333
2334 try
2335 {
2336 if (bufsize < 0)
2337 {
2338 return error(GL_INVALID_VALUE);
2339 }
2340
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002341 gl::Context *context = gl::getContext();
2342
2343 if (context)
2344 {
2345 gl::Program *programObject = context->getProgram(program);
2346
2347 if (!programObject)
2348 {
2349 return error(GL_INVALID_VALUE);
2350 }
2351
2352 programObject->getInfoLog(bufsize, length, infolog);
2353 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002354 }
2355 catch(std::bad_alloc&)
2356 {
2357 return error(GL_OUT_OF_MEMORY);
2358 }
2359}
2360
2361void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2362{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002363 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 +00002364
2365 try
2366 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002367 gl::Context *context = gl::getContext();
2368
2369 if (context)
2370 {
2371 if (target != GL_RENDERBUFFER)
2372 {
2373 return error(GL_INVALID_ENUM);
2374 }
2375
2376 if (context->renderbuffer == 0)
2377 {
2378 return error(GL_INVALID_OPERATION);
2379 }
2380
2381 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->renderbuffer);
2382
2383 switch (pname)
2384 {
2385 case GL_RENDERBUFFER_WIDTH:
2386 *params = renderbuffer->getWidth();
2387 break;
2388 case GL_RENDERBUFFER_HEIGHT:
2389 *params = renderbuffer->getHeight();
2390 break;
2391 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2392 *params = renderbuffer->getFormat();
2393 break;
2394 case GL_RENDERBUFFER_RED_SIZE:
2395 if (renderbuffer->isColorbuffer())
2396 {
2397 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
2398 }
2399 else
2400 {
2401 *params = 0;
2402 }
2403 break;
2404 case GL_RENDERBUFFER_GREEN_SIZE:
2405 if (renderbuffer->isColorbuffer())
2406 {
2407 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
2408 }
2409 else
2410 {
2411 *params = 0;
2412 }
2413 break;
2414 case GL_RENDERBUFFER_BLUE_SIZE:
2415 if (renderbuffer->isColorbuffer())
2416 {
2417 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
2418 }
2419 else
2420 {
2421 *params = 0;
2422 }
2423 break;
2424 case GL_RENDERBUFFER_ALPHA_SIZE:
2425 if (renderbuffer->isColorbuffer())
2426 {
2427 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
2428 }
2429 else
2430 {
2431 *params = 0;
2432 }
2433 break;
2434 case GL_RENDERBUFFER_DEPTH_SIZE:
2435 if (renderbuffer->isDepthbuffer())
2436 {
2437 *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
2438 }
2439 else
2440 {
2441 *params = 0;
2442 }
2443 break;
2444 case GL_RENDERBUFFER_STENCIL_SIZE:
2445 if (renderbuffer->isStencilbuffer())
2446 {
2447 *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
2448 }
2449 else
2450 {
2451 *params = 0;
2452 }
2453 break;
2454 default:
2455 return error(GL_INVALID_ENUM);
2456 }
2457 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002458 }
2459 catch(std::bad_alloc&)
2460 {
2461 return error(GL_OUT_OF_MEMORY);
2462 }
2463}
2464
2465void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2466{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002467 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002468
2469 try
2470 {
2471 gl::Context *context = gl::getContext();
2472
2473 if (context)
2474 {
2475 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002476
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002477 if (!shaderObject)
2478 {
2479 return error(GL_INVALID_VALUE);
2480 }
2481
2482 switch (pname)
2483 {
2484 case GL_SHADER_TYPE:
2485 *params = shaderObject->getType();
2486 return;
2487 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002488 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002489 return;
2490 case GL_COMPILE_STATUS:
2491 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2492 return;
2493 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002494 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002495 return;
2496 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002497 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002498 return;
2499 default:
2500 return error(GL_INVALID_ENUM);
2501 }
2502 }
2503 }
2504 catch(std::bad_alloc&)
2505 {
2506 return error(GL_OUT_OF_MEMORY);
2507 }
2508}
2509
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002510void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002511{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002512 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 +00002513 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002514
2515 try
2516 {
2517 if (bufsize < 0)
2518 {
2519 return error(GL_INVALID_VALUE);
2520 }
2521
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002522 gl::Context *context = gl::getContext();
2523
2524 if (context)
2525 {
2526 gl::Shader *shaderObject = context->getShader(shader);
2527
2528 if (!shaderObject)
2529 {
2530 return error(GL_INVALID_VALUE);
2531 }
2532
2533 shaderObject->getInfoLog(bufsize, length, infolog);
2534 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002535 }
2536 catch(std::bad_alloc&)
2537 {
2538 return error(GL_OUT_OF_MEMORY);
2539 }
2540}
2541
2542void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2543{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002544 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2545 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002546
2547 try
2548 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002549 switch (shadertype)
2550 {
2551 case GL_VERTEX_SHADER:
2552 case GL_FRAGMENT_SHADER:
2553 break;
2554 default:
2555 return error(GL_INVALID_ENUM);
2556 }
2557
2558 switch (precisiontype)
2559 {
2560 case GL_LOW_FLOAT:
2561 case GL_MEDIUM_FLOAT:
2562 case GL_HIGH_FLOAT:
2563 // Assume IEEE 754 precision
2564 range[0] = 127;
2565 range[1] = 127;
2566 precision[0] = 23;
2567 precision[1] = 23;
2568 break;
2569 case GL_LOW_INT:
2570 case GL_MEDIUM_INT:
2571 case GL_HIGH_INT:
2572 // Some (most) hardware only supports single-precision floating-point numbers,
2573 // which can accurately represent integers up to +/-16777216
2574 range[0] = 24;
2575 range[1] = 24;
2576 precision[0] = 0;
2577 precision[1] = 0;
2578 break;
2579 default:
2580 return error(GL_INVALID_ENUM);
2581 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002582 }
2583 catch(std::bad_alloc&)
2584 {
2585 return error(GL_OUT_OF_MEMORY);
2586 }
2587}
2588
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002589void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002590{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002591 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 +00002592 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002593
2594 try
2595 {
2596 if (bufsize < 0)
2597 {
2598 return error(GL_INVALID_VALUE);
2599 }
2600
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002601 gl::Context *context = gl::getContext();
2602
2603 if (context)
2604 {
2605 gl::Shader *shaderObject = context->getShader(shader);
2606
2607 if (!shaderObject)
2608 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002609 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002610 }
2611
2612 shaderObject->getSource(bufsize, length, source);
2613 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002614 }
2615 catch(std::bad_alloc&)
2616 {
2617 return error(GL_OUT_OF_MEMORY);
2618 }
2619}
2620
2621const GLubyte* __stdcall glGetString(GLenum name)
2622{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002623 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002624
2625 try
2626 {
2627 switch (name)
2628 {
2629 case GL_VENDOR:
2630 return (GLubyte*)"TransGaming Inc.";
2631 case GL_RENDERER:
2632 return (GLubyte*)"ANGLE";
2633 case GL_VERSION:
2634 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2635 case GL_SHADING_LANGUAGE_VERSION:
2636 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2637 case GL_EXTENSIONS:
2638 return (GLubyte*)"";
2639 default:
2640 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2641 }
2642 }
2643 catch(std::bad_alloc&)
2644 {
2645 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2646 }
2647
2648 return NULL;
2649}
2650
2651void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2652{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002653 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 +00002654
2655 try
2656 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002657 gl::Context *context = gl::getContext();
2658
2659 if (context)
2660 {
2661 gl::Texture *texture;
2662
2663 switch (target)
2664 {
2665 case GL_TEXTURE_2D:
2666 texture = context->getTexture2D();
2667 break;
2668 case GL_TEXTURE_CUBE_MAP:
2669 texture = context->getTextureCubeMap();
2670 break;
2671 default:
2672 return error(GL_INVALID_ENUM);
2673 }
2674
2675 switch (pname)
2676 {
2677 case GL_TEXTURE_MAG_FILTER:
2678 *params = (GLfloat)texture->getMagFilter();
2679 break;
2680 case GL_TEXTURE_MIN_FILTER:
2681 *params = (GLfloat)texture->getMinFilter();
2682 break;
2683 case GL_TEXTURE_WRAP_S:
2684 *params = (GLfloat)texture->getWrapS();
2685 break;
2686 case GL_TEXTURE_WRAP_T:
2687 *params = (GLfloat)texture->getWrapT();
2688 break;
2689 default:
2690 return error(GL_INVALID_ENUM);
2691 }
2692 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002693 }
2694 catch(std::bad_alloc&)
2695 {
2696 return error(GL_OUT_OF_MEMORY);
2697 }
2698}
2699
2700void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2701{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002702 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 +00002703
2704 try
2705 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002706 gl::Context *context = gl::getContext();
2707
2708 if (context)
2709 {
2710 gl::Texture *texture;
2711
2712 switch (target)
2713 {
2714 case GL_TEXTURE_2D:
2715 texture = context->getTexture2D();
2716 break;
2717 case GL_TEXTURE_CUBE_MAP:
2718 texture = context->getTextureCubeMap();
2719 break;
2720 default:
2721 return error(GL_INVALID_ENUM);
2722 }
2723
2724 switch (pname)
2725 {
2726 case GL_TEXTURE_MAG_FILTER:
2727 *params = texture->getMagFilter();
2728 break;
2729 case GL_TEXTURE_MIN_FILTER:
2730 *params = texture->getMinFilter();
2731 break;
2732 case GL_TEXTURE_WRAP_S:
2733 *params = texture->getWrapS();
2734 break;
2735 case GL_TEXTURE_WRAP_T:
2736 *params = texture->getWrapT();
2737 break;
2738 default:
2739 return error(GL_INVALID_ENUM);
2740 }
2741 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002742 }
2743 catch(std::bad_alloc&)
2744 {
2745 return error(GL_OUT_OF_MEMORY);
2746 }
2747}
2748
2749void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2750{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002751 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002752
2753 try
2754 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002755 gl::Context *context = gl::getContext();
2756
2757 if (context)
2758 {
2759 if (program == 0)
2760 {
2761 return error(GL_INVALID_VALUE);
2762 }
2763
2764 gl::Program *programObject = context->getProgram(program);
2765
2766 if (!programObject || !programObject->isLinked())
2767 {
2768 return error(GL_INVALID_OPERATION);
2769 }
2770
2771 if (!programObject->getUniformfv(location, params))
2772 {
2773 return error(GL_INVALID_OPERATION);
2774 }
2775 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002776 }
2777 catch(std::bad_alloc&)
2778 {
2779 return error(GL_OUT_OF_MEMORY);
2780 }
2781}
2782
2783void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2784{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002785 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002786
2787 try
2788 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002789 gl::Context *context = gl::getContext();
2790
2791 if (context)
2792 {
2793 if (program == 0)
2794 {
2795 return error(GL_INVALID_VALUE);
2796 }
2797
2798 gl::Program *programObject = context->getProgram(program);
2799
2800 if (!programObject || !programObject->isLinked())
2801 {
2802 return error(GL_INVALID_OPERATION);
2803 }
2804
2805 if (!programObject)
2806 {
2807 return error(GL_INVALID_OPERATION);
2808 }
2809
2810 if (!programObject->getUniformiv(location, params))
2811 {
2812 return error(GL_INVALID_OPERATION);
2813 }
2814 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002815 }
2816 catch(std::bad_alloc&)
2817 {
2818 return error(GL_OUT_OF_MEMORY);
2819 }
2820}
2821
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002822int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002823{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002824 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002825
2826 try
2827 {
2828 gl::Context *context = gl::getContext();
2829
2830 if (strstr(name, "gl_") == name)
2831 {
2832 return -1;
2833 }
2834
2835 if (context)
2836 {
2837 gl::Program *programObject = context->getProgram(program);
2838
2839 if (!programObject)
2840 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002841 if (context->getShader(program))
2842 {
2843 return error(GL_INVALID_OPERATION, -1);
2844 }
2845 else
2846 {
2847 return error(GL_INVALID_VALUE, -1);
2848 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002849 }
2850
2851 if (!programObject->isLinked())
2852 {
2853 return error(GL_INVALID_OPERATION, -1);
2854 }
2855
2856 return programObject->getUniformLocation(name);
2857 }
2858 }
2859 catch(std::bad_alloc&)
2860 {
2861 return error(GL_OUT_OF_MEMORY, -1);
2862 }
2863
2864 return -1;
2865}
2866
2867void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2868{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002869 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002870
2871 try
2872 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002873 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002874
daniel@transgaming.come0078962010-04-15 20:45:08 +00002875 if (context)
2876 {
2877 if (index >= gl::MAX_VERTEX_ATTRIBS)
2878 {
2879 return error(GL_INVALID_VALUE);
2880 }
2881
2882 switch (pname)
2883 {
2884 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2885 *params = (GLfloat)(context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2886 break;
2887 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2888 *params = (GLfloat)context->vertexAttribute[index].mSize;
2889 break;
2890 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2891 *params = (GLfloat)context->vertexAttribute[index].mStride;
2892 break;
2893 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2894 *params = (GLfloat)context->vertexAttribute[index].mType;
2895 break;
2896 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2897 *params = (GLfloat)(context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2898 break;
2899 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2900 *params = (GLfloat)context->vertexAttribute[index].mBoundBuffer;
2901 break;
2902 case GL_CURRENT_VERTEX_ATTRIB:
2903 for (int i = 0; i < 4; ++i)
2904 {
2905 params[i] = context->vertexAttribute[index].mCurrentValue[i];
2906 }
2907 break;
2908 default: return error(GL_INVALID_ENUM);
2909 }
2910 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002911 }
2912 catch(std::bad_alloc&)
2913 {
2914 return error(GL_OUT_OF_MEMORY);
2915 }
2916}
2917
2918void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2919{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002920 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002921
2922 try
2923 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002924 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002925
daniel@transgaming.come0078962010-04-15 20:45:08 +00002926 if (context)
2927 {
2928 if (index >= gl::MAX_VERTEX_ATTRIBS)
2929 {
2930 return error(GL_INVALID_VALUE);
2931 }
2932
2933 switch (pname)
2934 {
2935 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2936 *params = (context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2937 break;
2938 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2939 *params = context->vertexAttribute[index].mSize;
2940 break;
2941 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2942 *params = context->vertexAttribute[index].mStride;
2943 break;
2944 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2945 *params = context->vertexAttribute[index].mType;
2946 break;
2947 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2948 *params = (context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2949 break;
2950 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2951 *params = context->vertexAttribute[index].mBoundBuffer;
2952 break;
2953 case GL_CURRENT_VERTEX_ATTRIB:
2954 for (int i = 0; i < 4; ++i)
2955 {
2956 float currentValue = context->vertexAttribute[index].mCurrentValue[i];
2957 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
2958 }
2959 break;
2960 default: return error(GL_INVALID_ENUM);
2961 }
2962 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002963 }
2964 catch(std::bad_alloc&)
2965 {
2966 return error(GL_OUT_OF_MEMORY);
2967 }
2968}
2969
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002970void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002971{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002972 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002973
2974 try
2975 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002976 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002977
daniel@transgaming.come0078962010-04-15 20:45:08 +00002978 if (context)
2979 {
2980 if (index >= gl::MAX_VERTEX_ATTRIBS)
2981 {
2982 return error(GL_INVALID_VALUE);
2983 }
2984
2985 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
2986 {
2987 return error(GL_INVALID_ENUM);
2988 }
2989
2990 *pointer = const_cast<GLvoid*>(context->vertexAttribute[index].mPointer);
2991 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002992 }
2993 catch(std::bad_alloc&)
2994 {
2995 return error(GL_OUT_OF_MEMORY);
2996 }
2997}
2998
2999void __stdcall glHint(GLenum target, GLenum mode)
3000{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003001 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003002
3003 try
3004 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003005 switch (target)
3006 {
3007 case GL_GENERATE_MIPMAP_HINT:
3008 switch (mode)
3009 {
3010 case GL_FASTEST:
3011 case GL_NICEST:
3012 case GL_DONT_CARE:
3013 break;
3014 default:
3015 return error(GL_INVALID_ENUM);
3016 }
3017 break;
3018 default:
3019 return error(GL_INVALID_ENUM);
3020 }
3021
3022 gl::Context *context = gl::getContext();
3023 if (context)
3024 {
3025 if (target == GL_GENERATE_MIPMAP_HINT)
3026 context->generateMipmapHint = mode;
3027 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003028 }
3029 catch(std::bad_alloc&)
3030 {
3031 return error(GL_OUT_OF_MEMORY);
3032 }
3033}
3034
3035GLboolean __stdcall glIsBuffer(GLuint buffer)
3036{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003037 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003038
3039 try
3040 {
3041 gl::Context *context = gl::getContext();
3042
3043 if (context && buffer)
3044 {
3045 gl::Buffer *bufferObject = context->getBuffer(buffer);
3046
3047 if (bufferObject)
3048 {
3049 return GL_TRUE;
3050 }
3051 }
3052 }
3053 catch(std::bad_alloc&)
3054 {
3055 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3056 }
3057
3058 return GL_FALSE;
3059}
3060
3061GLboolean __stdcall glIsEnabled(GLenum cap)
3062{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003063 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003064
3065 try
3066 {
3067 gl::Context *context = gl::getContext();
3068
3069 if (context)
3070 {
3071 switch (cap)
3072 {
3073 case GL_CULL_FACE: return context->cullFace;
3074 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
3075 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
3076 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
3077 case GL_SCISSOR_TEST: return context->scissorTest;
3078 case GL_STENCIL_TEST: return context->stencilTest;
3079 case GL_DEPTH_TEST: return context->depthTest;
3080 case GL_BLEND: return context->blend;
3081 case GL_DITHER: return context->dither;
3082 default:
3083 return error(GL_INVALID_ENUM, false);
3084 }
3085 }
3086 }
3087 catch(std::bad_alloc&)
3088 {
3089 return error(GL_OUT_OF_MEMORY, false);
3090 }
3091
3092 return false;
3093}
3094
3095GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3096{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003097 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003098
3099 try
3100 {
3101 gl::Context *context = gl::getContext();
3102
3103 if (context && framebuffer)
3104 {
3105 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3106
3107 if (framebufferObject)
3108 {
3109 return GL_TRUE;
3110 }
3111 }
3112 }
3113 catch(std::bad_alloc&)
3114 {
3115 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3116 }
3117
3118 return GL_FALSE;
3119}
3120
3121GLboolean __stdcall glIsProgram(GLuint program)
3122{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003123 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003124
3125 try
3126 {
3127 gl::Context *context = gl::getContext();
3128
3129 if (context && program)
3130 {
3131 gl::Program *programObject = context->getProgram(program);
3132
3133 if (programObject)
3134 {
3135 return GL_TRUE;
3136 }
3137 }
3138 }
3139 catch(std::bad_alloc&)
3140 {
3141 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3142 }
3143
3144 return GL_FALSE;
3145}
3146
3147GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3148{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003149 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003150
3151 try
3152 {
3153 gl::Context *context = gl::getContext();
3154
3155 if (context && renderbuffer)
3156 {
3157 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3158
3159 if (renderbufferObject)
3160 {
3161 return GL_TRUE;
3162 }
3163 }
3164 }
3165 catch(std::bad_alloc&)
3166 {
3167 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3168 }
3169
3170 return GL_FALSE;
3171}
3172
3173GLboolean __stdcall glIsShader(GLuint shader)
3174{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003175 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003176
3177 try
3178 {
3179 gl::Context *context = gl::getContext();
3180
3181 if (context && shader)
3182 {
3183 gl::Shader *shaderObject = context->getShader(shader);
3184
3185 if (shaderObject)
3186 {
3187 return GL_TRUE;
3188 }
3189 }
3190 }
3191 catch(std::bad_alloc&)
3192 {
3193 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3194 }
3195
3196 return GL_FALSE;
3197}
3198
3199GLboolean __stdcall glIsTexture(GLuint texture)
3200{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003201 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003202
3203 try
3204 {
3205 gl::Context *context = gl::getContext();
3206
3207 if (context && texture)
3208 {
3209 gl::Texture *textureObject = context->getTexture(texture);
3210
3211 if (textureObject)
3212 {
3213 return GL_TRUE;
3214 }
3215 }
3216 }
3217 catch(std::bad_alloc&)
3218 {
3219 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3220 }
3221
3222 return GL_FALSE;
3223}
3224
3225void __stdcall glLineWidth(GLfloat width)
3226{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003227 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003228
3229 try
3230 {
3231 if (width <= 0.0f)
3232 {
3233 return error(GL_INVALID_VALUE);
3234 }
3235
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003236 gl::Context *context = gl::getContext();
3237
3238 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003239 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003240 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003241 }
3242 }
3243 catch(std::bad_alloc&)
3244 {
3245 return error(GL_OUT_OF_MEMORY);
3246 }
3247}
3248
3249void __stdcall glLinkProgram(GLuint program)
3250{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003251 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003252
3253 try
3254 {
3255 gl::Context *context = gl::getContext();
3256
3257 if (context)
3258 {
3259 gl::Program *programObject = context->getProgram(program);
3260
3261 if (!programObject)
3262 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003263 if (context->getShader(program))
3264 {
3265 return error(GL_INVALID_OPERATION);
3266 }
3267 else
3268 {
3269 return error(GL_INVALID_VALUE);
3270 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003271 }
3272
3273 programObject->link();
3274 }
3275 }
3276 catch(std::bad_alloc&)
3277 {
3278 return error(GL_OUT_OF_MEMORY);
3279 }
3280}
3281
3282void __stdcall glPixelStorei(GLenum pname, GLint param)
3283{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003284 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003285
3286 try
3287 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003288 gl::Context *context = gl::getContext();
3289
3290 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003291 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003292 switch (pname)
3293 {
3294 case GL_UNPACK_ALIGNMENT:
3295 if (param != 1 && param != 2 && param != 4 && param != 8)
3296 {
3297 return error(GL_INVALID_VALUE);
3298 }
3299
3300 context->unpackAlignment = param;
3301 break;
3302
3303 case GL_PACK_ALIGNMENT:
3304 if (param != 1 && param != 2 && param != 4 && param != 8)
3305 {
3306 return error(GL_INVALID_VALUE);
3307 }
3308
3309 context->packAlignment = param;
3310 break;
3311
3312 default:
3313 return error(GL_INVALID_ENUM);
3314 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003315 }
3316 }
3317 catch(std::bad_alloc&)
3318 {
3319 return error(GL_OUT_OF_MEMORY);
3320 }
3321}
3322
3323void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3324{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003325 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003326
3327 try
3328 {
3329 if (factor != 0.0f || units != 0.0f)
3330 {
3331 UNIMPLEMENTED(); // FIXME
3332 }
3333 }
3334 catch(std::bad_alloc&)
3335 {
3336 return error(GL_OUT_OF_MEMORY);
3337 }
3338}
3339
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003340void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003341{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003342 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003343 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003344 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003345
3346 try
3347 {
3348 if (width < 0 || height < 0)
3349 {
3350 return error(GL_INVALID_VALUE);
3351 }
3352
3353 switch (format)
3354 {
3355 case GL_RGBA:
3356 switch (type)
3357 {
3358 case GL_UNSIGNED_BYTE:
3359 break;
3360 default:
3361 return error(GL_INVALID_OPERATION);
3362 }
3363 break;
3364 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3365 switch (type)
3366 {
3367 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3368 break;
3369 default:
3370 return error(GL_INVALID_OPERATION);
3371 }
3372 break;
3373 default:
3374 return error(GL_INVALID_OPERATION);
3375 }
3376
3377 gl::Context *context = gl::getContext();
3378
3379 if (context)
3380 {
3381 context->readPixels(x, y, width, height, format, type, pixels);
3382 }
3383 }
3384 catch(std::bad_alloc&)
3385 {
3386 return error(GL_OUT_OF_MEMORY);
3387 }
3388}
3389
3390void __stdcall glReleaseShaderCompiler(void)
3391{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003392 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003393
3394 try
3395 {
3396 gl::Shader::releaseCompiler();
3397 }
3398 catch(std::bad_alloc&)
3399 {
3400 return error(GL_OUT_OF_MEMORY);
3401 }
3402}
3403
3404void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3405{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003406 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3407 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003408
3409 try
3410 {
3411 switch (target)
3412 {
3413 case GL_RENDERBUFFER:
3414 break;
3415 default:
3416 return error(GL_INVALID_ENUM);
3417 }
3418
3419 switch (internalformat)
3420 {
3421 case GL_DEPTH_COMPONENT16:
3422 case GL_RGBA4:
3423 case GL_RGB5_A1:
3424 case GL_RGB565:
3425 case GL_STENCIL_INDEX8:
3426 break;
3427 default:
3428 return error(GL_INVALID_ENUM);
3429 }
3430
3431 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3432 {
3433 return error(GL_INVALID_VALUE);
3434 }
3435
3436 gl::Context *context = gl::getContext();
3437
3438 if (context)
3439 {
3440 if (context->framebuffer == 0 || context->renderbuffer == 0)
3441 {
3442 return error(GL_INVALID_OPERATION);
3443 }
3444
3445 switch (internalformat)
3446 {
3447 case GL_DEPTH_COMPONENT16:
3448 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3449 break;
3450 case GL_RGBA4:
3451 case GL_RGB5_A1:
3452 case GL_RGB565:
daniel@transgaming.com70d312a2010-04-20 18:52:38 +00003453 context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003454 break;
3455 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003456 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003457 break;
3458 default:
3459 return error(GL_INVALID_ENUM);
3460 }
3461 }
3462 }
3463 catch(std::bad_alloc&)
3464 {
3465 return error(GL_OUT_OF_MEMORY);
3466 }
3467}
3468
3469void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3470{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003471 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003472
3473 try
3474 {
3475 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003476
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003477 if (context)
3478 {
3479 context->sampleCoverageValue = gl::clamp01(value);
3480 context->sampleCoverageInvert = invert;
3481 }
3482 }
3483 catch(std::bad_alloc&)
3484 {
3485 return error(GL_OUT_OF_MEMORY);
3486 }
3487}
3488
3489void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3490{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003491 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 +00003492
3493 try
3494 {
3495 if (width < 0 || height < 0)
3496 {
3497 return error(GL_INVALID_VALUE);
3498 }
3499
3500 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003501
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003502 if (context)
3503 {
3504 context->scissorX = x;
3505 context->scissorY = y;
3506 context->scissorWidth = width;
3507 context->scissorHeight = height;
3508 }
3509 }
3510 catch(std::bad_alloc&)
3511 {
3512 return error(GL_OUT_OF_MEMORY);
3513 }
3514}
3515
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003516void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003517{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003518 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003519 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003520 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003521
3522 try
3523 {
3524 if (n < 0 || length < 0)
3525 {
3526 return error(GL_INVALID_VALUE);
3527 }
3528
3529 UNIMPLEMENTED(); // FIXME
3530 }
3531 catch(std::bad_alloc&)
3532 {
3533 return error(GL_OUT_OF_MEMORY);
3534 }
3535}
3536
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003537void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003538{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003539 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 +00003540 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003541
3542 try
3543 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003544 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003545 {
3546 return error(GL_INVALID_VALUE);
3547 }
3548
3549 gl::Context *context = gl::getContext();
3550
3551 if (context)
3552 {
3553 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003554
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003555 if (!shaderObject)
3556 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003557 if (context->getProgram(shader))
3558 {
3559 return error(GL_INVALID_OPERATION);
3560 }
3561 else
3562 {
3563 return error(GL_INVALID_VALUE);
3564 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003565 }
3566
3567 shaderObject->setSource(count, string, length);
3568 }
3569 }
3570 catch(std::bad_alloc&)
3571 {
3572 return error(GL_OUT_OF_MEMORY);
3573 }
3574}
3575
3576void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3577{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003578 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003579}
3580
3581void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3582{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003583 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 +00003584
3585 try
3586 {
3587 switch (face)
3588 {
3589 case GL_FRONT:
3590 case GL_BACK:
3591 case GL_FRONT_AND_BACK:
3592 break;
3593 default:
3594 return error(GL_INVALID_ENUM);
3595 }
3596
3597 switch (func)
3598 {
3599 case GL_NEVER:
3600 case GL_ALWAYS:
3601 case GL_LESS:
3602 case GL_LEQUAL:
3603 case GL_EQUAL:
3604 case GL_GEQUAL:
3605 case GL_GREATER:
3606 case GL_NOTEQUAL:
3607 break;
3608 default:
3609 return error(GL_INVALID_ENUM);
3610 }
3611
3612 gl::Context *context = gl::getContext();
3613
3614 if (context)
3615 {
3616 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3617 {
3618 context->stencilFunc = func;
3619 context->stencilRef = ref;
3620 context->stencilMask = mask;
3621 }
3622
3623 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3624 {
3625 context->stencilBackFunc = func;
3626 context->stencilBackRef = ref;
3627 context->stencilBackMask = mask;
3628 }
3629 }
3630 }
3631 catch(std::bad_alloc&)
3632 {
3633 return error(GL_OUT_OF_MEMORY);
3634 }
3635}
3636
3637void __stdcall glStencilMask(GLuint mask)
3638{
3639 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3640}
3641
3642void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3643{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003644 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003645
3646 try
3647 {
3648 switch (face)
3649 {
3650 case GL_FRONT:
3651 case GL_BACK:
3652 case GL_FRONT_AND_BACK:
3653 break;
3654 default:
3655 return error(GL_INVALID_ENUM);
3656 }
3657
3658 gl::Context *context = gl::getContext();
3659
3660 if (context)
3661 {
3662 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3663 {
3664 context->stencilWritemask = mask;
3665 }
3666
3667 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3668 {
3669 context->stencilBackWritemask = mask;
3670 }
3671 }
3672 }
3673 catch(std::bad_alloc&)
3674 {
3675 return error(GL_OUT_OF_MEMORY);
3676 }
3677}
3678
3679void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3680{
3681 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3682}
3683
3684void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3685{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003686 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3687 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003688
3689 try
3690 {
3691 switch (face)
3692 {
3693 case GL_FRONT:
3694 case GL_BACK:
3695 case GL_FRONT_AND_BACK:
3696 break;
3697 default:
3698 return error(GL_INVALID_ENUM);
3699 }
3700
3701 switch (fail)
3702 {
3703 case GL_ZERO:
3704 case GL_KEEP:
3705 case GL_REPLACE:
3706 case GL_INCR:
3707 case GL_DECR:
3708 case GL_INVERT:
3709 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003710 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003711 break;
3712 default:
3713 return error(GL_INVALID_ENUM);
3714 }
3715
3716 switch (zfail)
3717 {
3718 case GL_ZERO:
3719 case GL_KEEP:
3720 case GL_REPLACE:
3721 case GL_INCR:
3722 case GL_DECR:
3723 case GL_INVERT:
3724 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003725 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003726 break;
3727 default:
3728 return error(GL_INVALID_ENUM);
3729 }
3730
3731 switch (zpass)
3732 {
3733 case GL_ZERO:
3734 case GL_KEEP:
3735 case GL_REPLACE:
3736 case GL_INCR:
3737 case GL_DECR:
3738 case GL_INVERT:
3739 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003740 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003741 break;
3742 default:
3743 return error(GL_INVALID_ENUM);
3744 }
3745
3746 gl::Context *context = gl::getContext();
3747
3748 if (context)
3749 {
3750 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3751 {
3752 context->stencilFail = fail;
3753 context->stencilPassDepthFail = zfail;
3754 context->stencilPassDepthPass = zpass;
3755 }
3756
3757 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3758 {
3759 context->stencilBackFail = fail;
3760 context->stencilBackPassDepthFail = zfail;
3761 context->stencilBackPassDepthPass = zpass;
3762 }
3763 }
3764 }
3765 catch(std::bad_alloc&)
3766 {
3767 return error(GL_OUT_OF_MEMORY);
3768 }
3769}
3770
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003771void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3772 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003773{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003774 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 +00003775 "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 +00003776 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003777
3778 try
3779 {
3780 if (level < 0 || width < 0 || height < 0)
3781 {
3782 return error(GL_INVALID_VALUE);
3783 }
3784
3785 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3786 {
3787 return error(GL_INVALID_VALUE);
3788 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003789
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003790 switch (target)
3791 {
3792 case GL_TEXTURE_2D:
3793 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3794 {
3795 return error(GL_INVALID_VALUE);
3796 }
3797 break;
3798 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3799 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3800 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3801 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3802 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3803 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003804 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003805 {
3806 return error(GL_INVALID_VALUE);
3807 }
3808
3809 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3810 {
3811 return error(GL_INVALID_VALUE);
3812 }
3813 break;
3814 default:
3815 return error(GL_INVALID_ENUM);
3816 }
3817
3818 if (internalformat != format)
3819 {
3820 return error(GL_INVALID_OPERATION);
3821 }
3822
3823 switch (internalformat)
3824 {
3825 case GL_ALPHA:
3826 case GL_LUMINANCE:
3827 case GL_LUMINANCE_ALPHA:
3828 switch (type)
3829 {
3830 case GL_UNSIGNED_BYTE:
3831 break;
3832 default:
3833 return error(GL_INVALID_ENUM);
3834 }
3835 break;
3836 case GL_RGB:
3837 switch (type)
3838 {
3839 case GL_UNSIGNED_BYTE:
3840 case GL_UNSIGNED_SHORT_5_6_5:
3841 break;
3842 default:
3843 return error(GL_INVALID_ENUM);
3844 }
3845 break;
3846 case GL_RGBA:
3847 switch (type)
3848 {
3849 case GL_UNSIGNED_BYTE:
3850 case GL_UNSIGNED_SHORT_4_4_4_4:
3851 case GL_UNSIGNED_SHORT_5_5_5_1:
3852 break;
3853 default:
3854 return error(GL_INVALID_ENUM);
3855 }
3856 break;
3857 default:
3858 return error(GL_INVALID_VALUE);
3859 }
3860
3861 if (border != 0)
3862 {
3863 return error(GL_INVALID_VALUE);
3864 }
3865
3866 gl::Context *context = gl::getContext();
3867
3868 if (context)
3869 {
3870 if (target == GL_TEXTURE_2D)
3871 {
3872 gl::Texture2D *texture = context->getTexture2D();
3873
3874 if (!texture)
3875 {
3876 return error(GL_INVALID_OPERATION);
3877 }
3878
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003879 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003880 }
3881 else
3882 {
3883 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3884
3885 if (!texture)
3886 {
3887 return error(GL_INVALID_OPERATION);
3888 }
3889
3890 switch (target)
3891 {
3892 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003893 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003894 break;
3895 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003896 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003897 break;
3898 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003899 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003900 break;
3901 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003902 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003903 break;
3904 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003905 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003906 break;
3907 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003908 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003909 break;
3910 default: UNREACHABLE();
3911 }
3912 }
3913 }
3914 }
3915 catch(std::bad_alloc&)
3916 {
3917 return error(GL_OUT_OF_MEMORY);
3918 }
3919}
3920
3921void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3922{
3923 glTexParameteri(target, pname, (GLint)param);
3924}
3925
3926void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3927{
3928 glTexParameteri(target, pname, (GLint)*params);
3929}
3930
3931void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3932{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003933 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003934
3935 try
3936 {
3937 gl::Context *context = gl::getContext();
3938
3939 if (context)
3940 {
3941 gl::Texture *texture;
3942
3943 switch (target)
3944 {
3945 case GL_TEXTURE_2D:
3946 texture = context->getTexture2D();
3947 break;
3948 case GL_TEXTURE_CUBE_MAP:
3949 texture = context->getTextureCubeMap();
3950 break;
3951 default:
3952 return error(GL_INVALID_ENUM);
3953 }
3954
3955 switch (pname)
3956 {
3957 case GL_TEXTURE_WRAP_S:
3958 if (!texture->setWrapS((GLenum)param))
3959 {
3960 return error(GL_INVALID_ENUM);
3961 }
3962 break;
3963 case GL_TEXTURE_WRAP_T:
3964 if (!texture->setWrapT((GLenum)param))
3965 {
3966 return error(GL_INVALID_ENUM);
3967 }
3968 break;
3969 case GL_TEXTURE_MIN_FILTER:
3970 if (!texture->setMinFilter((GLenum)param))
3971 {
3972 return error(GL_INVALID_ENUM);
3973 }
3974 break;
3975 case GL_TEXTURE_MAG_FILTER:
3976 if (!texture->setMagFilter((GLenum)param))
3977 {
3978 return error(GL_INVALID_ENUM);
3979 }
3980 break;
3981 default:
3982 return error(GL_INVALID_ENUM);
3983 }
3984 }
3985 }
3986 catch(std::bad_alloc&)
3987 {
3988 return error(GL_OUT_OF_MEMORY);
3989 }
3990}
3991
3992void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3993{
3994 glTexParameteri(target, pname, *params);
3995}
3996
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003997void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3998 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003999{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004000 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4001 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004002 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004003 target, level, xoffset, yoffset, width, height, format, type, pixels);
4004
4005 try
4006 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004007 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
4008 {
4009 return error(GL_INVALID_ENUM);
4010 }
4011
4012 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004013 {
4014 return error(GL_INVALID_VALUE);
4015 }
4016
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004017 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4018 {
4019 return error(GL_INVALID_VALUE);
4020 }
4021
4022 if (!es2dx::CheckTextureFormatType(format, type))
4023 {
4024 return error(GL_INVALID_ENUM);
4025 }
4026
4027 if (width == 0 || height == 0 || pixels == NULL)
4028 {
4029 return;
4030 }
4031
4032 gl::Context *context = gl::getContext();
4033
4034 if (context)
4035 {
4036 if (target == GL_TEXTURE_2D)
4037 {
4038 gl::Texture2D *texture = context->getTexture2D();
4039
4040 if (!texture)
4041 {
4042 return error(GL_INVALID_OPERATION);
4043 }
4044
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004045 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004046 }
4047 else if (es2dx::IsCubemapTextureTarget(target))
4048 {
4049 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4050
4051 if (!texture)
4052 {
4053 return error(GL_INVALID_OPERATION);
4054 }
4055
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004056 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004057 }
4058 else
4059 {
4060 UNREACHABLE();
4061 }
4062 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004063 }
4064 catch(std::bad_alloc&)
4065 {
4066 return error(GL_OUT_OF_MEMORY);
4067 }
4068}
4069
4070void __stdcall glUniform1f(GLint location, GLfloat x)
4071{
4072 glUniform1fv(location, 1, &x);
4073}
4074
4075void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4076{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004077 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004078
4079 try
4080 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004081 if (count < 0)
4082 {
4083 return error(GL_INVALID_VALUE);
4084 }
4085
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004086 if (location == -1)
4087 {
4088 return;
4089 }
4090
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004091 gl::Context *context = gl::getContext();
4092
4093 if (context)
4094 {
4095 gl::Program *program = context->getCurrentProgram();
4096
4097 if (!program)
4098 {
4099 return error(GL_INVALID_OPERATION);
4100 }
4101
4102 if (!program->setUniform1fv(location, count, v))
4103 {
4104 return error(GL_INVALID_OPERATION);
4105 }
4106 }
4107 }
4108 catch(std::bad_alloc&)
4109 {
4110 return error(GL_OUT_OF_MEMORY);
4111 }
4112}
4113
4114void __stdcall glUniform1i(GLint location, GLint x)
4115{
4116 glUniform1iv(location, 1, &x);
4117}
4118
4119void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4120{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004121 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004122
4123 try
4124 {
4125 if (count < 0)
4126 {
4127 return error(GL_INVALID_VALUE);
4128 }
4129
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004130 if (location == -1)
4131 {
4132 return;
4133 }
4134
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004135 gl::Context *context = gl::getContext();
4136
4137 if (context)
4138 {
4139 gl::Program *program = context->getCurrentProgram();
4140
4141 if (!program)
4142 {
4143 return error(GL_INVALID_OPERATION);
4144 }
4145
4146 if (!program->setUniform1iv(location, count, v))
4147 {
4148 return error(GL_INVALID_OPERATION);
4149 }
4150 }
4151 }
4152 catch(std::bad_alloc&)
4153 {
4154 return error(GL_OUT_OF_MEMORY);
4155 }
4156}
4157
4158void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4159{
4160 GLfloat xy[2] = {x, y};
4161
4162 glUniform2fv(location, 1, (GLfloat*)&xy);
4163}
4164
4165void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4166{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004167 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004168
4169 try
4170 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004171 if (count < 0)
4172 {
4173 return error(GL_INVALID_VALUE);
4174 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004175
4176 if (location == -1)
4177 {
4178 return;
4179 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004180
4181 gl::Context *context = gl::getContext();
4182
4183 if (context)
4184 {
4185 gl::Program *program = context->getCurrentProgram();
4186
4187 if (!program)
4188 {
4189 return error(GL_INVALID_OPERATION);
4190 }
4191
4192 if (!program->setUniform2fv(location, count, v))
4193 {
4194 return error(GL_INVALID_OPERATION);
4195 }
4196 }
4197 }
4198 catch(std::bad_alloc&)
4199 {
4200 return error(GL_OUT_OF_MEMORY);
4201 }
4202}
4203
4204void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4205{
4206 GLint xy[4] = {x, y};
4207
4208 glUniform2iv(location, 1, (GLint*)&xy);
4209}
4210
4211void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4212{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004213 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004214
4215 try
4216 {
4217 if (count < 0)
4218 {
4219 return error(GL_INVALID_VALUE);
4220 }
4221
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004222 if (location == -1)
4223 {
4224 return;
4225 }
4226
4227 gl::Context *context = gl::getContext();
4228
4229 if (context)
4230 {
4231 gl::Program *program = context->getCurrentProgram();
4232
4233 if (!program)
4234 {
4235 return error(GL_INVALID_OPERATION);
4236 }
4237
4238 if (!program->setUniform2iv(location, count, v))
4239 {
4240 return error(GL_INVALID_OPERATION);
4241 }
4242 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004243 }
4244 catch(std::bad_alloc&)
4245 {
4246 return error(GL_OUT_OF_MEMORY);
4247 }
4248}
4249
4250void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4251{
4252 GLfloat xyz[3] = {x, y, z};
4253
4254 glUniform3fv(location, 1, (GLfloat*)&xyz);
4255}
4256
4257void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4258{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004259 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004260
4261 try
4262 {
4263 if (count < 0)
4264 {
4265 return error(GL_INVALID_VALUE);
4266 }
4267
4268 if (location == -1)
4269 {
4270 return;
4271 }
4272
4273 gl::Context *context = gl::getContext();
4274
4275 if (context)
4276 {
4277 gl::Program *program = context->getCurrentProgram();
4278
4279 if (!program)
4280 {
4281 return error(GL_INVALID_OPERATION);
4282 }
4283
4284 if (!program->setUniform3fv(location, count, v))
4285 {
4286 return error(GL_INVALID_OPERATION);
4287 }
4288 }
4289 }
4290 catch(std::bad_alloc&)
4291 {
4292 return error(GL_OUT_OF_MEMORY);
4293 }
4294}
4295
4296void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4297{
4298 GLint xyz[3] = {x, y, z};
4299
4300 glUniform3iv(location, 1, (GLint*)&xyz);
4301}
4302
4303void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4304{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004305 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004306
4307 try
4308 {
4309 if (count < 0)
4310 {
4311 return error(GL_INVALID_VALUE);
4312 }
4313
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004314 if (location == -1)
4315 {
4316 return;
4317 }
4318
4319 gl::Context *context = gl::getContext();
4320
4321 if (context)
4322 {
4323 gl::Program *program = context->getCurrentProgram();
4324
4325 if (!program)
4326 {
4327 return error(GL_INVALID_OPERATION);
4328 }
4329
4330 if (!program->setUniform3iv(location, count, v))
4331 {
4332 return error(GL_INVALID_OPERATION);
4333 }
4334 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004335 }
4336 catch(std::bad_alloc&)
4337 {
4338 return error(GL_OUT_OF_MEMORY);
4339 }
4340}
4341
4342void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4343{
4344 GLfloat xyzw[4] = {x, y, z, w};
4345
4346 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4347}
4348
4349void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4350{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004351 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004352
4353 try
4354 {
4355 if (count < 0)
4356 {
4357 return error(GL_INVALID_VALUE);
4358 }
4359
4360 if (location == -1)
4361 {
4362 return;
4363 }
4364
4365 gl::Context *context = gl::getContext();
4366
4367 if (context)
4368 {
4369 gl::Program *program = context->getCurrentProgram();
4370
4371 if (!program)
4372 {
4373 return error(GL_INVALID_OPERATION);
4374 }
4375
4376 if (!program->setUniform4fv(location, count, v))
4377 {
4378 return error(GL_INVALID_OPERATION);
4379 }
4380 }
4381 }
4382 catch(std::bad_alloc&)
4383 {
4384 return error(GL_OUT_OF_MEMORY);
4385 }
4386}
4387
4388void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4389{
4390 GLint xyzw[4] = {x, y, z, w};
4391
4392 glUniform4iv(location, 1, (GLint*)&xyzw);
4393}
4394
4395void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4396{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004397 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004398
4399 try
4400 {
4401 if (count < 0)
4402 {
4403 return error(GL_INVALID_VALUE);
4404 }
4405
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004406 if (location == -1)
4407 {
4408 return;
4409 }
4410
4411 gl::Context *context = gl::getContext();
4412
4413 if (context)
4414 {
4415 gl::Program *program = context->getCurrentProgram();
4416
4417 if (!program)
4418 {
4419 return error(GL_INVALID_OPERATION);
4420 }
4421
4422 if (!program->setUniform4iv(location, count, v))
4423 {
4424 return error(GL_INVALID_OPERATION);
4425 }
4426 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004427 }
4428 catch(std::bad_alloc&)
4429 {
4430 return error(GL_OUT_OF_MEMORY);
4431 }
4432}
4433
4434void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4435{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004436 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4437 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004438
4439 try
4440 {
4441 if (count < 0 || transpose != GL_FALSE)
4442 {
4443 return error(GL_INVALID_VALUE);
4444 }
4445
4446 if (location == -1)
4447 {
4448 return;
4449 }
4450
4451 gl::Context *context = gl::getContext();
4452
4453 if (context)
4454 {
4455 gl::Program *program = context->getCurrentProgram();
4456
4457 if (!program)
4458 {
4459 return error(GL_INVALID_OPERATION);
4460 }
4461
4462 if (!program->setUniformMatrix2fv(location, count, value))
4463 {
4464 return error(GL_INVALID_OPERATION);
4465 }
4466 }
4467 }
4468 catch(std::bad_alloc&)
4469 {
4470 return error(GL_OUT_OF_MEMORY);
4471 }
4472}
4473
4474void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4475{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004476 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4477 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004478
4479 try
4480 {
4481 if (count < 0 || transpose != GL_FALSE)
4482 {
4483 return error(GL_INVALID_VALUE);
4484 }
4485
4486 if (location == -1)
4487 {
4488 return;
4489 }
4490
4491 gl::Context *context = gl::getContext();
4492
4493 if (context)
4494 {
4495 gl::Program *program = context->getCurrentProgram();
4496
4497 if (!program)
4498 {
4499 return error(GL_INVALID_OPERATION);
4500 }
4501
4502 if (!program->setUniformMatrix3fv(location, count, value))
4503 {
4504 return error(GL_INVALID_OPERATION);
4505 }
4506 }
4507 }
4508 catch(std::bad_alloc&)
4509 {
4510 return error(GL_OUT_OF_MEMORY);
4511 }
4512}
4513
4514void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4515{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004516 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4517 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004518
4519 try
4520 {
4521 if (count < 0 || transpose != GL_FALSE)
4522 {
4523 return error(GL_INVALID_VALUE);
4524 }
4525
4526 if (location == -1)
4527 {
4528 return;
4529 }
4530
4531 gl::Context *context = gl::getContext();
4532
4533 if (context)
4534 {
4535 gl::Program *program = context->getCurrentProgram();
4536
4537 if (!program)
4538 {
4539 return error(GL_INVALID_OPERATION);
4540 }
4541
4542 if (!program->setUniformMatrix4fv(location, count, value))
4543 {
4544 return error(GL_INVALID_OPERATION);
4545 }
4546 }
4547 }
4548 catch(std::bad_alloc&)
4549 {
4550 return error(GL_OUT_OF_MEMORY);
4551 }
4552}
4553
4554void __stdcall glUseProgram(GLuint program)
4555{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004556 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004557
4558 try
4559 {
4560 gl::Context *context = gl::getContext();
4561
4562 if (context)
4563 {
4564 gl::Program *programObject = context->getProgram(program);
4565
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004566 if (!programObject && program != 0)
4567 {
4568 if (context->getShader(program))
4569 {
4570 return error(GL_INVALID_OPERATION);
4571 }
4572 else
4573 {
4574 return error(GL_INVALID_VALUE);
4575 }
4576 }
4577
4578 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004579 {
4580 return error(GL_INVALID_OPERATION);
4581 }
4582
4583 context->useProgram(program);
4584 }
4585 }
4586 catch(std::bad_alloc&)
4587 {
4588 return error(GL_OUT_OF_MEMORY);
4589 }
4590}
4591
4592void __stdcall glValidateProgram(GLuint program)
4593{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004594 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004595
4596 try
4597 {
4598 UNIMPLEMENTED(); // FIXME
4599 }
4600 catch(std::bad_alloc&)
4601 {
4602 return error(GL_OUT_OF_MEMORY);
4603 }
4604}
4605
4606void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4607{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004608 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004609
4610 try
4611 {
4612 if (index >= gl::MAX_VERTEX_ATTRIBS)
4613 {
4614 return error(GL_INVALID_VALUE);
4615 }
4616
4617 UNIMPLEMENTED(); // FIXME
4618 }
4619 catch(std::bad_alloc&)
4620 {
4621 return error(GL_OUT_OF_MEMORY);
4622 }
4623}
4624
4625void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4626{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004627 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004628
4629 try
4630 {
4631 if (index >= gl::MAX_VERTEX_ATTRIBS)
4632 {
4633 return error(GL_INVALID_VALUE);
4634 }
4635
4636 UNIMPLEMENTED(); // FIXME
4637 }
4638 catch(std::bad_alloc&)
4639 {
4640 return error(GL_OUT_OF_MEMORY);
4641 }
4642}
4643
4644void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4645{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004646 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004647
4648 try
4649 {
4650 if (index >= gl::MAX_VERTEX_ATTRIBS)
4651 {
4652 return error(GL_INVALID_VALUE);
4653 }
4654
4655 UNIMPLEMENTED(); // FIXME
4656 }
4657 catch(std::bad_alloc&)
4658 {
4659 return error(GL_OUT_OF_MEMORY);
4660 }
4661}
4662
4663void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4664{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004665 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004666
4667 try
4668 {
4669 if (index >= gl::MAX_VERTEX_ATTRIBS)
4670 {
4671 return error(GL_INVALID_VALUE);
4672 }
4673
4674 UNIMPLEMENTED(); // FIXME
4675 }
4676 catch(std::bad_alloc&)
4677 {
4678 return error(GL_OUT_OF_MEMORY);
4679 }
4680}
4681
4682void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4683{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004684 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 +00004685
4686 try
4687 {
4688 if (index >= gl::MAX_VERTEX_ATTRIBS)
4689 {
4690 return error(GL_INVALID_VALUE);
4691 }
4692
4693 UNIMPLEMENTED(); // FIXME
4694 }
4695 catch(std::bad_alloc&)
4696 {
4697 return error(GL_OUT_OF_MEMORY);
4698 }
4699}
4700
4701void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4702{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004703 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004704
4705 try
4706 {
4707 if (index >= gl::MAX_VERTEX_ATTRIBS)
4708 {
4709 return error(GL_INVALID_VALUE);
4710 }
4711
4712 UNIMPLEMENTED(); // FIXME
4713 }
4714 catch(std::bad_alloc&)
4715 {
4716 return error(GL_OUT_OF_MEMORY);
4717 }
4718}
4719
4720void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4721{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004722 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 +00004723
4724 try
4725 {
4726 if (index >= gl::MAX_VERTEX_ATTRIBS)
4727 {
4728 return error(GL_INVALID_VALUE);
4729 }
4730
4731 UNIMPLEMENTED(); // FIXME
4732 }
4733 catch(std::bad_alloc&)
4734 {
4735 return error(GL_OUT_OF_MEMORY);
4736 }
4737}
4738
4739void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4740{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004741 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004742
4743 try
4744 {
4745 if (index >= gl::MAX_VERTEX_ATTRIBS)
4746 {
4747 return error(GL_INVALID_VALUE);
4748 }
4749
4750 UNIMPLEMENTED(); // FIXME
4751 }
4752 catch(std::bad_alloc&)
4753 {
4754 return error(GL_OUT_OF_MEMORY);
4755 }
4756}
4757
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004758void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004759{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004760 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004761 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004762 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004763
4764 try
4765 {
4766 if (index >= gl::MAX_VERTEX_ATTRIBS)
4767 {
4768 return error(GL_INVALID_VALUE);
4769 }
4770
4771 if (size < 1 || size > 4)
4772 {
4773 return error(GL_INVALID_VALUE);
4774 }
4775
4776 switch (type)
4777 {
4778 case GL_BYTE:
4779 case GL_UNSIGNED_BYTE:
4780 case GL_SHORT:
4781 case GL_UNSIGNED_SHORT:
4782 case GL_FIXED:
4783 case GL_FLOAT:
4784 break;
4785 default:
4786 return error(GL_INVALID_ENUM);
4787 }
4788
4789 if (stride < 0)
4790 {
4791 return error(GL_INVALID_VALUE);
4792 }
4793
4794 gl::Context *context = gl::getContext();
4795
4796 if (context)
4797 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004798 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4799 context->vertexAttribute[index].mSize = size;
4800 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004801 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004802 context->vertexAttribute[index].mStride = stride;
4803 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004804 }
4805 }
4806 catch(std::bad_alloc&)
4807 {
4808 return error(GL_OUT_OF_MEMORY);
4809 }
4810}
4811
4812void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4813{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004814 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 +00004815
4816 try
4817 {
4818 if (width < 0 || height < 0)
4819 {
4820 return error(GL_INVALID_VALUE);
4821 }
4822
4823 gl::Context *context = gl::getContext();
4824
4825 if (context)
4826 {
4827 context->viewportX = x;
4828 context->viewportY = y;
4829 context->viewportWidth = width;
4830 context->viewportHeight = height;
4831 }
4832 }
4833 catch(std::bad_alloc&)
4834 {
4835 return error(GL_OUT_OF_MEMORY);
4836 }
4837}
4838
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004839void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4840 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004841{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004842 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4843 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004844 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004845 target, level, internalformat, width, height, depth, border, format, type, pixels);
4846
4847 try
4848 {
4849 UNIMPLEMENTED(); // FIXME
4850 }
4851 catch(std::bad_alloc&)
4852 {
4853 return error(GL_OUT_OF_MEMORY);
4854 }
4855}
4856}