blob: ecd66c6a511d0b33a4ef717841ea7d787d5a350a [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
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016#include "Context.h"
17#include "main.h"
18#include "Program.h"
19#include "Shader.h"
20#include "Buffer.h"
21#include "Texture.h"
22#include "Renderbuffer.h"
23#include "Framebuffer.h"
24#include "mathutil.h"
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000025#include "common/debug.h"
daniel@transgaming.com00c75962010-03-11 20:36:15 +000026#include "utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027
28extern "C"
29{
30
31void __stdcall glActiveTexture(GLenum texture)
32{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000033 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034
35 try
36 {
37 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
38 {
39 return error(GL_INVALID_ENUM);
40 }
41
42 gl::Context *context = gl::getContext();
43
44 if (context)
45 {
46 context->activeSampler = texture - GL_TEXTURE0;
47 }
48 }
49 catch(std::bad_alloc&)
50 {
51 return error(GL_OUT_OF_MEMORY);
52 }
53}
54
55void __stdcall glAttachShader(GLuint program, GLuint shader)
56{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000057 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000058
59 try
60 {
61 gl::Context *context = gl::getContext();
62
63 if (context)
64 {
65 gl::Program *programObject = context->getProgram(program);
66 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000067
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000068 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000069 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000070 if (context->getShader(program))
71 {
72 return error(GL_INVALID_OPERATION);
73 }
74 else
75 {
76 return error(GL_INVALID_VALUE);
77 }
78 }
79
80 if (!shaderObject)
81 {
82 if (context->getProgram(shader))
83 {
84 return error(GL_INVALID_OPERATION);
85 }
86 else
87 {
88 return error(GL_INVALID_VALUE);
89 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090 }
91
92 if (!programObject->attachShader(shaderObject))
93 {
94 return error(GL_INVALID_OPERATION);
95 }
96 }
97 }
98 catch(std::bad_alloc&)
99 {
100 return error(GL_OUT_OF_MEMORY);
101 }
102}
103
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000104void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000105{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000106 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107
108 try
109 {
110 if (index >= gl::MAX_VERTEX_ATTRIBS)
111 {
112 return error(GL_INVALID_VALUE);
113 }
114
115 gl::Context *context = gl::getContext();
116
117 if (context)
118 {
119 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000120
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000121 if (!programObject)
122 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000123 if (context->getShader(program))
124 {
125 return error(GL_INVALID_OPERATION);
126 }
127 else
128 {
129 return error(GL_INVALID_VALUE);
130 }
131 }
132
133 if (strncmp(name, "gl_", 3) == 0)
134 {
135 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000136 }
137
138 programObject->bindAttributeLocation(index, name);
139 }
140 }
141 catch(std::bad_alloc&)
142 {
143 return error(GL_OUT_OF_MEMORY);
144 }
145}
146
147void __stdcall glBindBuffer(GLenum target, GLuint buffer)
148{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000149 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150
151 try
152 {
153 gl::Context *context = gl::getContext();
154
155 if (context)
156 {
157 switch (target)
158 {
159 case GL_ARRAY_BUFFER:
160 context->bindArrayBuffer(buffer);
161 return;
162 case GL_ELEMENT_ARRAY_BUFFER:
163 context->bindElementArrayBuffer(buffer);
164 return;
165 default:
166 return error(GL_INVALID_ENUM);
167 }
168 }
169 }
170 catch(std::bad_alloc&)
171 {
172 return error(GL_OUT_OF_MEMORY);
173 }
174}
175
176void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
177{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000178 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000179
180 try
181 {
182 if (target != GL_FRAMEBUFFER)
183 {
184 return error(GL_INVALID_ENUM);
185 }
186
187 gl::Context *context = gl::getContext();
188
189 if (context)
190 {
191 context->bindFramebuffer(framebuffer);
192 }
193 }
194 catch(std::bad_alloc&)
195 {
196 return error(GL_OUT_OF_MEMORY);
197 }
198}
199
200void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
201{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000202 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203
204 try
205 {
206 if (target != GL_RENDERBUFFER)
207 {
208 return error(GL_INVALID_ENUM);
209 }
210
211 gl::Context *context = gl::getContext();
212
213 if (context)
214 {
215 context->bindRenderbuffer(renderbuffer);
216 }
217 }
218 catch(std::bad_alloc&)
219 {
220 return error(GL_OUT_OF_MEMORY);
221 }
222}
223
224void __stdcall glBindTexture(GLenum target, GLuint texture)
225{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000226 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227
228 try
229 {
230 gl::Context *context = gl::getContext();
231
232 if (context)
233 {
234 gl::Texture *textureObject = context->getTexture(texture);
235
236 if (textureObject && textureObject->getTarget() != target && texture != 0)
237 {
238 return error(GL_INVALID_OPERATION);
239 }
240
241 switch (target)
242 {
243 case GL_TEXTURE_2D:
244 context->bindTexture2D(texture);
245 return;
246 case GL_TEXTURE_CUBE_MAP:
247 context->bindTextureCubeMap(texture);
248 return;
249 default:
250 return error(GL_INVALID_ENUM);
251 }
252 }
253 }
254 catch(std::bad_alloc&)
255 {
256 return error(GL_OUT_OF_MEMORY);
257 }
258}
259
260void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
261{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000262 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
263 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264
265 try
266 {
267 gl::Context* context = gl::getContext();
268
269 if (context)
270 {
271 context->blendColor.red = gl::clamp01(red);
272 context->blendColor.blue = gl::clamp01(blue);
273 context->blendColor.green = gl::clamp01(green);
274 context->blendColor.alpha = gl::clamp01(alpha);
275 }
276 }
277 catch(std::bad_alloc&)
278 {
279 return error(GL_OUT_OF_MEMORY);
280 }
281}
282
283void __stdcall glBlendEquation(GLenum mode)
284{
285 glBlendEquationSeparate(mode, mode);
286}
287
288void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
289{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000290 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000291
292 try
293 {
294 switch (modeRGB)
295 {
296 case GL_FUNC_ADD:
297 case GL_FUNC_SUBTRACT:
298 case GL_FUNC_REVERSE_SUBTRACT:
299 break;
300 default:
301 return error(GL_INVALID_ENUM);
302 }
303
304 switch (modeAlpha)
305 {
306 case GL_FUNC_ADD:
307 case GL_FUNC_SUBTRACT:
308 case GL_FUNC_REVERSE_SUBTRACT:
309 break;
310 default:
311 return error(GL_INVALID_ENUM);
312 }
313
314 gl::Context *context = gl::getContext();
315
316 if (context)
317 {
318 context->blendEquationRGB = modeRGB;
319 context->blendEquationAlpha = modeAlpha;
320 }
321 }
322 catch(std::bad_alloc&)
323 {
324 return error(GL_OUT_OF_MEMORY);
325 }
326}
327
328void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
329{
330 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
331}
332
333void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
334{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000335 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
336 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000337
338 try
339 {
340 switch (srcRGB)
341 {
342 case GL_ZERO:
343 case GL_ONE:
344 case GL_SRC_COLOR:
345 case GL_ONE_MINUS_SRC_COLOR:
346 case GL_DST_COLOR:
347 case GL_ONE_MINUS_DST_COLOR:
348 case GL_SRC_ALPHA:
349 case GL_ONE_MINUS_SRC_ALPHA:
350 case GL_DST_ALPHA:
351 case GL_ONE_MINUS_DST_ALPHA:
352 case GL_CONSTANT_COLOR:
353 case GL_ONE_MINUS_CONSTANT_COLOR:
354 case GL_CONSTANT_ALPHA:
355 case GL_ONE_MINUS_CONSTANT_ALPHA:
356 case GL_SRC_ALPHA_SATURATE:
357 break;
358 default:
359 return error(GL_INVALID_ENUM);
360 }
361
362 switch (dstRGB)
363 {
364 case GL_ZERO:
365 case GL_ONE:
366 case GL_SRC_COLOR:
367 case GL_ONE_MINUS_SRC_COLOR:
368 case GL_DST_COLOR:
369 case GL_ONE_MINUS_DST_COLOR:
370 case GL_SRC_ALPHA:
371 case GL_ONE_MINUS_SRC_ALPHA:
372 case GL_DST_ALPHA:
373 case GL_ONE_MINUS_DST_ALPHA:
374 case GL_CONSTANT_COLOR:
375 case GL_ONE_MINUS_CONSTANT_COLOR:
376 case GL_CONSTANT_ALPHA:
377 case GL_ONE_MINUS_CONSTANT_ALPHA:
378 break;
379 default:
380 return error(GL_INVALID_ENUM);
381 }
382
383 switch (srcAlpha)
384 {
385 case GL_ZERO:
386 case GL_ONE:
387 case GL_SRC_COLOR:
388 case GL_ONE_MINUS_SRC_COLOR:
389 case GL_DST_COLOR:
390 case GL_ONE_MINUS_DST_COLOR:
391 case GL_SRC_ALPHA:
392 case GL_ONE_MINUS_SRC_ALPHA:
393 case GL_DST_ALPHA:
394 case GL_ONE_MINUS_DST_ALPHA:
395 case GL_CONSTANT_COLOR:
396 case GL_ONE_MINUS_CONSTANT_COLOR:
397 case GL_CONSTANT_ALPHA:
398 case GL_ONE_MINUS_CONSTANT_ALPHA:
399 case GL_SRC_ALPHA_SATURATE:
400 break;
401 default:
402 return error(GL_INVALID_ENUM);
403 }
404
405 switch (dstAlpha)
406 {
407 case GL_ZERO:
408 case GL_ONE:
409 case GL_SRC_COLOR:
410 case GL_ONE_MINUS_SRC_COLOR:
411 case GL_DST_COLOR:
412 case GL_ONE_MINUS_DST_COLOR:
413 case GL_SRC_ALPHA:
414 case GL_ONE_MINUS_SRC_ALPHA:
415 case GL_DST_ALPHA:
416 case GL_ONE_MINUS_DST_ALPHA:
417 case GL_CONSTANT_COLOR:
418 case GL_ONE_MINUS_CONSTANT_COLOR:
419 case GL_CONSTANT_ALPHA:
420 case GL_ONE_MINUS_CONSTANT_ALPHA:
421 break;
422 default:
423 return error(GL_INVALID_ENUM);
424 }
425
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000426 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
427 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
428
429 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
430 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
431
432 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000433 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000434 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
435 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000436 }
437
438 gl::Context *context = gl::getContext();
439
440 if (context)
441 {
442 context->sourceBlendRGB = srcRGB;
443 context->sourceBlendAlpha = srcAlpha;
444 context->destBlendRGB = dstRGB;
445 context->destBlendAlpha = dstAlpha;
446 }
447 }
448 catch(std::bad_alloc&)
449 {
450 return error(GL_OUT_OF_MEMORY);
451 }
452}
453
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000454void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000455{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000456 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 +0000457 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000458
459 try
460 {
461 if (size < 0)
462 {
463 return error(GL_INVALID_VALUE);
464 }
465
466 switch (usage)
467 {
468 case GL_STREAM_DRAW:
469 case GL_STATIC_DRAW:
470 case GL_DYNAMIC_DRAW:
471 break;
472 default:
473 return error(GL_INVALID_ENUM);
474 }
475
476 gl::Context *context = gl::getContext();
477
478 if (context)
479 {
480 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000481
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000482 switch (target)
483 {
484 case GL_ARRAY_BUFFER:
485 buffer = context->getArrayBuffer();
486 break;
487 case GL_ELEMENT_ARRAY_BUFFER:
488 buffer = context->getElementArrayBuffer();
489 break;
490 default:
491 return error(GL_INVALID_ENUM);
492 }
493
494 if (!buffer)
495 {
496 return error(GL_INVALID_OPERATION);
497 }
498
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000499 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000500 }
501 }
502 catch(std::bad_alloc&)
503 {
504 return error(GL_OUT_OF_MEMORY);
505 }
506}
507
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000508void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000509{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000510 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 +0000511 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512
513 try
514 {
515 if (size < 0)
516 {
517 return error(GL_INVALID_VALUE);
518 }
519
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000520 if (data == NULL)
521 {
522 return;
523 }
524
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000525 gl::Context *context = gl::getContext();
526
527 if (context)
528 {
529 gl::Buffer *buffer;
530
531 switch (target)
532 {
533 case GL_ARRAY_BUFFER:
534 buffer = context->getArrayBuffer();
535 break;
536 case GL_ELEMENT_ARRAY_BUFFER:
537 buffer = context->getElementArrayBuffer();
538 break;
539 default:
540 return error(GL_INVALID_ENUM);
541 }
542
543 if (!buffer)
544 {
545 return error(GL_INVALID_OPERATION);
546 }
547
548 GLenum err = buffer->bufferSubData(data, size, offset);
549
550 if (err != GL_NO_ERROR)
551 {
552 return error(err);
553 }
554 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000555 }
556 catch(std::bad_alloc&)
557 {
558 return error(GL_OUT_OF_MEMORY);
559 }
560}
561
562GLenum __stdcall glCheckFramebufferStatus(GLenum target)
563{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000564 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000565
566 try
567 {
568 if (target != GL_FRAMEBUFFER)
569 {
570 return error(GL_INVALID_ENUM, 0);
571 }
572
573 gl::Context *context = gl::getContext();
574
575 if (context)
576 {
577 gl::Framebuffer *framebuffer = context->getFramebuffer();
578
579 return framebuffer->completeness();
580 }
581 }
582 catch(std::bad_alloc&)
583 {
584 return error(GL_OUT_OF_MEMORY, 0);
585 }
586
587 return 0;
588}
589
590void __stdcall glClear(GLbitfield mask)
591{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000592 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000593
594 try
595 {
596 gl::Context *context = gl::getContext();
597
598 if (context)
599 {
600 context->clear(mask);
601 }
602 }
603 catch(std::bad_alloc&)
604 {
605 return error(GL_OUT_OF_MEMORY);
606 }
607}
608
609void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
610{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000611 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
612 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000613
614 try
615 {
616 gl::Context *context = gl::getContext();
617
618 if (context)
619 {
620 context->setClearColor(red, green, blue, alpha);
621 }
622 }
623 catch(std::bad_alloc&)
624 {
625 return error(GL_OUT_OF_MEMORY);
626 }
627}
628
629void __stdcall glClearDepthf(GLclampf depth)
630{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000631 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000632
633 try
634 {
635 gl::Context *context = gl::getContext();
636
637 if (context)
638 {
639 context->setClearDepth(depth);
640 }
641 }
642 catch(std::bad_alloc&)
643 {
644 return error(GL_OUT_OF_MEMORY);
645 }
646}
647
648void __stdcall glClearStencil(GLint s)
649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000650 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000651
652 try
653 {
654 gl::Context *context = gl::getContext();
655
656 if (context)
657 {
658 context->setClearStencil(s);
659 }
660 }
661 catch(std::bad_alloc&)
662 {
663 return error(GL_OUT_OF_MEMORY);
664 }
665}
666
667void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
668{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000669 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
670 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000671
672 try
673 {
674 gl::Context *context = gl::getContext();
675
676 if (context)
677 {
678 context->colorMaskRed = red != GL_FALSE;
679 context->colorMaskGreen = green != GL_FALSE;
680 context->colorMaskBlue = blue != GL_FALSE;
681 context->colorMaskAlpha = alpha != GL_FALSE;
682 }
683 }
684 catch(std::bad_alloc&)
685 {
686 return error(GL_OUT_OF_MEMORY);
687 }
688}
689
690void __stdcall glCompileShader(GLuint shader)
691{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000692 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000693
694 try
695 {
696 gl::Context *context = gl::getContext();
697
698 if (context)
699 {
700 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000701
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000702 if (!shaderObject)
703 {
704 return error(GL_INVALID_VALUE);
705 }
706
707 shaderObject->compile();
708 }
709 }
710 catch(std::bad_alloc&)
711 {
712 return error(GL_OUT_OF_MEMORY);
713 }
714}
715
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000716void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
717 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000718{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000719 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000720 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000721 target, level, internalformat, width, height, border, imageSize, data);
722
723 try
724 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000725 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
726 {
727 return error(GL_INVALID_ENUM);
728 }
729
730 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000731 {
732 return error(GL_INVALID_VALUE);
733 }
734
daniel@transgaming.com41430492010-03-11 20:36:18 +0000735 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
736 {
737 return error(GL_INVALID_VALUE);
738 }
739
740 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000741 }
742 catch(std::bad_alloc&)
743 {
744 return error(GL_OUT_OF_MEMORY);
745 }
746}
747
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000748void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
749 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000750{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000751 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
752 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000753 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000754 target, level, xoffset, yoffset, width, height, format, imageSize, data);
755
756 try
757 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000758 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
759 {
760 return error(GL_INVALID_ENUM);
761 }
762
763 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000764 {
765 return error(GL_INVALID_VALUE);
766 }
767
daniel@transgaming.com41430492010-03-11 20:36:18 +0000768 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
769 {
770 return error(GL_INVALID_VALUE);
771 }
772
773 if (xoffset != 0 || yoffset != 0)
774 {
775 return error(GL_INVALID_OPERATION);
776 }
777
778 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000779 }
780 catch(std::bad_alloc&)
781 {
782 return error(GL_OUT_OF_MEMORY);
783 }
784}
785
786void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
787{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000788 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
789 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000790 target, level, internalformat, x, y, width, height, border);
791
792 try
793 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000794 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000795 {
796 return error(GL_INVALID_VALUE);
797 }
798
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000799 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
800 {
801 return error(GL_INVALID_VALUE);
802 }
803
804 switch (target)
805 {
806 case GL_TEXTURE_2D:
807 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
808 {
809 return error(GL_INVALID_VALUE);
810 }
811 break;
812 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
813 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
814 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
815 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
816 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
817 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
818 if (!gl::isPow2(width) || !gl::isPow2(height))
819 {
820 return error(GL_INVALID_VALUE);
821 }
822
823 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
824 {
825 return error(GL_INVALID_VALUE);
826 }
827 break;
828 default:
829 return error(GL_INVALID_ENUM);
830 }
831
832 switch (internalformat)
833 {
834 case GL_ALPHA:
835 case GL_LUMINANCE:
836 case GL_LUMINANCE_ALPHA:
837 case GL_RGB:
838 case GL_RGBA:
839 break;
840 default:
841 return error(GL_INVALID_VALUE);
842 }
843
844 if (border != 0)
845 {
846 return error(GL_INVALID_VALUE);
847 }
848
849 gl::Context *context = gl::getContext();
850
851 if (context)
852 {
853 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
854
855 if (target == GL_TEXTURE_2D)
856 {
857 gl::Texture2D *texture = context->getTexture2D();
858
859 if (!texture)
860 {
861 return error(GL_INVALID_OPERATION);
862 }
863
864 texture->copyImage(level, internalformat, x, y, width, height, source);
865 }
866 else if (es2dx::IsCubemapTextureTarget(target))
867 {
868 gl::TextureCubeMap *texture = context->getTextureCubeMap();
869
870 if (!texture)
871 {
872 return error(GL_INVALID_OPERATION);
873 }
874
875 texture->copyImage(target, level, internalformat, x, y, width, height, source);
876 }
877 else
878 {
879 UNREACHABLE();
880 }
881 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000882 }
883 catch(std::bad_alloc&)
884 {
885 return error(GL_OUT_OF_MEMORY);
886 }
887}
888
889void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
890{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000891 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
892 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000893 target, level, xoffset, yoffset, x, y, width, height);
894
895 try
896 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000897 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
898 {
899 return error(GL_INVALID_ENUM);
900 }
901
902 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000903 {
904 return error(GL_INVALID_VALUE);
905 }
906
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000907 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
908 {
909 return error(GL_INVALID_VALUE);
910 }
911
912 if (width == 0 || height == 0)
913 {
914 return;
915 }
916
917 gl::Context *context = gl::getContext();
918
919 if (context)
920 {
921 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
922
923 if (target == GL_TEXTURE_2D)
924 {
925 gl::Texture2D *texture = context->getTexture2D();
926
927 if (!texture)
928 {
929 return error(GL_INVALID_OPERATION);
930 }
931
932 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
933 }
934 else if (es2dx::IsCubemapTextureTarget(target))
935 {
936 gl::TextureCubeMap *texture = context->getTextureCubeMap();
937
938 if (!texture)
939 {
940 return error(GL_INVALID_OPERATION);
941 }
942
943 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
944 }
945 else
946 {
947 UNREACHABLE();
948 }
949 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000950 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000951
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000952 catch(std::bad_alloc&)
953 {
954 return error(GL_OUT_OF_MEMORY);
955 }
956}
957
958GLuint __stdcall glCreateProgram(void)
959{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000960 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000961
962 try
963 {
964 gl::Context *context = gl::getContext();
965
966 if (context)
967 {
968 return context->createProgram();
969 }
970 }
971 catch(std::bad_alloc&)
972 {
973 return error(GL_OUT_OF_MEMORY, 0);
974 }
975
976 return 0;
977}
978
979GLuint __stdcall glCreateShader(GLenum type)
980{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000981 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000982
983 try
984 {
985 gl::Context *context = gl::getContext();
986
987 if (context)
988 {
989 switch (type)
990 {
991 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000992 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000993 return context->createShader(type);
994 default:
995 return error(GL_INVALID_ENUM, 0);
996 }
997 }
998 }
999 catch(std::bad_alloc&)
1000 {
1001 return error(GL_OUT_OF_MEMORY, 0);
1002 }
1003
1004 return 0;
1005}
1006
1007void __stdcall glCullFace(GLenum mode)
1008{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001009 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001010
1011 try
1012 {
1013 switch (mode)
1014 {
1015 case GL_FRONT:
1016 case GL_BACK:
1017 case GL_FRONT_AND_BACK:
1018 {
1019 gl::Context *context = gl::getContext();
1020
1021 if (context)
1022 {
1023 context->cullMode = mode;
1024 }
1025 }
1026 break;
1027 default:
1028 return error(GL_INVALID_ENUM);
1029 }
1030 }
1031 catch(std::bad_alloc&)
1032 {
1033 return error(GL_OUT_OF_MEMORY);
1034 }
1035}
1036
1037void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1038{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001039 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001040
1041 try
1042 {
1043 if (n < 0)
1044 {
1045 return error(GL_INVALID_VALUE);
1046 }
1047
1048 gl::Context *context = gl::getContext();
1049
1050 if (context)
1051 {
1052 for (int i = 0; i < n; i++)
1053 {
1054 context->deleteBuffer(buffers[i]);
1055 }
1056 }
1057 }
1058 catch(std::bad_alloc&)
1059 {
1060 return error(GL_OUT_OF_MEMORY);
1061 }
1062}
1063
1064void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1065{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001066 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001067
1068 try
1069 {
1070 if (n < 0)
1071 {
1072 return error(GL_INVALID_VALUE);
1073 }
1074
1075 gl::Context *context = gl::getContext();
1076
1077 if (context)
1078 {
1079 for (int i = 0; i < n; i++)
1080 {
1081 if (framebuffers[i] != 0)
1082 {
1083 context->deleteFramebuffer(framebuffers[i]);
1084 }
1085 }
1086 }
1087 }
1088 catch(std::bad_alloc&)
1089 {
1090 return error(GL_OUT_OF_MEMORY);
1091 }
1092}
1093
1094void __stdcall glDeleteProgram(GLuint program)
1095{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001096 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001097
1098 try
1099 {
1100 gl::Context *context = gl::getContext();
1101
1102 if (context)
1103 {
1104 context->deleteProgram(program);
1105 }
1106 }
1107 catch(std::bad_alloc&)
1108 {
1109 return error(GL_OUT_OF_MEMORY);
1110 }
1111}
1112
1113void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1114{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001115 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001116
1117 try
1118 {
1119 if (n < 0)
1120 {
1121 return error(GL_INVALID_VALUE);
1122 }
1123
1124 gl::Context *context = gl::getContext();
1125
1126 if (context)
1127 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001128 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001129 {
1130 context->deleteRenderbuffer(renderbuffers[i]);
1131 }
1132 }
1133 }
1134 catch(std::bad_alloc&)
1135 {
1136 return error(GL_OUT_OF_MEMORY);
1137 }
1138}
1139
1140void __stdcall glDeleteShader(GLuint shader)
1141{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001142 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001143
1144 try
1145 {
1146 gl::Context *context = gl::getContext();
1147
1148 if (context)
1149 {
1150 context->deleteShader(shader);
1151 }
1152 }
1153 catch(std::bad_alloc&)
1154 {
1155 return error(GL_OUT_OF_MEMORY);
1156 }
1157}
1158
1159void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1160{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001161 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001162
1163 try
1164 {
1165 if (n < 0)
1166 {
1167 return error(GL_INVALID_VALUE);
1168 }
1169
1170 gl::Context *context = gl::getContext();
1171
1172 if (context)
1173 {
1174 for (int i = 0; i < n; i++)
1175 {
1176 if (textures[i] != 0)
1177 {
1178 context->deleteTexture(textures[i]);
1179 }
1180 }
1181 }
1182 }
1183 catch(std::bad_alloc&)
1184 {
1185 return error(GL_OUT_OF_MEMORY);
1186 }
1187}
1188
1189void __stdcall glDepthFunc(GLenum func)
1190{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001191 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001192
1193 try
1194 {
1195 switch (func)
1196 {
1197 case GL_NEVER:
1198 case GL_ALWAYS:
1199 case GL_LESS:
1200 case GL_LEQUAL:
1201 case GL_EQUAL:
1202 case GL_GREATER:
1203 case GL_GEQUAL:
1204 case GL_NOTEQUAL:
1205 break;
1206 default:
1207 return error(GL_INVALID_ENUM);
1208 }
1209
1210 gl::Context *context = gl::getContext();
1211
1212 if (context)
1213 {
1214 context->depthFunc = func;
1215 }
1216 }
1217 catch(std::bad_alloc&)
1218 {
1219 return error(GL_OUT_OF_MEMORY);
1220 }
1221}
1222
1223void __stdcall glDepthMask(GLboolean flag)
1224{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001225 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001226
1227 try
1228 {
1229 gl::Context *context = gl::getContext();
1230
1231 if (context)
1232 {
1233 context->depthMask = flag != GL_FALSE;
1234 }
1235 }
1236 catch(std::bad_alloc&)
1237 {
1238 return error(GL_OUT_OF_MEMORY);
1239 }
1240}
1241
1242void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1243{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001244 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001245
1246 try
1247 {
1248 gl::Context *context = gl::getContext();
1249
1250 if (context)
1251 {
1252 context->zNear = zNear;
1253 context->zFar = zFar;
1254 }
1255 }
1256 catch(std::bad_alloc&)
1257 {
1258 return error(GL_OUT_OF_MEMORY);
1259 }
1260}
1261
1262void __stdcall glDetachShader(GLuint program, GLuint shader)
1263{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001264 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001265
1266 try
1267 {
1268 gl::Context *context = gl::getContext();
1269
1270 if (context)
1271 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001272
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001273 gl::Program *programObject = context->getProgram(program);
1274 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001275
1276 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001277 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001278 gl::Shader *shaderByProgramHandle;
1279 shaderByProgramHandle = context->getShader(program);
1280 if (!shaderByProgramHandle)
1281 {
1282 return error(GL_INVALID_VALUE);
1283 }
1284 else
1285 {
1286 return error(GL_INVALID_OPERATION);
1287 }
1288 }
1289
1290 if (!shaderObject)
1291 {
1292 gl::Program *programByShaderHandle = context->getProgram(shader);
1293 if (!programByShaderHandle)
1294 {
1295 return error(GL_INVALID_VALUE);
1296 }
1297 else
1298 {
1299 return error(GL_INVALID_OPERATION);
1300 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001301 }
1302
1303 if (!programObject->detachShader(shaderObject))
1304 {
1305 return error(GL_INVALID_OPERATION);
1306 }
1307
1308 if (shaderObject->isDeletable())
1309 {
1310 context->deleteShader(shader);
1311 }
1312 }
1313 }
1314 catch(std::bad_alloc&)
1315 {
1316 return error(GL_OUT_OF_MEMORY);
1317 }
1318}
1319
1320void __stdcall glDisable(GLenum cap)
1321{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001322 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001323
1324 try
1325 {
1326 gl::Context *context = gl::getContext();
1327
1328 if (context)
1329 {
1330 switch (cap)
1331 {
1332 case GL_CULL_FACE: context->cullFace = false; break;
1333 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1334 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1335 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1336 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1337 case GL_STENCIL_TEST: context->stencilTest = false; break;
1338 case GL_DEPTH_TEST: context->depthTest = false; break;
1339 case GL_BLEND: context->blend = false; break;
1340 case GL_DITHER: context->dither = false; break;
1341 default:
1342 return error(GL_INVALID_ENUM);
1343 }
1344 }
1345 }
1346 catch(std::bad_alloc&)
1347 {
1348 return error(GL_OUT_OF_MEMORY);
1349 }
1350}
1351
1352void __stdcall glDisableVertexAttribArray(GLuint index)
1353{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001354 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001355
1356 try
1357 {
1358 if (index >= gl::MAX_VERTEX_ATTRIBS)
1359 {
1360 return error(GL_INVALID_VALUE);
1361 }
1362
1363 gl::Context *context = gl::getContext();
1364
1365 if (context)
1366 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001367 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001368 }
1369 }
1370 catch(std::bad_alloc&)
1371 {
1372 return error(GL_OUT_OF_MEMORY);
1373 }
1374}
1375
1376void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1377{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001378 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001379
1380 try
1381 {
1382 if (count < 0 || first < 0)
1383 {
1384 return error(GL_INVALID_VALUE);
1385 }
1386
1387 gl::Context *context = gl::getContext();
1388
1389 if (context)
1390 {
1391 context->drawArrays(mode, first, count);
1392 }
1393 }
1394 catch(std::bad_alloc&)
1395 {
1396 return error(GL_OUT_OF_MEMORY);
1397 }
1398}
1399
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001400void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001401{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001402 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 +00001403 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001404
1405 try
1406 {
1407 if (count < 0)
1408 {
1409 return error(GL_INVALID_VALUE);
1410 }
1411
1412 switch (type)
1413 {
1414 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001415 case GL_UNSIGNED_SHORT:
1416 break;
1417 default:
1418 return error(GL_INVALID_ENUM);
1419 }
1420
1421 gl::Context *context = gl::getContext();
1422
1423 if (context)
1424 {
1425 context->drawElements(mode, count, type, indices);
1426 }
1427 }
1428 catch(std::bad_alloc&)
1429 {
1430 return error(GL_OUT_OF_MEMORY);
1431 }
1432}
1433
1434void __stdcall glEnable(GLenum cap)
1435{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001436 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001437
1438 try
1439 {
1440 gl::Context *context = gl::getContext();
1441
1442 if (context)
1443 {
1444 switch (cap)
1445 {
1446 case GL_CULL_FACE: context->cullFace = true; break;
1447 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1448 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1449 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1450 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1451 case GL_STENCIL_TEST: context->stencilTest = true; break;
1452 case GL_DEPTH_TEST: context->depthTest = true; break;
1453 case GL_BLEND: context->blend = true; break;
1454 case GL_DITHER: context->dither = true; break;
1455 default:
1456 return error(GL_INVALID_ENUM);
1457 }
1458 }
1459 }
1460 catch(std::bad_alloc&)
1461 {
1462 return error(GL_OUT_OF_MEMORY);
1463 }
1464}
1465
1466void __stdcall glEnableVertexAttribArray(GLuint index)
1467{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001468 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001469
1470 try
1471 {
1472 if (index >= gl::MAX_VERTEX_ATTRIBS)
1473 {
1474 return error(GL_INVALID_VALUE);
1475 }
1476
1477 gl::Context *context = gl::getContext();
1478
1479 if (context)
1480 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001481 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001482 }
1483 }
1484 catch(std::bad_alloc&)
1485 {
1486 return error(GL_OUT_OF_MEMORY);
1487 }
1488}
1489
1490void __stdcall glFinish(void)
1491{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001492 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001493
1494 try
1495 {
1496 gl::Context *context = gl::getContext();
1497
1498 if (context)
1499 {
1500 context->finish();
1501 }
1502 }
1503 catch(std::bad_alloc&)
1504 {
1505 return error(GL_OUT_OF_MEMORY);
1506 }
1507}
1508
1509void __stdcall glFlush(void)
1510{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001511 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001512
1513 try
1514 {
1515 gl::Context *context = gl::getContext();
1516
1517 if (context)
1518 {
1519 context->flush();
1520 }
1521 }
1522 catch(std::bad_alloc&)
1523 {
1524 return error(GL_OUT_OF_MEMORY);
1525 }
1526}
1527
1528void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1529{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001530 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1531 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001532
1533 try
1534 {
1535 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1536 {
1537 return error(GL_INVALID_ENUM);
1538 }
1539
1540 gl::Context *context = gl::getContext();
1541
1542 if (context)
1543 {
1544 gl::Framebuffer *framebuffer = context->getFramebuffer();
1545
1546 if (context->framebuffer == 0 || !framebuffer)
1547 {
1548 return error(GL_INVALID_OPERATION);
1549 }
1550
1551 switch (attachment)
1552 {
1553 case GL_COLOR_ATTACHMENT0:
1554 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1555 break;
1556 case GL_DEPTH_ATTACHMENT:
1557 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1558 break;
1559 case GL_STENCIL_ATTACHMENT:
1560 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1561 break;
1562 default:
1563 return error(GL_INVALID_ENUM);
1564 }
1565 }
1566 }
1567 catch(std::bad_alloc&)
1568 {
1569 return error(GL_OUT_OF_MEMORY);
1570 }
1571}
1572
1573void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1574{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001575 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1576 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001577
1578 try
1579 {
1580 if (target != GL_FRAMEBUFFER)
1581 {
1582 return error(GL_INVALID_ENUM);
1583 }
1584
1585 switch (attachment)
1586 {
1587 case GL_COLOR_ATTACHMENT0:
1588 break;
1589 default:
1590 return error(GL_INVALID_ENUM);
1591 }
1592
1593 gl::Context *context = gl::getContext();
1594
1595 if (context)
1596 {
1597 if (texture)
1598 {
1599 switch (textarget)
1600 {
1601 case GL_TEXTURE_2D:
1602 if (!context->getTexture2D())
1603 {
1604 return error(GL_INVALID_OPERATION);
1605 }
1606 break;
1607 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1608 UNIMPLEMENTED(); // FIXME
1609 break;
1610 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1611 UNIMPLEMENTED(); // FIXME
1612 break;
1613 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1614 UNIMPLEMENTED(); // FIXME
1615 break;
1616 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1617 UNIMPLEMENTED(); // FIXME
1618 break;
1619 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1620 UNIMPLEMENTED(); // FIXME
1621 break;
1622 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1623 UNIMPLEMENTED(); // FIXME
1624 break;
1625 default:
1626 return error(GL_INVALID_ENUM);
1627 }
1628
1629 if (level != 0)
1630 {
1631 return error(GL_INVALID_VALUE);
1632 }
1633 }
1634
1635 gl::Framebuffer *framebuffer = context->getFramebuffer();
1636
1637 if (context->framebuffer == 0 || !framebuffer)
1638 {
1639 return error(GL_INVALID_OPERATION);
1640 }
1641
1642 framebuffer->setColorbuffer(GL_TEXTURE, texture);
1643 }
1644 }
1645 catch(std::bad_alloc&)
1646 {
1647 return error(GL_OUT_OF_MEMORY);
1648 }
1649}
1650
1651void __stdcall glFrontFace(GLenum mode)
1652{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001653 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001654
1655 try
1656 {
1657 switch (mode)
1658 {
1659 case GL_CW:
1660 case GL_CCW:
1661 {
1662 gl::Context *context = gl::getContext();
1663
1664 if (context)
1665 {
1666 context->frontFace = mode;
1667 }
1668 }
1669 break;
1670 default:
1671 return error(GL_INVALID_ENUM);
1672 }
1673 }
1674 catch(std::bad_alloc&)
1675 {
1676 return error(GL_OUT_OF_MEMORY);
1677 }
1678}
1679
1680void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1681{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001682 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001683
1684 try
1685 {
1686 if (n < 0)
1687 {
1688 return error(GL_INVALID_VALUE);
1689 }
1690
1691 gl::Context *context = gl::getContext();
1692
1693 if (context)
1694 {
1695 for (int i = 0; i < n; i++)
1696 {
1697 buffers[i] = context->createBuffer();
1698 }
1699 }
1700 }
1701 catch(std::bad_alloc&)
1702 {
1703 return error(GL_OUT_OF_MEMORY);
1704 }
1705}
1706
1707void __stdcall glGenerateMipmap(GLenum target)
1708{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001709 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001710
1711 try
1712 {
1713 UNIMPLEMENTED(); // FIXME
1714 }
1715 catch(std::bad_alloc&)
1716 {
1717 return error(GL_OUT_OF_MEMORY);
1718 }
1719}
1720
1721void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1722{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001723 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001724
1725 try
1726 {
1727 if (n < 0)
1728 {
1729 return error(GL_INVALID_VALUE);
1730 }
1731
1732 gl::Context *context = gl::getContext();
1733
1734 if (context)
1735 {
1736 for (int i = 0; i < n; i++)
1737 {
1738 framebuffers[i] = context->createFramebuffer();
1739 }
1740 }
1741 }
1742 catch(std::bad_alloc&)
1743 {
1744 return error(GL_OUT_OF_MEMORY);
1745 }
1746}
1747
1748void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1749{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001750 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001751
1752 try
1753 {
1754 if (n < 0)
1755 {
1756 return error(GL_INVALID_VALUE);
1757 }
1758
1759 gl::Context *context = gl::getContext();
1760
1761 if (context)
1762 {
1763 for (int i = 0; i < n; i++)
1764 {
1765 renderbuffers[i] = context->createRenderbuffer();
1766 }
1767 }
1768 }
1769 catch(std::bad_alloc&)
1770 {
1771 return error(GL_OUT_OF_MEMORY);
1772 }
1773}
1774
1775void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1776{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001777 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001778
1779 try
1780 {
1781 if (n < 0)
1782 {
1783 return error(GL_INVALID_VALUE);
1784 }
1785
1786 gl::Context *context = gl::getContext();
1787
1788 if (context)
1789 {
1790 for (int i = 0; i < n; i++)
1791 {
1792 textures[i] = context->createTexture();
1793 }
1794 }
1795 }
1796 catch(std::bad_alloc&)
1797 {
1798 return error(GL_OUT_OF_MEMORY);
1799 }
1800}
1801
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001802void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001803{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001804 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001805 "GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001806 program, index, bufsize, length, size, type, name);
1807
1808 try
1809 {
1810 if (bufsize < 0)
1811 {
1812 return error(GL_INVALID_VALUE);
1813 }
1814
1815 UNIMPLEMENTED(); // FIXME
1816 }
1817 catch(std::bad_alloc&)
1818 {
1819 return error(GL_OUT_OF_MEMORY);
1820 }
1821}
1822
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001823void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001824{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001825 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001826 "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 +00001827 program, index, bufsize, length, size, type, name);
1828
1829 try
1830 {
1831 if (bufsize < 0)
1832 {
1833 return error(GL_INVALID_VALUE);
1834 }
1835
1836 UNIMPLEMENTED(); // FIXME
1837 }
1838 catch(std::bad_alloc&)
1839 {
1840 return error(GL_OUT_OF_MEMORY);
1841 }
1842}
1843
1844void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1845{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001846 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1847 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001848
1849 try
1850 {
1851 if (maxcount < 0)
1852 {
1853 return error(GL_INVALID_VALUE);
1854 }
1855
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001856 gl::Context *context = gl::getContext();
1857
1858 if (context)
1859 {
1860 gl::Program *programObject = context->getProgram(program);
1861
1862 if (!programObject)
1863 {
1864 return error(GL_INVALID_VALUE);
1865 }
1866
1867 return programObject->getAttachedShaders(maxcount, count, shaders);
1868 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001869 }
1870 catch(std::bad_alloc&)
1871 {
1872 return error(GL_OUT_OF_MEMORY);
1873 }
1874}
1875
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001876int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001877{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001878 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001879
1880 try
1881 {
1882 gl::Context *context = gl::getContext();
1883
1884 if (context)
1885 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001886
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001887 gl::Program *programObject = context->getProgram(program);
1888
1889 if (!programObject)
1890 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001891 if (context->getShader(program))
1892 {
1893 return error(GL_INVALID_OPERATION, -1);
1894 }
1895 else
1896 {
1897 return error(GL_INVALID_VALUE, -1);
1898 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001899 }
1900
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00001901 if (!programObject->isLinked())
1902 {
1903 return error(GL_INVALID_OPERATION, -1);
1904 }
1905
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001906 return programObject->getAttributeLocation(name);
1907 }
1908 }
1909 catch(std::bad_alloc&)
1910 {
1911 return error(GL_OUT_OF_MEMORY, -1);
1912 }
1913
1914 return -1;
1915}
1916
1917void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1918{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001919 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001920
1921 try
1922 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001923 gl::Context *context = gl::getContext();
1924
1925 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001926 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001927 if (!(context->getBooleanv(pname, params)))
1928 {
1929 GLenum nativeType;
1930 unsigned int numParams = 0;
1931 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1932 return error(GL_INVALID_ENUM);
1933
1934 if (numParams == 0)
1935 return; // it is known that the pname is valid, but there are no parameters to return
1936
1937 if (nativeType == GL_FLOAT)
1938 {
1939 GLfloat *floatParams = NULL;
1940 floatParams = new GLfloat[numParams];
1941
1942 context->getFloatv(pname, floatParams);
1943
1944 for (unsigned int i = 0; i < numParams; ++i)
1945 {
1946 if (floatParams[i] == 0.0f)
1947 params[i] = GL_FALSE;
1948 else
1949 params[i] = GL_TRUE;
1950 }
1951
1952 delete [] floatParams;
1953 }
1954 else if (nativeType == GL_INT)
1955 {
1956 GLint *intParams = NULL;
1957 intParams = new GLint[numParams];
1958
1959 context->getIntegerv(pname, intParams);
1960
1961 for (unsigned int i = 0; i < numParams; ++i)
1962 {
1963 if (intParams[i] == 0)
1964 params[i] = GL_FALSE;
1965 else
1966 params[i] = GL_TRUE;
1967 }
1968
1969 delete [] intParams;
1970 }
1971 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001972 }
1973 }
1974 catch(std::bad_alloc&)
1975 {
1976 return error(GL_OUT_OF_MEMORY);
1977 }
1978}
1979
1980void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1981{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001982 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 +00001983
1984 try
1985 {
1986 UNIMPLEMENTED(); // FIXME
1987 }
1988 catch(std::bad_alloc&)
1989 {
1990 return error(GL_OUT_OF_MEMORY);
1991 }
1992}
1993
1994GLenum __stdcall glGetError(void)
1995{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001996 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001997
1998 gl::Context *context = gl::getContext();
1999
2000 if (context)
2001 {
2002 return context->getError();
2003 }
2004
2005 return GL_NO_ERROR;
2006}
2007
2008void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2009{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002010 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002011
2012 try
2013 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002014 gl::Context *context = gl::getContext();
2015
2016 if (context)
2017 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002018 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002019 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002020 GLenum nativeType;
2021 unsigned int numParams = 0;
2022 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2023 return error(GL_INVALID_ENUM);
2024
2025 if (numParams == 0)
2026 return; // it is known that the pname is valid, but that there are no parameters to return.
2027
2028 if (nativeType == GL_BOOL)
2029 {
2030 GLboolean *boolParams = NULL;
2031 boolParams = new GLboolean[numParams];
2032
2033 context->getBooleanv(pname, boolParams);
2034
2035 for (unsigned int i = 0; i < numParams; ++i)
2036 {
2037 if (boolParams[i] == GL_FALSE)
2038 params[i] = 0.0f;
2039 else
2040 params[i] = 1.0f;
2041 }
2042
2043 delete [] boolParams;
2044 }
2045 else if (nativeType == GL_INT)
2046 {
2047 GLint *intParams = NULL;
2048 intParams = new GLint[numParams];
2049
2050 context->getIntegerv(pname, intParams);
2051
2052 for (unsigned int i = 0; i < numParams; ++i)
2053 {
2054 params[i] = (GLfloat)intParams[i];
2055 }
2056
2057 delete [] intParams;
2058 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002059 }
2060 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002061 }
2062 catch(std::bad_alloc&)
2063 {
2064 return error(GL_OUT_OF_MEMORY);
2065 }
2066}
2067
2068void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2069{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002070 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2071 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002072
2073 try
2074 {
2075 gl::Context *context = gl::getContext();
2076
2077 if (context)
2078 {
2079 if (context->framebuffer == 0)
2080 {
2081 return error(GL_INVALID_OPERATION);
2082 }
2083
2084 UNIMPLEMENTED(); // FIXME
2085 }
2086 }
2087 catch(std::bad_alloc&)
2088 {
2089 return error(GL_OUT_OF_MEMORY);
2090 }
2091}
2092
2093void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2094{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002095 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002096
2097 try
2098 {
2099 gl::Context *context = gl::getContext();
2100
2101 if (context)
2102 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002103 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002104 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002105 GLenum nativeType;
2106 unsigned int numParams = 0;
2107 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2108 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002109
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002110 if (numParams == 0)
2111 return; // it is known that pname is valid, but there are no parameters to return
2112
2113 if (nativeType == GL_BOOL)
2114 {
2115 GLboolean *boolParams = NULL;
2116 boolParams = new GLboolean[numParams];
2117
2118 context->getBooleanv(pname, boolParams);
2119
2120 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002121 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002122 if (boolParams[i] == GL_FALSE)
2123 params[i] = 0;
2124 else
2125 params[i] = 1;
2126 }
2127
2128 delete [] boolParams;
2129 }
2130 else if (nativeType == GL_FLOAT)
2131 {
2132 GLfloat *floatParams = NULL;
2133 floatParams = new GLfloat[numParams];
2134
2135 context->getFloatv(pname, floatParams);
2136
2137 for (unsigned int i = 0; i < numParams; ++i)
2138 {
2139 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002140 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002141 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002142 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002143 else
2144 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 +00002145 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002146
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002147 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002148 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002149 }
2150 }
2151 }
2152 catch(std::bad_alloc&)
2153 {
2154 return error(GL_OUT_OF_MEMORY);
2155 }
2156}
2157
2158void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2159{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002160 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002161
2162 try
2163 {
2164 gl::Context *context = gl::getContext();
2165
2166 if (context)
2167 {
2168 gl::Program *programObject = context->getProgram(program);
2169
2170 if (!programObject)
2171 {
2172 return error(GL_INVALID_VALUE);
2173 }
2174
2175 switch (pname)
2176 {
2177 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002178 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002179 return;
2180 case GL_LINK_STATUS:
2181 *params = programObject->isLinked();
2182 return;
2183 case GL_VALIDATE_STATUS:
2184 UNIMPLEMENTED(); // FIXME
2185 *params = GL_TRUE;
2186 return;
2187 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002188 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002189 return;
2190 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002191 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002192 return;
2193 case GL_ACTIVE_ATTRIBUTES:
2194 UNIMPLEMENTED(); // FIXME
2195 *params = 0;
2196 return;
2197 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2198 UNIMPLEMENTED(); // FIXME
2199 *params = 0;
2200 return;
2201 case GL_ACTIVE_UNIFORMS:
2202 UNIMPLEMENTED(); // FIXME
2203 *params = 0;
2204 return;
2205 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2206 UNIMPLEMENTED(); // FIXME
2207 *params = 0;
2208 return;
2209 default:
2210 return error(GL_INVALID_ENUM);
2211 }
2212 }
2213 }
2214 catch(std::bad_alloc&)
2215 {
2216 return error(GL_OUT_OF_MEMORY);
2217 }
2218}
2219
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002220void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002221{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002222 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 +00002223 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002224
2225 try
2226 {
2227 if (bufsize < 0)
2228 {
2229 return error(GL_INVALID_VALUE);
2230 }
2231
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002232 gl::Context *context = gl::getContext();
2233
2234 if (context)
2235 {
2236 gl::Program *programObject = context->getProgram(program);
2237
2238 if (!programObject)
2239 {
2240 return error(GL_INVALID_VALUE);
2241 }
2242
2243 programObject->getInfoLog(bufsize, length, infolog);
2244 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002245 }
2246 catch(std::bad_alloc&)
2247 {
2248 return error(GL_OUT_OF_MEMORY);
2249 }
2250}
2251
2252void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2253{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002254 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 +00002255
2256 try
2257 {
2258 UNIMPLEMENTED(); // FIXME
2259 }
2260 catch(std::bad_alloc&)
2261 {
2262 return error(GL_OUT_OF_MEMORY);
2263 }
2264}
2265
2266void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2267{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002268 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002269
2270 try
2271 {
2272 gl::Context *context = gl::getContext();
2273
2274 if (context)
2275 {
2276 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002277
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002278 if (!shaderObject)
2279 {
2280 return error(GL_INVALID_VALUE);
2281 }
2282
2283 switch (pname)
2284 {
2285 case GL_SHADER_TYPE:
2286 *params = shaderObject->getType();
2287 return;
2288 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002289 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002290 return;
2291 case GL_COMPILE_STATUS:
2292 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2293 return;
2294 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002295 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002296 return;
2297 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002298 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002299 return;
2300 default:
2301 return error(GL_INVALID_ENUM);
2302 }
2303 }
2304 }
2305 catch(std::bad_alloc&)
2306 {
2307 return error(GL_OUT_OF_MEMORY);
2308 }
2309}
2310
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002311void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002312{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002313 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 +00002314 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002315
2316 try
2317 {
2318 if (bufsize < 0)
2319 {
2320 return error(GL_INVALID_VALUE);
2321 }
2322
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002323 gl::Context *context = gl::getContext();
2324
2325 if (context)
2326 {
2327 gl::Shader *shaderObject = context->getShader(shader);
2328
2329 if (!shaderObject)
2330 {
2331 return error(GL_INVALID_VALUE);
2332 }
2333
2334 shaderObject->getInfoLog(bufsize, length, infolog);
2335 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002336 }
2337 catch(std::bad_alloc&)
2338 {
2339 return error(GL_OUT_OF_MEMORY);
2340 }
2341}
2342
2343void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2344{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002345 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2346 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002347
2348 try
2349 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002350 switch (shadertype)
2351 {
2352 case GL_VERTEX_SHADER:
2353 case GL_FRAGMENT_SHADER:
2354 break;
2355 default:
2356 return error(GL_INVALID_ENUM);
2357 }
2358
2359 switch (precisiontype)
2360 {
2361 case GL_LOW_FLOAT:
2362 case GL_MEDIUM_FLOAT:
2363 case GL_HIGH_FLOAT:
2364 // Assume IEEE 754 precision
2365 range[0] = 127;
2366 range[1] = 127;
2367 precision[0] = 23;
2368 precision[1] = 23;
2369 break;
2370 case GL_LOW_INT:
2371 case GL_MEDIUM_INT:
2372 case GL_HIGH_INT:
2373 // Some (most) hardware only supports single-precision floating-point numbers,
2374 // which can accurately represent integers up to +/-16777216
2375 range[0] = 24;
2376 range[1] = 24;
2377 precision[0] = 0;
2378 precision[1] = 0;
2379 break;
2380 default:
2381 return error(GL_INVALID_ENUM);
2382 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002383 }
2384 catch(std::bad_alloc&)
2385 {
2386 return error(GL_OUT_OF_MEMORY);
2387 }
2388}
2389
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002390void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002391{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002392 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 +00002393 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002394
2395 try
2396 {
2397 if (bufsize < 0)
2398 {
2399 return error(GL_INVALID_VALUE);
2400 }
2401
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002402 gl::Context *context = gl::getContext();
2403
2404 if (context)
2405 {
2406 gl::Shader *shaderObject = context->getShader(shader);
2407
2408 if (!shaderObject)
2409 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002410 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002411 }
2412
2413 shaderObject->getSource(bufsize, length, source);
2414 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002415 }
2416 catch(std::bad_alloc&)
2417 {
2418 return error(GL_OUT_OF_MEMORY);
2419 }
2420}
2421
2422const GLubyte* __stdcall glGetString(GLenum name)
2423{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002424 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002425
2426 try
2427 {
2428 switch (name)
2429 {
2430 case GL_VENDOR:
2431 return (GLubyte*)"TransGaming Inc.";
2432 case GL_RENDERER:
2433 return (GLubyte*)"ANGLE";
2434 case GL_VERSION:
2435 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2436 case GL_SHADING_LANGUAGE_VERSION:
2437 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2438 case GL_EXTENSIONS:
2439 return (GLubyte*)"";
2440 default:
2441 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2442 }
2443 }
2444 catch(std::bad_alloc&)
2445 {
2446 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2447 }
2448
2449 return NULL;
2450}
2451
2452void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2453{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002454 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 +00002455
2456 try
2457 {
2458 UNIMPLEMENTED(); // FIXME
2459 }
2460 catch(std::bad_alloc&)
2461 {
2462 return error(GL_OUT_OF_MEMORY);
2463 }
2464}
2465
2466void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2467{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002468 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 +00002469
2470 try
2471 {
2472 UNIMPLEMENTED(); // FIXME
2473 }
2474 catch(std::bad_alloc&)
2475 {
2476 return error(GL_OUT_OF_MEMORY);
2477 }
2478}
2479
2480void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2481{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002482 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002483
2484 try
2485 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002486 gl::Context *context = gl::getContext();
2487
2488 if (context)
2489 {
2490 if (program == 0)
2491 {
2492 return error(GL_INVALID_VALUE);
2493 }
2494
2495 gl::Program *programObject = context->getProgram(program);
2496
2497 if (!programObject || !programObject->isLinked())
2498 {
2499 return error(GL_INVALID_OPERATION);
2500 }
2501
2502 if (!programObject->getUniformfv(location, params))
2503 {
2504 return error(GL_INVALID_OPERATION);
2505 }
2506 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002507 }
2508 catch(std::bad_alloc&)
2509 {
2510 return error(GL_OUT_OF_MEMORY);
2511 }
2512}
2513
2514void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2515{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002516 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002517
2518 try
2519 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002520 gl::Context *context = gl::getContext();
2521
2522 if (context)
2523 {
2524 if (program == 0)
2525 {
2526 return error(GL_INVALID_VALUE);
2527 }
2528
2529 gl::Program *programObject = context->getProgram(program);
2530
2531 if (!programObject || !programObject->isLinked())
2532 {
2533 return error(GL_INVALID_OPERATION);
2534 }
2535
2536 if (!programObject)
2537 {
2538 return error(GL_INVALID_OPERATION);
2539 }
2540
2541 if (!programObject->getUniformiv(location, params))
2542 {
2543 return error(GL_INVALID_OPERATION);
2544 }
2545 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002546 }
2547 catch(std::bad_alloc&)
2548 {
2549 return error(GL_OUT_OF_MEMORY);
2550 }
2551}
2552
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002553int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002554{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002555 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002556
2557 try
2558 {
2559 gl::Context *context = gl::getContext();
2560
2561 if (strstr(name, "gl_") == name)
2562 {
2563 return -1;
2564 }
2565
2566 if (context)
2567 {
2568 gl::Program *programObject = context->getProgram(program);
2569
2570 if (!programObject)
2571 {
2572 return error(GL_INVALID_VALUE, -1);
2573 }
2574
2575 if (!programObject->isLinked())
2576 {
2577 return error(GL_INVALID_OPERATION, -1);
2578 }
2579
2580 return programObject->getUniformLocation(name);
2581 }
2582 }
2583 catch(std::bad_alloc&)
2584 {
2585 return error(GL_OUT_OF_MEMORY, -1);
2586 }
2587
2588 return -1;
2589}
2590
2591void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2592{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002593 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002594
2595 try
2596 {
2597 if (index >= gl::MAX_VERTEX_ATTRIBS)
2598 {
2599 return error(GL_INVALID_VALUE);
2600 }
2601
2602 UNIMPLEMENTED(); // FIXME
2603 }
2604 catch(std::bad_alloc&)
2605 {
2606 return error(GL_OUT_OF_MEMORY);
2607 }
2608}
2609
2610void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2611{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002612 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002613
2614 try
2615 {
2616 if (index >= gl::MAX_VERTEX_ATTRIBS)
2617 {
2618 return error(GL_INVALID_VALUE);
2619 }
2620
2621 UNIMPLEMENTED(); // FIXME
2622 }
2623 catch(std::bad_alloc&)
2624 {
2625 return error(GL_OUT_OF_MEMORY);
2626 }
2627}
2628
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002629void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002630{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002631 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002632
2633 try
2634 {
2635 if (index >= gl::MAX_VERTEX_ATTRIBS)
2636 {
2637 return error(GL_INVALID_VALUE);
2638 }
2639
2640 UNIMPLEMENTED(); // FIXME
2641 }
2642 catch(std::bad_alloc&)
2643 {
2644 return error(GL_OUT_OF_MEMORY);
2645 }
2646}
2647
2648void __stdcall glHint(GLenum target, GLenum mode)
2649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002650 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002651
2652 try
2653 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002654 switch (target)
2655 {
2656 case GL_GENERATE_MIPMAP_HINT:
2657 switch (mode)
2658 {
2659 case GL_FASTEST:
2660 case GL_NICEST:
2661 case GL_DONT_CARE:
2662 break;
2663 default:
2664 return error(GL_INVALID_ENUM);
2665 }
2666 break;
2667 default:
2668 return error(GL_INVALID_ENUM);
2669 }
2670
2671 gl::Context *context = gl::getContext();
2672 if (context)
2673 {
2674 if (target == GL_GENERATE_MIPMAP_HINT)
2675 context->generateMipmapHint = mode;
2676 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002677 }
2678 catch(std::bad_alloc&)
2679 {
2680 return error(GL_OUT_OF_MEMORY);
2681 }
2682}
2683
2684GLboolean __stdcall glIsBuffer(GLuint buffer)
2685{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002686 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002687
2688 try
2689 {
2690 gl::Context *context = gl::getContext();
2691
2692 if (context && buffer)
2693 {
2694 gl::Buffer *bufferObject = context->getBuffer(buffer);
2695
2696 if (bufferObject)
2697 {
2698 return GL_TRUE;
2699 }
2700 }
2701 }
2702 catch(std::bad_alloc&)
2703 {
2704 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2705 }
2706
2707 return GL_FALSE;
2708}
2709
2710GLboolean __stdcall glIsEnabled(GLenum cap)
2711{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002712 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002713
2714 try
2715 {
2716 gl::Context *context = gl::getContext();
2717
2718 if (context)
2719 {
2720 switch (cap)
2721 {
2722 case GL_CULL_FACE: return context->cullFace;
2723 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
2724 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
2725 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
2726 case GL_SCISSOR_TEST: return context->scissorTest;
2727 case GL_STENCIL_TEST: return context->stencilTest;
2728 case GL_DEPTH_TEST: return context->depthTest;
2729 case GL_BLEND: return context->blend;
2730 case GL_DITHER: return context->dither;
2731 default:
2732 return error(GL_INVALID_ENUM, false);
2733 }
2734 }
2735 }
2736 catch(std::bad_alloc&)
2737 {
2738 return error(GL_OUT_OF_MEMORY, false);
2739 }
2740
2741 return false;
2742}
2743
2744GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
2745{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002746 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002747
2748 try
2749 {
2750 gl::Context *context = gl::getContext();
2751
2752 if (context && framebuffer)
2753 {
2754 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2755
2756 if (framebufferObject)
2757 {
2758 return GL_TRUE;
2759 }
2760 }
2761 }
2762 catch(std::bad_alloc&)
2763 {
2764 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2765 }
2766
2767 return GL_FALSE;
2768}
2769
2770GLboolean __stdcall glIsProgram(GLuint program)
2771{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002772 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002773
2774 try
2775 {
2776 gl::Context *context = gl::getContext();
2777
2778 if (context && program)
2779 {
2780 gl::Program *programObject = context->getProgram(program);
2781
2782 if (programObject)
2783 {
2784 return GL_TRUE;
2785 }
2786 }
2787 }
2788 catch(std::bad_alloc&)
2789 {
2790 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2791 }
2792
2793 return GL_FALSE;
2794}
2795
2796GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
2797{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002798 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002799
2800 try
2801 {
2802 gl::Context *context = gl::getContext();
2803
2804 if (context && renderbuffer)
2805 {
2806 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2807
2808 if (renderbufferObject)
2809 {
2810 return GL_TRUE;
2811 }
2812 }
2813 }
2814 catch(std::bad_alloc&)
2815 {
2816 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2817 }
2818
2819 return GL_FALSE;
2820}
2821
2822GLboolean __stdcall glIsShader(GLuint shader)
2823{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002824 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002825
2826 try
2827 {
2828 gl::Context *context = gl::getContext();
2829
2830 if (context && shader)
2831 {
2832 gl::Shader *shaderObject = context->getShader(shader);
2833
2834 if (shaderObject)
2835 {
2836 return GL_TRUE;
2837 }
2838 }
2839 }
2840 catch(std::bad_alloc&)
2841 {
2842 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2843 }
2844
2845 return GL_FALSE;
2846}
2847
2848GLboolean __stdcall glIsTexture(GLuint texture)
2849{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002850 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002851
2852 try
2853 {
2854 gl::Context *context = gl::getContext();
2855
2856 if (context && texture)
2857 {
2858 gl::Texture *textureObject = context->getTexture(texture);
2859
2860 if (textureObject)
2861 {
2862 return GL_TRUE;
2863 }
2864 }
2865 }
2866 catch(std::bad_alloc&)
2867 {
2868 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2869 }
2870
2871 return GL_FALSE;
2872}
2873
2874void __stdcall glLineWidth(GLfloat width)
2875{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002876 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002877
2878 try
2879 {
2880 if (width <= 0.0f)
2881 {
2882 return error(GL_INVALID_VALUE);
2883 }
2884
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002885 gl::Context *context = gl::getContext();
2886
2887 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002888 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002889 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002890 }
2891 }
2892 catch(std::bad_alloc&)
2893 {
2894 return error(GL_OUT_OF_MEMORY);
2895 }
2896}
2897
2898void __stdcall glLinkProgram(GLuint program)
2899{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002900 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002901
2902 try
2903 {
2904 gl::Context *context = gl::getContext();
2905
2906 if (context)
2907 {
2908 gl::Program *programObject = context->getProgram(program);
2909
2910 if (!programObject)
2911 {
2912 return error(GL_INVALID_VALUE);
2913 }
2914
2915 programObject->link();
2916 }
2917 }
2918 catch(std::bad_alloc&)
2919 {
2920 return error(GL_OUT_OF_MEMORY);
2921 }
2922}
2923
2924void __stdcall glPixelStorei(GLenum pname, GLint param)
2925{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002926 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002927
2928 try
2929 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002930 gl::Context *context = gl::getContext();
2931
2932 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002933 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002934 switch (pname)
2935 {
2936 case GL_UNPACK_ALIGNMENT:
2937 if (param != 1 && param != 2 && param != 4 && param != 8)
2938 {
2939 return error(GL_INVALID_VALUE);
2940 }
2941
2942 context->unpackAlignment = param;
2943 break;
2944
2945 case GL_PACK_ALIGNMENT:
2946 if (param != 1 && param != 2 && param != 4 && param != 8)
2947 {
2948 return error(GL_INVALID_VALUE);
2949 }
2950
2951 context->packAlignment = param;
2952 break;
2953
2954 default:
2955 return error(GL_INVALID_ENUM);
2956 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002957 }
2958 }
2959 catch(std::bad_alloc&)
2960 {
2961 return error(GL_OUT_OF_MEMORY);
2962 }
2963}
2964
2965void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
2966{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002967 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002968
2969 try
2970 {
2971 if (factor != 0.0f || units != 0.0f)
2972 {
2973 UNIMPLEMENTED(); // FIXME
2974 }
2975 }
2976 catch(std::bad_alloc&)
2977 {
2978 return error(GL_OUT_OF_MEMORY);
2979 }
2980}
2981
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002982void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002983{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002984 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002985 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002986 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002987
2988 try
2989 {
2990 if (width < 0 || height < 0)
2991 {
2992 return error(GL_INVALID_VALUE);
2993 }
2994
2995 switch (format)
2996 {
2997 case GL_RGBA:
2998 switch (type)
2999 {
3000 case GL_UNSIGNED_BYTE:
3001 break;
3002 default:
3003 return error(GL_INVALID_OPERATION);
3004 }
3005 break;
3006 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3007 switch (type)
3008 {
3009 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3010 break;
3011 default:
3012 return error(GL_INVALID_OPERATION);
3013 }
3014 break;
3015 default:
3016 return error(GL_INVALID_OPERATION);
3017 }
3018
3019 gl::Context *context = gl::getContext();
3020
3021 if (context)
3022 {
3023 context->readPixels(x, y, width, height, format, type, pixels);
3024 }
3025 }
3026 catch(std::bad_alloc&)
3027 {
3028 return error(GL_OUT_OF_MEMORY);
3029 }
3030}
3031
3032void __stdcall glReleaseShaderCompiler(void)
3033{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003034 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003035
3036 try
3037 {
3038 gl::Shader::releaseCompiler();
3039 }
3040 catch(std::bad_alloc&)
3041 {
3042 return error(GL_OUT_OF_MEMORY);
3043 }
3044}
3045
3046void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3047{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003048 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3049 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003050
3051 try
3052 {
3053 switch (target)
3054 {
3055 case GL_RENDERBUFFER:
3056 break;
3057 default:
3058 return error(GL_INVALID_ENUM);
3059 }
3060
3061 switch (internalformat)
3062 {
3063 case GL_DEPTH_COMPONENT16:
3064 case GL_RGBA4:
3065 case GL_RGB5_A1:
3066 case GL_RGB565:
3067 case GL_STENCIL_INDEX8:
3068 break;
3069 default:
3070 return error(GL_INVALID_ENUM);
3071 }
3072
3073 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3074 {
3075 return error(GL_INVALID_VALUE);
3076 }
3077
3078 gl::Context *context = gl::getContext();
3079
3080 if (context)
3081 {
3082 if (context->framebuffer == 0 || context->renderbuffer == 0)
3083 {
3084 return error(GL_INVALID_OPERATION);
3085 }
3086
3087 switch (internalformat)
3088 {
3089 case GL_DEPTH_COMPONENT16:
3090 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3091 break;
3092 case GL_RGBA4:
3093 case GL_RGB5_A1:
3094 case GL_RGB565:
3095 UNIMPLEMENTED(); // FIXME
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003096 // context->setRenderbuffer(new Colorbuffer(renderTarget));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003097 break;
3098 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003099 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003100 break;
3101 default:
3102 return error(GL_INVALID_ENUM);
3103 }
3104 }
3105 }
3106 catch(std::bad_alloc&)
3107 {
3108 return error(GL_OUT_OF_MEMORY);
3109 }
3110}
3111
3112void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3113{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003114 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003115
3116 try
3117 {
3118 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003119
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003120 if (context)
3121 {
3122 context->sampleCoverageValue = gl::clamp01(value);
3123 context->sampleCoverageInvert = invert;
3124 }
3125 }
3126 catch(std::bad_alloc&)
3127 {
3128 return error(GL_OUT_OF_MEMORY);
3129 }
3130}
3131
3132void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3133{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003134 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 +00003135
3136 try
3137 {
3138 if (width < 0 || height < 0)
3139 {
3140 return error(GL_INVALID_VALUE);
3141 }
3142
3143 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003144
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003145 if (context)
3146 {
3147 context->scissorX = x;
3148 context->scissorY = y;
3149 context->scissorWidth = width;
3150 context->scissorHeight = height;
3151 }
3152 }
3153 catch(std::bad_alloc&)
3154 {
3155 return error(GL_OUT_OF_MEMORY);
3156 }
3157}
3158
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003159void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003160{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003161 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003162 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003163 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003164
3165 try
3166 {
3167 if (n < 0 || length < 0)
3168 {
3169 return error(GL_INVALID_VALUE);
3170 }
3171
3172 UNIMPLEMENTED(); // FIXME
3173 }
3174 catch(std::bad_alloc&)
3175 {
3176 return error(GL_OUT_OF_MEMORY);
3177 }
3178}
3179
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003180void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003181{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003182 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 +00003183 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003184
3185 try
3186 {
daniel@transgaming.com57a0bab2010-04-03 20:56:10 +00003187 if (shader == 0 || count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003188 {
3189 return error(GL_INVALID_VALUE);
3190 }
3191
3192 gl::Context *context = gl::getContext();
3193
3194 if (context)
3195 {
3196 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003197
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003198 if (!shaderObject)
3199 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003200 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003201 }
3202
3203 shaderObject->setSource(count, string, length);
3204 }
3205 }
3206 catch(std::bad_alloc&)
3207 {
3208 return error(GL_OUT_OF_MEMORY);
3209 }
3210}
3211
3212void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3213{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003214 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003215}
3216
3217void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3218{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003219 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 +00003220
3221 try
3222 {
3223 switch (face)
3224 {
3225 case GL_FRONT:
3226 case GL_BACK:
3227 case GL_FRONT_AND_BACK:
3228 break;
3229 default:
3230 return error(GL_INVALID_ENUM);
3231 }
3232
3233 switch (func)
3234 {
3235 case GL_NEVER:
3236 case GL_ALWAYS:
3237 case GL_LESS:
3238 case GL_LEQUAL:
3239 case GL_EQUAL:
3240 case GL_GEQUAL:
3241 case GL_GREATER:
3242 case GL_NOTEQUAL:
3243 break;
3244 default:
3245 return error(GL_INVALID_ENUM);
3246 }
3247
3248 gl::Context *context = gl::getContext();
3249
3250 if (context)
3251 {
3252 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3253 {
3254 context->stencilFunc = func;
3255 context->stencilRef = ref;
3256 context->stencilMask = mask;
3257 }
3258
3259 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3260 {
3261 context->stencilBackFunc = func;
3262 context->stencilBackRef = ref;
3263 context->stencilBackMask = mask;
3264 }
3265 }
3266 }
3267 catch(std::bad_alloc&)
3268 {
3269 return error(GL_OUT_OF_MEMORY);
3270 }
3271}
3272
3273void __stdcall glStencilMask(GLuint mask)
3274{
3275 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3276}
3277
3278void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3279{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003280 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003281
3282 try
3283 {
3284 switch (face)
3285 {
3286 case GL_FRONT:
3287 case GL_BACK:
3288 case GL_FRONT_AND_BACK:
3289 break;
3290 default:
3291 return error(GL_INVALID_ENUM);
3292 }
3293
3294 gl::Context *context = gl::getContext();
3295
3296 if (context)
3297 {
3298 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3299 {
3300 context->stencilWritemask = mask;
3301 }
3302
3303 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3304 {
3305 context->stencilBackWritemask = mask;
3306 }
3307 }
3308 }
3309 catch(std::bad_alloc&)
3310 {
3311 return error(GL_OUT_OF_MEMORY);
3312 }
3313}
3314
3315void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3316{
3317 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3318}
3319
3320void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3321{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003322 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3323 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003324
3325 try
3326 {
3327 switch (face)
3328 {
3329 case GL_FRONT:
3330 case GL_BACK:
3331 case GL_FRONT_AND_BACK:
3332 break;
3333 default:
3334 return error(GL_INVALID_ENUM);
3335 }
3336
3337 switch (fail)
3338 {
3339 case GL_ZERO:
3340 case GL_KEEP:
3341 case GL_REPLACE:
3342 case GL_INCR:
3343 case GL_DECR:
3344 case GL_INVERT:
3345 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003346 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003347 break;
3348 default:
3349 return error(GL_INVALID_ENUM);
3350 }
3351
3352 switch (zfail)
3353 {
3354 case GL_ZERO:
3355 case GL_KEEP:
3356 case GL_REPLACE:
3357 case GL_INCR:
3358 case GL_DECR:
3359 case GL_INVERT:
3360 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003361 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003362 break;
3363 default:
3364 return error(GL_INVALID_ENUM);
3365 }
3366
3367 switch (zpass)
3368 {
3369 case GL_ZERO:
3370 case GL_KEEP:
3371 case GL_REPLACE:
3372 case GL_INCR:
3373 case GL_DECR:
3374 case GL_INVERT:
3375 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003376 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003377 break;
3378 default:
3379 return error(GL_INVALID_ENUM);
3380 }
3381
3382 gl::Context *context = gl::getContext();
3383
3384 if (context)
3385 {
3386 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3387 {
3388 context->stencilFail = fail;
3389 context->stencilPassDepthFail = zfail;
3390 context->stencilPassDepthPass = zpass;
3391 }
3392
3393 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3394 {
3395 context->stencilBackFail = fail;
3396 context->stencilBackPassDepthFail = zfail;
3397 context->stencilBackPassDepthPass = zpass;
3398 }
3399 }
3400 }
3401 catch(std::bad_alloc&)
3402 {
3403 return error(GL_OUT_OF_MEMORY);
3404 }
3405}
3406
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003407void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3408 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003409{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003410 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 +00003411 "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 +00003412 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003413
3414 try
3415 {
3416 if (level < 0 || width < 0 || height < 0)
3417 {
3418 return error(GL_INVALID_VALUE);
3419 }
3420
3421 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3422 {
3423 return error(GL_INVALID_VALUE);
3424 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003425
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003426 switch (target)
3427 {
3428 case GL_TEXTURE_2D:
3429 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3430 {
3431 return error(GL_INVALID_VALUE);
3432 }
3433 break;
3434 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3435 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3436 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3437 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3438 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3439 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3440 if (!gl::isPow2(width) || !gl::isPow2(height))
3441 {
3442 return error(GL_INVALID_VALUE);
3443 }
3444
3445 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3446 {
3447 return error(GL_INVALID_VALUE);
3448 }
3449 break;
3450 default:
3451 return error(GL_INVALID_ENUM);
3452 }
3453
3454 if (internalformat != format)
3455 {
3456 return error(GL_INVALID_OPERATION);
3457 }
3458
3459 switch (internalformat)
3460 {
3461 case GL_ALPHA:
3462 case GL_LUMINANCE:
3463 case GL_LUMINANCE_ALPHA:
3464 switch (type)
3465 {
3466 case GL_UNSIGNED_BYTE:
3467 break;
3468 default:
3469 return error(GL_INVALID_ENUM);
3470 }
3471 break;
3472 case GL_RGB:
3473 switch (type)
3474 {
3475 case GL_UNSIGNED_BYTE:
3476 case GL_UNSIGNED_SHORT_5_6_5:
3477 break;
3478 default:
3479 return error(GL_INVALID_ENUM);
3480 }
3481 break;
3482 case GL_RGBA:
3483 switch (type)
3484 {
3485 case GL_UNSIGNED_BYTE:
3486 case GL_UNSIGNED_SHORT_4_4_4_4:
3487 case GL_UNSIGNED_SHORT_5_5_5_1:
3488 break;
3489 default:
3490 return error(GL_INVALID_ENUM);
3491 }
3492 break;
3493 default:
3494 return error(GL_INVALID_VALUE);
3495 }
3496
3497 if (border != 0)
3498 {
3499 return error(GL_INVALID_VALUE);
3500 }
3501
3502 gl::Context *context = gl::getContext();
3503
3504 if (context)
3505 {
3506 if (target == GL_TEXTURE_2D)
3507 {
3508 gl::Texture2D *texture = context->getTexture2D();
3509
3510 if (!texture)
3511 {
3512 return error(GL_INVALID_OPERATION);
3513 }
3514
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003515 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003516 }
3517 else
3518 {
3519 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3520
3521 if (!texture)
3522 {
3523 return error(GL_INVALID_OPERATION);
3524 }
3525
3526 switch (target)
3527 {
3528 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003529 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003530 break;
3531 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003532 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003533 break;
3534 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003535 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003536 break;
3537 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003538 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003539 break;
3540 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003541 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003542 break;
3543 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003544 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003545 break;
3546 default: UNREACHABLE();
3547 }
3548 }
3549 }
3550 }
3551 catch(std::bad_alloc&)
3552 {
3553 return error(GL_OUT_OF_MEMORY);
3554 }
3555}
3556
3557void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3558{
3559 glTexParameteri(target, pname, (GLint)param);
3560}
3561
3562void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3563{
3564 glTexParameteri(target, pname, (GLint)*params);
3565}
3566
3567void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3568{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003569 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003570
3571 try
3572 {
3573 gl::Context *context = gl::getContext();
3574
3575 if (context)
3576 {
3577 gl::Texture *texture;
3578
3579 switch (target)
3580 {
3581 case GL_TEXTURE_2D:
3582 texture = context->getTexture2D();
3583 break;
3584 case GL_TEXTURE_CUBE_MAP:
3585 texture = context->getTextureCubeMap();
3586 break;
3587 default:
3588 return error(GL_INVALID_ENUM);
3589 }
3590
3591 switch (pname)
3592 {
3593 case GL_TEXTURE_WRAP_S:
3594 if (!texture->setWrapS((GLenum)param))
3595 {
3596 return error(GL_INVALID_ENUM);
3597 }
3598 break;
3599 case GL_TEXTURE_WRAP_T:
3600 if (!texture->setWrapT((GLenum)param))
3601 {
3602 return error(GL_INVALID_ENUM);
3603 }
3604 break;
3605 case GL_TEXTURE_MIN_FILTER:
3606 if (!texture->setMinFilter((GLenum)param))
3607 {
3608 return error(GL_INVALID_ENUM);
3609 }
3610 break;
3611 case GL_TEXTURE_MAG_FILTER:
3612 if (!texture->setMagFilter((GLenum)param))
3613 {
3614 return error(GL_INVALID_ENUM);
3615 }
3616 break;
3617 default:
3618 return error(GL_INVALID_ENUM);
3619 }
3620 }
3621 }
3622 catch(std::bad_alloc&)
3623 {
3624 return error(GL_OUT_OF_MEMORY);
3625 }
3626}
3627
3628void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3629{
3630 glTexParameteri(target, pname, *params);
3631}
3632
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003633void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3634 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003635{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003636 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3637 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003638 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003639 target, level, xoffset, yoffset, width, height, format, type, pixels);
3640
3641 try
3642 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003643 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
3644 {
3645 return error(GL_INVALID_ENUM);
3646 }
3647
3648 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003649 {
3650 return error(GL_INVALID_VALUE);
3651 }
3652
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003653 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
3654 {
3655 return error(GL_INVALID_VALUE);
3656 }
3657
3658 if (!es2dx::CheckTextureFormatType(format, type))
3659 {
3660 return error(GL_INVALID_ENUM);
3661 }
3662
3663 if (width == 0 || height == 0 || pixels == NULL)
3664 {
3665 return;
3666 }
3667
3668 gl::Context *context = gl::getContext();
3669
3670 if (context)
3671 {
3672 if (target == GL_TEXTURE_2D)
3673 {
3674 gl::Texture2D *texture = context->getTexture2D();
3675
3676 if (!texture)
3677 {
3678 return error(GL_INVALID_OPERATION);
3679 }
3680
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003681 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003682 }
3683 else if (es2dx::IsCubemapTextureTarget(target))
3684 {
3685 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3686
3687 if (!texture)
3688 {
3689 return error(GL_INVALID_OPERATION);
3690 }
3691
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003692 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003693 }
3694 else
3695 {
3696 UNREACHABLE();
3697 }
3698 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003699 }
3700 catch(std::bad_alloc&)
3701 {
3702 return error(GL_OUT_OF_MEMORY);
3703 }
3704}
3705
3706void __stdcall glUniform1f(GLint location, GLfloat x)
3707{
3708 glUniform1fv(location, 1, &x);
3709}
3710
3711void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
3712{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003713 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003714
3715 try
3716 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003717 if (count < 0)
3718 {
3719 return error(GL_INVALID_VALUE);
3720 }
3721
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003722 if (location == -1)
3723 {
3724 return;
3725 }
3726
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003727 gl::Context *context = gl::getContext();
3728
3729 if (context)
3730 {
3731 gl::Program *program = context->getCurrentProgram();
3732
3733 if (!program)
3734 {
3735 return error(GL_INVALID_OPERATION);
3736 }
3737
3738 if (!program->setUniform1fv(location, count, v))
3739 {
3740 return error(GL_INVALID_OPERATION);
3741 }
3742 }
3743 }
3744 catch(std::bad_alloc&)
3745 {
3746 return error(GL_OUT_OF_MEMORY);
3747 }
3748}
3749
3750void __stdcall glUniform1i(GLint location, GLint x)
3751{
3752 glUniform1iv(location, 1, &x);
3753}
3754
3755void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
3756{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003757 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003758
3759 try
3760 {
3761 if (count < 0)
3762 {
3763 return error(GL_INVALID_VALUE);
3764 }
3765
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003766 if (location == -1)
3767 {
3768 return;
3769 }
3770
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003771 gl::Context *context = gl::getContext();
3772
3773 if (context)
3774 {
3775 gl::Program *program = context->getCurrentProgram();
3776
3777 if (!program)
3778 {
3779 return error(GL_INVALID_OPERATION);
3780 }
3781
3782 if (!program->setUniform1iv(location, count, v))
3783 {
3784 return error(GL_INVALID_OPERATION);
3785 }
3786 }
3787 }
3788 catch(std::bad_alloc&)
3789 {
3790 return error(GL_OUT_OF_MEMORY);
3791 }
3792}
3793
3794void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
3795{
3796 GLfloat xy[2] = {x, y};
3797
3798 glUniform2fv(location, 1, (GLfloat*)&xy);
3799}
3800
3801void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
3802{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003803 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003804
3805 try
3806 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003807 if (count < 0)
3808 {
3809 return error(GL_INVALID_VALUE);
3810 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003811
3812 if (location == -1)
3813 {
3814 return;
3815 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003816
3817 gl::Context *context = gl::getContext();
3818
3819 if (context)
3820 {
3821 gl::Program *program = context->getCurrentProgram();
3822
3823 if (!program)
3824 {
3825 return error(GL_INVALID_OPERATION);
3826 }
3827
3828 if (!program->setUniform2fv(location, count, v))
3829 {
3830 return error(GL_INVALID_OPERATION);
3831 }
3832 }
3833 }
3834 catch(std::bad_alloc&)
3835 {
3836 return error(GL_OUT_OF_MEMORY);
3837 }
3838}
3839
3840void __stdcall glUniform2i(GLint location, GLint x, GLint y)
3841{
3842 GLint xy[4] = {x, y};
3843
3844 glUniform2iv(location, 1, (GLint*)&xy);
3845}
3846
3847void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
3848{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003849 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003850
3851 try
3852 {
3853 if (count < 0)
3854 {
3855 return error(GL_INVALID_VALUE);
3856 }
3857
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003858 if (location == -1)
3859 {
3860 return;
3861 }
3862
3863 gl::Context *context = gl::getContext();
3864
3865 if (context)
3866 {
3867 gl::Program *program = context->getCurrentProgram();
3868
3869 if (!program)
3870 {
3871 return error(GL_INVALID_OPERATION);
3872 }
3873
3874 if (!program->setUniform2iv(location, count, v))
3875 {
3876 return error(GL_INVALID_OPERATION);
3877 }
3878 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003879 }
3880 catch(std::bad_alloc&)
3881 {
3882 return error(GL_OUT_OF_MEMORY);
3883 }
3884}
3885
3886void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
3887{
3888 GLfloat xyz[3] = {x, y, z};
3889
3890 glUniform3fv(location, 1, (GLfloat*)&xyz);
3891}
3892
3893void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
3894{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003895 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003896
3897 try
3898 {
3899 if (count < 0)
3900 {
3901 return error(GL_INVALID_VALUE);
3902 }
3903
3904 if (location == -1)
3905 {
3906 return;
3907 }
3908
3909 gl::Context *context = gl::getContext();
3910
3911 if (context)
3912 {
3913 gl::Program *program = context->getCurrentProgram();
3914
3915 if (!program)
3916 {
3917 return error(GL_INVALID_OPERATION);
3918 }
3919
3920 if (!program->setUniform3fv(location, count, v))
3921 {
3922 return error(GL_INVALID_OPERATION);
3923 }
3924 }
3925 }
3926 catch(std::bad_alloc&)
3927 {
3928 return error(GL_OUT_OF_MEMORY);
3929 }
3930}
3931
3932void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
3933{
3934 GLint xyz[3] = {x, y, z};
3935
3936 glUniform3iv(location, 1, (GLint*)&xyz);
3937}
3938
3939void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
3940{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003941 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003942
3943 try
3944 {
3945 if (count < 0)
3946 {
3947 return error(GL_INVALID_VALUE);
3948 }
3949
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003950 if (location == -1)
3951 {
3952 return;
3953 }
3954
3955 gl::Context *context = gl::getContext();
3956
3957 if (context)
3958 {
3959 gl::Program *program = context->getCurrentProgram();
3960
3961 if (!program)
3962 {
3963 return error(GL_INVALID_OPERATION);
3964 }
3965
3966 if (!program->setUniform3iv(location, count, v))
3967 {
3968 return error(GL_INVALID_OPERATION);
3969 }
3970 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003971 }
3972 catch(std::bad_alloc&)
3973 {
3974 return error(GL_OUT_OF_MEMORY);
3975 }
3976}
3977
3978void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3979{
3980 GLfloat xyzw[4] = {x, y, z, w};
3981
3982 glUniform4fv(location, 1, (GLfloat*)&xyzw);
3983}
3984
3985void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
3986{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003987 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003988
3989 try
3990 {
3991 if (count < 0)
3992 {
3993 return error(GL_INVALID_VALUE);
3994 }
3995
3996 if (location == -1)
3997 {
3998 return;
3999 }
4000
4001 gl::Context *context = gl::getContext();
4002
4003 if (context)
4004 {
4005 gl::Program *program = context->getCurrentProgram();
4006
4007 if (!program)
4008 {
4009 return error(GL_INVALID_OPERATION);
4010 }
4011
4012 if (!program->setUniform4fv(location, count, v))
4013 {
4014 return error(GL_INVALID_OPERATION);
4015 }
4016 }
4017 }
4018 catch(std::bad_alloc&)
4019 {
4020 return error(GL_OUT_OF_MEMORY);
4021 }
4022}
4023
4024void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4025{
4026 GLint xyzw[4] = {x, y, z, w};
4027
4028 glUniform4iv(location, 1, (GLint*)&xyzw);
4029}
4030
4031void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4032{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004033 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004034
4035 try
4036 {
4037 if (count < 0)
4038 {
4039 return error(GL_INVALID_VALUE);
4040 }
4041
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004042 if (location == -1)
4043 {
4044 return;
4045 }
4046
4047 gl::Context *context = gl::getContext();
4048
4049 if (context)
4050 {
4051 gl::Program *program = context->getCurrentProgram();
4052
4053 if (!program)
4054 {
4055 return error(GL_INVALID_OPERATION);
4056 }
4057
4058 if (!program->setUniform4iv(location, count, v))
4059 {
4060 return error(GL_INVALID_OPERATION);
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 glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4071{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004072 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4073 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004074
4075 try
4076 {
4077 if (count < 0 || transpose != GL_FALSE)
4078 {
4079 return error(GL_INVALID_VALUE);
4080 }
4081
4082 if (location == -1)
4083 {
4084 return;
4085 }
4086
4087 gl::Context *context = gl::getContext();
4088
4089 if (context)
4090 {
4091 gl::Program *program = context->getCurrentProgram();
4092
4093 if (!program)
4094 {
4095 return error(GL_INVALID_OPERATION);
4096 }
4097
4098 if (!program->setUniformMatrix2fv(location, count, value))
4099 {
4100 return error(GL_INVALID_OPERATION);
4101 }
4102 }
4103 }
4104 catch(std::bad_alloc&)
4105 {
4106 return error(GL_OUT_OF_MEMORY);
4107 }
4108}
4109
4110void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4111{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004112 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4113 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004114
4115 try
4116 {
4117 if (count < 0 || transpose != GL_FALSE)
4118 {
4119 return error(GL_INVALID_VALUE);
4120 }
4121
4122 if (location == -1)
4123 {
4124 return;
4125 }
4126
4127 gl::Context *context = gl::getContext();
4128
4129 if (context)
4130 {
4131 gl::Program *program = context->getCurrentProgram();
4132
4133 if (!program)
4134 {
4135 return error(GL_INVALID_OPERATION);
4136 }
4137
4138 if (!program->setUniformMatrix3fv(location, count, value))
4139 {
4140 return error(GL_INVALID_OPERATION);
4141 }
4142 }
4143 }
4144 catch(std::bad_alloc&)
4145 {
4146 return error(GL_OUT_OF_MEMORY);
4147 }
4148}
4149
4150void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4151{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004152 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4153 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004154
4155 try
4156 {
4157 if (count < 0 || transpose != GL_FALSE)
4158 {
4159 return error(GL_INVALID_VALUE);
4160 }
4161
4162 if (location == -1)
4163 {
4164 return;
4165 }
4166
4167 gl::Context *context = gl::getContext();
4168
4169 if (context)
4170 {
4171 gl::Program *program = context->getCurrentProgram();
4172
4173 if (!program)
4174 {
4175 return error(GL_INVALID_OPERATION);
4176 }
4177
4178 if (!program->setUniformMatrix4fv(location, count, value))
4179 {
4180 return error(GL_INVALID_OPERATION);
4181 }
4182 }
4183 }
4184 catch(std::bad_alloc&)
4185 {
4186 return error(GL_OUT_OF_MEMORY);
4187 }
4188}
4189
4190void __stdcall glUseProgram(GLuint program)
4191{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004192 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004193
4194 try
4195 {
4196 gl::Context *context = gl::getContext();
4197
4198 if (context)
4199 {
4200 gl::Program *programObject = context->getProgram(program);
4201
4202 if (programObject && !programObject->isLinked())
4203 {
4204 return error(GL_INVALID_OPERATION);
4205 }
4206
4207 context->useProgram(program);
4208 }
4209 }
4210 catch(std::bad_alloc&)
4211 {
4212 return error(GL_OUT_OF_MEMORY);
4213 }
4214}
4215
4216void __stdcall glValidateProgram(GLuint program)
4217{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004218 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004219
4220 try
4221 {
4222 UNIMPLEMENTED(); // FIXME
4223 }
4224 catch(std::bad_alloc&)
4225 {
4226 return error(GL_OUT_OF_MEMORY);
4227 }
4228}
4229
4230void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4231{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004232 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004233
4234 try
4235 {
4236 if (index >= gl::MAX_VERTEX_ATTRIBS)
4237 {
4238 return error(GL_INVALID_VALUE);
4239 }
4240
4241 UNIMPLEMENTED(); // FIXME
4242 }
4243 catch(std::bad_alloc&)
4244 {
4245 return error(GL_OUT_OF_MEMORY);
4246 }
4247}
4248
4249void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4250{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004251 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004252
4253 try
4254 {
4255 if (index >= gl::MAX_VERTEX_ATTRIBS)
4256 {
4257 return error(GL_INVALID_VALUE);
4258 }
4259
4260 UNIMPLEMENTED(); // FIXME
4261 }
4262 catch(std::bad_alloc&)
4263 {
4264 return error(GL_OUT_OF_MEMORY);
4265 }
4266}
4267
4268void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4269{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004270 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004271
4272 try
4273 {
4274 if (index >= gl::MAX_VERTEX_ATTRIBS)
4275 {
4276 return error(GL_INVALID_VALUE);
4277 }
4278
4279 UNIMPLEMENTED(); // FIXME
4280 }
4281 catch(std::bad_alloc&)
4282 {
4283 return error(GL_OUT_OF_MEMORY);
4284 }
4285}
4286
4287void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4288{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004289 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004290
4291 try
4292 {
4293 if (index >= gl::MAX_VERTEX_ATTRIBS)
4294 {
4295 return error(GL_INVALID_VALUE);
4296 }
4297
4298 UNIMPLEMENTED(); // FIXME
4299 }
4300 catch(std::bad_alloc&)
4301 {
4302 return error(GL_OUT_OF_MEMORY);
4303 }
4304}
4305
4306void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4307{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004308 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 +00004309
4310 try
4311 {
4312 if (index >= gl::MAX_VERTEX_ATTRIBS)
4313 {
4314 return error(GL_INVALID_VALUE);
4315 }
4316
4317 UNIMPLEMENTED(); // FIXME
4318 }
4319 catch(std::bad_alloc&)
4320 {
4321 return error(GL_OUT_OF_MEMORY);
4322 }
4323}
4324
4325void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4326{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004327 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004328
4329 try
4330 {
4331 if (index >= gl::MAX_VERTEX_ATTRIBS)
4332 {
4333 return error(GL_INVALID_VALUE);
4334 }
4335
4336 UNIMPLEMENTED(); // FIXME
4337 }
4338 catch(std::bad_alloc&)
4339 {
4340 return error(GL_OUT_OF_MEMORY);
4341 }
4342}
4343
4344void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4345{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004346 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 +00004347
4348 try
4349 {
4350 if (index >= gl::MAX_VERTEX_ATTRIBS)
4351 {
4352 return error(GL_INVALID_VALUE);
4353 }
4354
4355 UNIMPLEMENTED(); // FIXME
4356 }
4357 catch(std::bad_alloc&)
4358 {
4359 return error(GL_OUT_OF_MEMORY);
4360 }
4361}
4362
4363void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4364{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004365 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004366
4367 try
4368 {
4369 if (index >= gl::MAX_VERTEX_ATTRIBS)
4370 {
4371 return error(GL_INVALID_VALUE);
4372 }
4373
4374 UNIMPLEMENTED(); // FIXME
4375 }
4376 catch(std::bad_alloc&)
4377 {
4378 return error(GL_OUT_OF_MEMORY);
4379 }
4380}
4381
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004382void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004383{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004384 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004385 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004386 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004387
4388 try
4389 {
4390 if (index >= gl::MAX_VERTEX_ATTRIBS)
4391 {
4392 return error(GL_INVALID_VALUE);
4393 }
4394
4395 if (size < 1 || size > 4)
4396 {
4397 return error(GL_INVALID_VALUE);
4398 }
4399
4400 switch (type)
4401 {
4402 case GL_BYTE:
4403 case GL_UNSIGNED_BYTE:
4404 case GL_SHORT:
4405 case GL_UNSIGNED_SHORT:
4406 case GL_FIXED:
4407 case GL_FLOAT:
4408 break;
4409 default:
4410 return error(GL_INVALID_ENUM);
4411 }
4412
4413 if (stride < 0)
4414 {
4415 return error(GL_INVALID_VALUE);
4416 }
4417
4418 gl::Context *context = gl::getContext();
4419
4420 if (context)
4421 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004422 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4423 context->vertexAttribute[index].mSize = size;
4424 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004425 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004426 context->vertexAttribute[index].mStride = stride;
4427 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004428 }
4429 }
4430 catch(std::bad_alloc&)
4431 {
4432 return error(GL_OUT_OF_MEMORY);
4433 }
4434}
4435
4436void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4437{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004438 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 +00004439
4440 try
4441 {
4442 if (width < 0 || height < 0)
4443 {
4444 return error(GL_INVALID_VALUE);
4445 }
4446
4447 gl::Context *context = gl::getContext();
4448
4449 if (context)
4450 {
4451 context->viewportX = x;
4452 context->viewportY = y;
4453 context->viewportWidth = width;
4454 context->viewportHeight = height;
4455 }
4456 }
4457 catch(std::bad_alloc&)
4458 {
4459 return error(GL_OUT_OF_MEMORY);
4460 }
4461}
4462
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004463void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4464 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004465{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004466 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4467 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004468 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004469 target, level, internalformat, width, height, depth, border, format, type, pixels);
4470
4471 try
4472 {
4473 UNIMPLEMENTED(); // FIXME
4474 }
4475 catch(std::bad_alloc&)
4476 {
4477 return error(GL_OUT_OF_MEMORY);
4478 }
4479}
4480}