blob: 6147e866db4d86a2ac7aa1d501da176f2172c921 [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 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000704 if (context->getProgram(shader))
705 {
706 return error(GL_INVALID_OPERATION);
707 }
708 else
709 {
710 return error(GL_INVALID_VALUE);
711 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000712 }
713
714 shaderObject->compile();
715 }
716 }
717 catch(std::bad_alloc&)
718 {
719 return error(GL_OUT_OF_MEMORY);
720 }
721}
722
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000723void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
724 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000725{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000726 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000727 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000728 target, level, internalformat, width, height, border, imageSize, data);
729
730 try
731 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000732 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
733 {
734 return error(GL_INVALID_ENUM);
735 }
736
737 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000738 {
739 return error(GL_INVALID_VALUE);
740 }
741
daniel@transgaming.com41430492010-03-11 20:36:18 +0000742 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
743 {
744 return error(GL_INVALID_VALUE);
745 }
746
747 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748 }
749 catch(std::bad_alloc&)
750 {
751 return error(GL_OUT_OF_MEMORY);
752 }
753}
754
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000755void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
756 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000757{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000758 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
759 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000760 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000761 target, level, xoffset, yoffset, width, height, format, imageSize, data);
762
763 try
764 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000765 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
766 {
767 return error(GL_INVALID_ENUM);
768 }
769
770 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000771 {
772 return error(GL_INVALID_VALUE);
773 }
774
daniel@transgaming.com41430492010-03-11 20:36:18 +0000775 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
776 {
777 return error(GL_INVALID_VALUE);
778 }
779
780 if (xoffset != 0 || yoffset != 0)
781 {
782 return error(GL_INVALID_OPERATION);
783 }
784
785 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000786 }
787 catch(std::bad_alloc&)
788 {
789 return error(GL_OUT_OF_MEMORY);
790 }
791}
792
793void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
794{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000795 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
796 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000797 target, level, internalformat, x, y, width, height, border);
798
799 try
800 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000801 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000802 {
803 return error(GL_INVALID_VALUE);
804 }
805
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000806 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
807 {
808 return error(GL_INVALID_VALUE);
809 }
810
811 switch (target)
812 {
813 case GL_TEXTURE_2D:
814 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
815 {
816 return error(GL_INVALID_VALUE);
817 }
818 break;
819 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
820 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
821 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
822 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
823 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
824 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
825 if (!gl::isPow2(width) || !gl::isPow2(height))
826 {
827 return error(GL_INVALID_VALUE);
828 }
829
830 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
831 {
832 return error(GL_INVALID_VALUE);
833 }
834 break;
835 default:
836 return error(GL_INVALID_ENUM);
837 }
838
839 switch (internalformat)
840 {
841 case GL_ALPHA:
842 case GL_LUMINANCE:
843 case GL_LUMINANCE_ALPHA:
844 case GL_RGB:
845 case GL_RGBA:
846 break;
847 default:
848 return error(GL_INVALID_VALUE);
849 }
850
851 if (border != 0)
852 {
853 return error(GL_INVALID_VALUE);
854 }
855
856 gl::Context *context = gl::getContext();
857
858 if (context)
859 {
860 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
861
862 if (target == GL_TEXTURE_2D)
863 {
864 gl::Texture2D *texture = context->getTexture2D();
865
866 if (!texture)
867 {
868 return error(GL_INVALID_OPERATION);
869 }
870
871 texture->copyImage(level, internalformat, x, y, width, height, source);
872 }
873 else if (es2dx::IsCubemapTextureTarget(target))
874 {
875 gl::TextureCubeMap *texture = context->getTextureCubeMap();
876
877 if (!texture)
878 {
879 return error(GL_INVALID_OPERATION);
880 }
881
882 texture->copyImage(target, level, internalformat, x, y, width, height, source);
883 }
884 else
885 {
886 UNREACHABLE();
887 }
888 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000889 }
890 catch(std::bad_alloc&)
891 {
892 return error(GL_OUT_OF_MEMORY);
893 }
894}
895
896void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
897{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000898 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
899 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000900 target, level, xoffset, yoffset, x, y, width, height);
901
902 try
903 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000904 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
905 {
906 return error(GL_INVALID_ENUM);
907 }
908
909 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000910 {
911 return error(GL_INVALID_VALUE);
912 }
913
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000914 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
915 {
916 return error(GL_INVALID_VALUE);
917 }
918
919 if (width == 0 || height == 0)
920 {
921 return;
922 }
923
924 gl::Context *context = gl::getContext();
925
926 if (context)
927 {
928 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
929
930 if (target == GL_TEXTURE_2D)
931 {
932 gl::Texture2D *texture = context->getTexture2D();
933
934 if (!texture)
935 {
936 return error(GL_INVALID_OPERATION);
937 }
938
939 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
940 }
941 else if (es2dx::IsCubemapTextureTarget(target))
942 {
943 gl::TextureCubeMap *texture = context->getTextureCubeMap();
944
945 if (!texture)
946 {
947 return error(GL_INVALID_OPERATION);
948 }
949
950 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
951 }
952 else
953 {
954 UNREACHABLE();
955 }
956 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000957 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000958
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000959 catch(std::bad_alloc&)
960 {
961 return error(GL_OUT_OF_MEMORY);
962 }
963}
964
965GLuint __stdcall glCreateProgram(void)
966{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000967 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000968
969 try
970 {
971 gl::Context *context = gl::getContext();
972
973 if (context)
974 {
975 return context->createProgram();
976 }
977 }
978 catch(std::bad_alloc&)
979 {
980 return error(GL_OUT_OF_MEMORY, 0);
981 }
982
983 return 0;
984}
985
986GLuint __stdcall glCreateShader(GLenum type)
987{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000988 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000989
990 try
991 {
992 gl::Context *context = gl::getContext();
993
994 if (context)
995 {
996 switch (type)
997 {
998 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000999 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001000 return context->createShader(type);
1001 default:
1002 return error(GL_INVALID_ENUM, 0);
1003 }
1004 }
1005 }
1006 catch(std::bad_alloc&)
1007 {
1008 return error(GL_OUT_OF_MEMORY, 0);
1009 }
1010
1011 return 0;
1012}
1013
1014void __stdcall glCullFace(GLenum mode)
1015{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001016 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001017
1018 try
1019 {
1020 switch (mode)
1021 {
1022 case GL_FRONT:
1023 case GL_BACK:
1024 case GL_FRONT_AND_BACK:
1025 {
1026 gl::Context *context = gl::getContext();
1027
1028 if (context)
1029 {
1030 context->cullMode = mode;
1031 }
1032 }
1033 break;
1034 default:
1035 return error(GL_INVALID_ENUM);
1036 }
1037 }
1038 catch(std::bad_alloc&)
1039 {
1040 return error(GL_OUT_OF_MEMORY);
1041 }
1042}
1043
1044void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1045{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001046 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001047
1048 try
1049 {
1050 if (n < 0)
1051 {
1052 return error(GL_INVALID_VALUE);
1053 }
1054
1055 gl::Context *context = gl::getContext();
1056
1057 if (context)
1058 {
1059 for (int i = 0; i < n; i++)
1060 {
1061 context->deleteBuffer(buffers[i]);
1062 }
1063 }
1064 }
1065 catch(std::bad_alloc&)
1066 {
1067 return error(GL_OUT_OF_MEMORY);
1068 }
1069}
1070
1071void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1072{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001073 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001074
1075 try
1076 {
1077 if (n < 0)
1078 {
1079 return error(GL_INVALID_VALUE);
1080 }
1081
1082 gl::Context *context = gl::getContext();
1083
1084 if (context)
1085 {
1086 for (int i = 0; i < n; i++)
1087 {
1088 if (framebuffers[i] != 0)
1089 {
1090 context->deleteFramebuffer(framebuffers[i]);
1091 }
1092 }
1093 }
1094 }
1095 catch(std::bad_alloc&)
1096 {
1097 return error(GL_OUT_OF_MEMORY);
1098 }
1099}
1100
1101void __stdcall glDeleteProgram(GLuint program)
1102{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001103 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001104
1105 try
1106 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001107 if (program == 0)
1108 {
1109 return;
1110 }
1111
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001112 gl::Context *context = gl::getContext();
1113
1114 if (context)
1115 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001116 if (!context->getProgram(program))
1117 {
1118 if(context->getShader(program))
1119 {
1120 return error(GL_INVALID_OPERATION);
1121 }
1122 else
1123 {
1124 return error(GL_INVALID_VALUE);
1125 }
1126 }
1127
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001128 context->deleteProgram(program);
1129 }
1130 }
1131 catch(std::bad_alloc&)
1132 {
1133 return error(GL_OUT_OF_MEMORY);
1134 }
1135}
1136
1137void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1138{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001139 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001140
1141 try
1142 {
1143 if (n < 0)
1144 {
1145 return error(GL_INVALID_VALUE);
1146 }
1147
1148 gl::Context *context = gl::getContext();
1149
1150 if (context)
1151 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001152 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001153 {
1154 context->deleteRenderbuffer(renderbuffers[i]);
1155 }
1156 }
1157 }
1158 catch(std::bad_alloc&)
1159 {
1160 return error(GL_OUT_OF_MEMORY);
1161 }
1162}
1163
1164void __stdcall glDeleteShader(GLuint shader)
1165{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001166 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001167
1168 try
1169 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001170 if (shader == 0)
1171 {
1172 return;
1173 }
1174
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001175 gl::Context *context = gl::getContext();
1176
1177 if (context)
1178 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001179 if (!context->getShader(shader))
1180 {
1181 if(context->getProgram(shader))
1182 {
1183 return error(GL_INVALID_OPERATION);
1184 }
1185 else
1186 {
1187 return error(GL_INVALID_VALUE);
1188 }
1189 }
1190
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001191 context->deleteShader(shader);
1192 }
1193 }
1194 catch(std::bad_alloc&)
1195 {
1196 return error(GL_OUT_OF_MEMORY);
1197 }
1198}
1199
1200void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1201{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001202 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001203
1204 try
1205 {
1206 if (n < 0)
1207 {
1208 return error(GL_INVALID_VALUE);
1209 }
1210
1211 gl::Context *context = gl::getContext();
1212
1213 if (context)
1214 {
1215 for (int i = 0; i < n; i++)
1216 {
1217 if (textures[i] != 0)
1218 {
1219 context->deleteTexture(textures[i]);
1220 }
1221 }
1222 }
1223 }
1224 catch(std::bad_alloc&)
1225 {
1226 return error(GL_OUT_OF_MEMORY);
1227 }
1228}
1229
1230void __stdcall glDepthFunc(GLenum func)
1231{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001232 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001233
1234 try
1235 {
1236 switch (func)
1237 {
1238 case GL_NEVER:
1239 case GL_ALWAYS:
1240 case GL_LESS:
1241 case GL_LEQUAL:
1242 case GL_EQUAL:
1243 case GL_GREATER:
1244 case GL_GEQUAL:
1245 case GL_NOTEQUAL:
1246 break;
1247 default:
1248 return error(GL_INVALID_ENUM);
1249 }
1250
1251 gl::Context *context = gl::getContext();
1252
1253 if (context)
1254 {
1255 context->depthFunc = func;
1256 }
1257 }
1258 catch(std::bad_alloc&)
1259 {
1260 return error(GL_OUT_OF_MEMORY);
1261 }
1262}
1263
1264void __stdcall glDepthMask(GLboolean flag)
1265{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001266 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001267
1268 try
1269 {
1270 gl::Context *context = gl::getContext();
1271
1272 if (context)
1273 {
1274 context->depthMask = flag != GL_FALSE;
1275 }
1276 }
1277 catch(std::bad_alloc&)
1278 {
1279 return error(GL_OUT_OF_MEMORY);
1280 }
1281}
1282
1283void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1284{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001285 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001286
1287 try
1288 {
1289 gl::Context *context = gl::getContext();
1290
1291 if (context)
1292 {
1293 context->zNear = zNear;
1294 context->zFar = zFar;
1295 }
1296 }
1297 catch(std::bad_alloc&)
1298 {
1299 return error(GL_OUT_OF_MEMORY);
1300 }
1301}
1302
1303void __stdcall glDetachShader(GLuint program, GLuint shader)
1304{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001305 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001306
1307 try
1308 {
1309 gl::Context *context = gl::getContext();
1310
1311 if (context)
1312 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001313
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001314 gl::Program *programObject = context->getProgram(program);
1315 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001316
1317 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001318 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001319 gl::Shader *shaderByProgramHandle;
1320 shaderByProgramHandle = context->getShader(program);
1321 if (!shaderByProgramHandle)
1322 {
1323 return error(GL_INVALID_VALUE);
1324 }
1325 else
1326 {
1327 return error(GL_INVALID_OPERATION);
1328 }
1329 }
1330
1331 if (!shaderObject)
1332 {
1333 gl::Program *programByShaderHandle = context->getProgram(shader);
1334 if (!programByShaderHandle)
1335 {
1336 return error(GL_INVALID_VALUE);
1337 }
1338 else
1339 {
1340 return error(GL_INVALID_OPERATION);
1341 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001342 }
1343
1344 if (!programObject->detachShader(shaderObject))
1345 {
1346 return error(GL_INVALID_OPERATION);
1347 }
1348
1349 if (shaderObject->isDeletable())
1350 {
1351 context->deleteShader(shader);
1352 }
1353 }
1354 }
1355 catch(std::bad_alloc&)
1356 {
1357 return error(GL_OUT_OF_MEMORY);
1358 }
1359}
1360
1361void __stdcall glDisable(GLenum cap)
1362{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001363 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001364
1365 try
1366 {
1367 gl::Context *context = gl::getContext();
1368
1369 if (context)
1370 {
1371 switch (cap)
1372 {
1373 case GL_CULL_FACE: context->cullFace = false; break;
1374 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1375 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1376 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1377 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1378 case GL_STENCIL_TEST: context->stencilTest = false; break;
1379 case GL_DEPTH_TEST: context->depthTest = false; break;
1380 case GL_BLEND: context->blend = false; break;
1381 case GL_DITHER: context->dither = false; break;
1382 default:
1383 return error(GL_INVALID_ENUM);
1384 }
1385 }
1386 }
1387 catch(std::bad_alloc&)
1388 {
1389 return error(GL_OUT_OF_MEMORY);
1390 }
1391}
1392
1393void __stdcall glDisableVertexAttribArray(GLuint index)
1394{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001395 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001396
1397 try
1398 {
1399 if (index >= gl::MAX_VERTEX_ATTRIBS)
1400 {
1401 return error(GL_INVALID_VALUE);
1402 }
1403
1404 gl::Context *context = gl::getContext();
1405
1406 if (context)
1407 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001408 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001409 }
1410 }
1411 catch(std::bad_alloc&)
1412 {
1413 return error(GL_OUT_OF_MEMORY);
1414 }
1415}
1416
1417void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1418{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001419 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001420
1421 try
1422 {
1423 if (count < 0 || first < 0)
1424 {
1425 return error(GL_INVALID_VALUE);
1426 }
1427
1428 gl::Context *context = gl::getContext();
1429
1430 if (context)
1431 {
1432 context->drawArrays(mode, first, count);
1433 }
1434 }
1435 catch(std::bad_alloc&)
1436 {
1437 return error(GL_OUT_OF_MEMORY);
1438 }
1439}
1440
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001441void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001442{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001443 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 +00001444 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001445
1446 try
1447 {
1448 if (count < 0)
1449 {
1450 return error(GL_INVALID_VALUE);
1451 }
1452
1453 switch (type)
1454 {
1455 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001456 case GL_UNSIGNED_SHORT:
1457 break;
1458 default:
1459 return error(GL_INVALID_ENUM);
1460 }
1461
1462 gl::Context *context = gl::getContext();
1463
1464 if (context)
1465 {
1466 context->drawElements(mode, count, type, indices);
1467 }
1468 }
1469 catch(std::bad_alloc&)
1470 {
1471 return error(GL_OUT_OF_MEMORY);
1472 }
1473}
1474
1475void __stdcall glEnable(GLenum cap)
1476{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001477 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001478
1479 try
1480 {
1481 gl::Context *context = gl::getContext();
1482
1483 if (context)
1484 {
1485 switch (cap)
1486 {
1487 case GL_CULL_FACE: context->cullFace = true; break;
1488 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1489 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1490 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1491 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1492 case GL_STENCIL_TEST: context->stencilTest = true; break;
1493 case GL_DEPTH_TEST: context->depthTest = true; break;
1494 case GL_BLEND: context->blend = true; break;
1495 case GL_DITHER: context->dither = true; break;
1496 default:
1497 return error(GL_INVALID_ENUM);
1498 }
1499 }
1500 }
1501 catch(std::bad_alloc&)
1502 {
1503 return error(GL_OUT_OF_MEMORY);
1504 }
1505}
1506
1507void __stdcall glEnableVertexAttribArray(GLuint index)
1508{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001509 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001510
1511 try
1512 {
1513 if (index >= gl::MAX_VERTEX_ATTRIBS)
1514 {
1515 return error(GL_INVALID_VALUE);
1516 }
1517
1518 gl::Context *context = gl::getContext();
1519
1520 if (context)
1521 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001522 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001523 }
1524 }
1525 catch(std::bad_alloc&)
1526 {
1527 return error(GL_OUT_OF_MEMORY);
1528 }
1529}
1530
1531void __stdcall glFinish(void)
1532{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001533 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001534
1535 try
1536 {
1537 gl::Context *context = gl::getContext();
1538
1539 if (context)
1540 {
1541 context->finish();
1542 }
1543 }
1544 catch(std::bad_alloc&)
1545 {
1546 return error(GL_OUT_OF_MEMORY);
1547 }
1548}
1549
1550void __stdcall glFlush(void)
1551{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001552 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001553
1554 try
1555 {
1556 gl::Context *context = gl::getContext();
1557
1558 if (context)
1559 {
1560 context->flush();
1561 }
1562 }
1563 catch(std::bad_alloc&)
1564 {
1565 return error(GL_OUT_OF_MEMORY);
1566 }
1567}
1568
1569void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1570{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001571 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1572 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001573
1574 try
1575 {
1576 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1577 {
1578 return error(GL_INVALID_ENUM);
1579 }
1580
1581 gl::Context *context = gl::getContext();
1582
1583 if (context)
1584 {
1585 gl::Framebuffer *framebuffer = context->getFramebuffer();
1586
1587 if (context->framebuffer == 0 || !framebuffer)
1588 {
1589 return error(GL_INVALID_OPERATION);
1590 }
1591
1592 switch (attachment)
1593 {
1594 case GL_COLOR_ATTACHMENT0:
1595 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1596 break;
1597 case GL_DEPTH_ATTACHMENT:
1598 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1599 break;
1600 case GL_STENCIL_ATTACHMENT:
1601 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1602 break;
1603 default:
1604 return error(GL_INVALID_ENUM);
1605 }
1606 }
1607 }
1608 catch(std::bad_alloc&)
1609 {
1610 return error(GL_OUT_OF_MEMORY);
1611 }
1612}
1613
1614void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1615{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001616 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1617 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001618
1619 try
1620 {
1621 if (target != GL_FRAMEBUFFER)
1622 {
1623 return error(GL_INVALID_ENUM);
1624 }
1625
1626 switch (attachment)
1627 {
1628 case GL_COLOR_ATTACHMENT0:
1629 break;
1630 default:
1631 return error(GL_INVALID_ENUM);
1632 }
1633
1634 gl::Context *context = gl::getContext();
1635
1636 if (context)
1637 {
1638 if (texture)
1639 {
1640 switch (textarget)
1641 {
1642 case GL_TEXTURE_2D:
1643 if (!context->getTexture2D())
1644 {
1645 return error(GL_INVALID_OPERATION);
1646 }
1647 break;
1648 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1649 UNIMPLEMENTED(); // FIXME
1650 break;
1651 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1652 UNIMPLEMENTED(); // FIXME
1653 break;
1654 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1655 UNIMPLEMENTED(); // FIXME
1656 break;
1657 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1658 UNIMPLEMENTED(); // FIXME
1659 break;
1660 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1661 UNIMPLEMENTED(); // FIXME
1662 break;
1663 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1664 UNIMPLEMENTED(); // FIXME
1665 break;
1666 default:
1667 return error(GL_INVALID_ENUM);
1668 }
1669
1670 if (level != 0)
1671 {
1672 return error(GL_INVALID_VALUE);
1673 }
1674 }
1675
1676 gl::Framebuffer *framebuffer = context->getFramebuffer();
1677
1678 if (context->framebuffer == 0 || !framebuffer)
1679 {
1680 return error(GL_INVALID_OPERATION);
1681 }
1682
1683 framebuffer->setColorbuffer(GL_TEXTURE, texture);
1684 }
1685 }
1686 catch(std::bad_alloc&)
1687 {
1688 return error(GL_OUT_OF_MEMORY);
1689 }
1690}
1691
1692void __stdcall glFrontFace(GLenum mode)
1693{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001694 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001695
1696 try
1697 {
1698 switch (mode)
1699 {
1700 case GL_CW:
1701 case GL_CCW:
1702 {
1703 gl::Context *context = gl::getContext();
1704
1705 if (context)
1706 {
1707 context->frontFace = mode;
1708 }
1709 }
1710 break;
1711 default:
1712 return error(GL_INVALID_ENUM);
1713 }
1714 }
1715 catch(std::bad_alloc&)
1716 {
1717 return error(GL_OUT_OF_MEMORY);
1718 }
1719}
1720
1721void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1722{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001723 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
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 buffers[i] = context->createBuffer();
1739 }
1740 }
1741 }
1742 catch(std::bad_alloc&)
1743 {
1744 return error(GL_OUT_OF_MEMORY);
1745 }
1746}
1747
1748void __stdcall glGenerateMipmap(GLenum target)
1749{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001750 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001751
1752 try
1753 {
1754 UNIMPLEMENTED(); // FIXME
1755 }
1756 catch(std::bad_alloc&)
1757 {
1758 return error(GL_OUT_OF_MEMORY);
1759 }
1760}
1761
1762void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1763{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001764 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001765
1766 try
1767 {
1768 if (n < 0)
1769 {
1770 return error(GL_INVALID_VALUE);
1771 }
1772
1773 gl::Context *context = gl::getContext();
1774
1775 if (context)
1776 {
1777 for (int i = 0; i < n; i++)
1778 {
1779 framebuffers[i] = context->createFramebuffer();
1780 }
1781 }
1782 }
1783 catch(std::bad_alloc&)
1784 {
1785 return error(GL_OUT_OF_MEMORY);
1786 }
1787}
1788
1789void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1790{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001791 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001792
1793 try
1794 {
1795 if (n < 0)
1796 {
1797 return error(GL_INVALID_VALUE);
1798 }
1799
1800 gl::Context *context = gl::getContext();
1801
1802 if (context)
1803 {
1804 for (int i = 0; i < n; i++)
1805 {
1806 renderbuffers[i] = context->createRenderbuffer();
1807 }
1808 }
1809 }
1810 catch(std::bad_alloc&)
1811 {
1812 return error(GL_OUT_OF_MEMORY);
1813 }
1814}
1815
1816void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1817{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001818 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001819
1820 try
1821 {
1822 if (n < 0)
1823 {
1824 return error(GL_INVALID_VALUE);
1825 }
1826
1827 gl::Context *context = gl::getContext();
1828
1829 if (context)
1830 {
1831 for (int i = 0; i < n; i++)
1832 {
1833 textures[i] = context->createTexture();
1834 }
1835 }
1836 }
1837 catch(std::bad_alloc&)
1838 {
1839 return error(GL_OUT_OF_MEMORY);
1840 }
1841}
1842
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001843void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001844{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001845 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001846 "GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001847 program, index, bufsize, length, size, type, name);
1848
1849 try
1850 {
1851 if (bufsize < 0)
1852 {
1853 return error(GL_INVALID_VALUE);
1854 }
1855
1856 UNIMPLEMENTED(); // FIXME
1857 }
1858 catch(std::bad_alloc&)
1859 {
1860 return error(GL_OUT_OF_MEMORY);
1861 }
1862}
1863
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001864void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001865{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001866 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001867 "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 +00001868 program, index, bufsize, length, size, type, name);
1869
1870 try
1871 {
1872 if (bufsize < 0)
1873 {
1874 return error(GL_INVALID_VALUE);
1875 }
1876
1877 UNIMPLEMENTED(); // FIXME
1878 }
1879 catch(std::bad_alloc&)
1880 {
1881 return error(GL_OUT_OF_MEMORY);
1882 }
1883}
1884
1885void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1886{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001887 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1888 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001889
1890 try
1891 {
1892 if (maxcount < 0)
1893 {
1894 return error(GL_INVALID_VALUE);
1895 }
1896
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001897 gl::Context *context = gl::getContext();
1898
1899 if (context)
1900 {
1901 gl::Program *programObject = context->getProgram(program);
1902
1903 if (!programObject)
1904 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001905 if (context->getShader(program))
1906 {
1907 return error(GL_INVALID_OPERATION);
1908 }
1909 else
1910 {
1911 return error(GL_INVALID_VALUE);
1912 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001913 }
1914
1915 return programObject->getAttachedShaders(maxcount, count, shaders);
1916 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001917 }
1918 catch(std::bad_alloc&)
1919 {
1920 return error(GL_OUT_OF_MEMORY);
1921 }
1922}
1923
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001924int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001925{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001926 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001927
1928 try
1929 {
1930 gl::Context *context = gl::getContext();
1931
1932 if (context)
1933 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001934
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001935 gl::Program *programObject = context->getProgram(program);
1936
1937 if (!programObject)
1938 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001939 if (context->getShader(program))
1940 {
1941 return error(GL_INVALID_OPERATION, -1);
1942 }
1943 else
1944 {
1945 return error(GL_INVALID_VALUE, -1);
1946 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001947 }
1948
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00001949 if (!programObject->isLinked())
1950 {
1951 return error(GL_INVALID_OPERATION, -1);
1952 }
1953
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001954 return programObject->getAttributeLocation(name);
1955 }
1956 }
1957 catch(std::bad_alloc&)
1958 {
1959 return error(GL_OUT_OF_MEMORY, -1);
1960 }
1961
1962 return -1;
1963}
1964
1965void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1966{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001967 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001968
1969 try
1970 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001971 gl::Context *context = gl::getContext();
1972
1973 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001974 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001975 if (!(context->getBooleanv(pname, params)))
1976 {
1977 GLenum nativeType;
1978 unsigned int numParams = 0;
1979 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1980 return error(GL_INVALID_ENUM);
1981
1982 if (numParams == 0)
1983 return; // it is known that the pname is valid, but there are no parameters to return
1984
1985 if (nativeType == GL_FLOAT)
1986 {
1987 GLfloat *floatParams = NULL;
1988 floatParams = new GLfloat[numParams];
1989
1990 context->getFloatv(pname, floatParams);
1991
1992 for (unsigned int i = 0; i < numParams; ++i)
1993 {
1994 if (floatParams[i] == 0.0f)
1995 params[i] = GL_FALSE;
1996 else
1997 params[i] = GL_TRUE;
1998 }
1999
2000 delete [] floatParams;
2001 }
2002 else if (nativeType == GL_INT)
2003 {
2004 GLint *intParams = NULL;
2005 intParams = new GLint[numParams];
2006
2007 context->getIntegerv(pname, intParams);
2008
2009 for (unsigned int i = 0; i < numParams; ++i)
2010 {
2011 if (intParams[i] == 0)
2012 params[i] = GL_FALSE;
2013 else
2014 params[i] = GL_TRUE;
2015 }
2016
2017 delete [] intParams;
2018 }
2019 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002020 }
2021 }
2022 catch(std::bad_alloc&)
2023 {
2024 return error(GL_OUT_OF_MEMORY);
2025 }
2026}
2027
2028void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2029{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002030 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 +00002031
2032 try
2033 {
2034 UNIMPLEMENTED(); // FIXME
2035 }
2036 catch(std::bad_alloc&)
2037 {
2038 return error(GL_OUT_OF_MEMORY);
2039 }
2040}
2041
2042GLenum __stdcall glGetError(void)
2043{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002044 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002045
2046 gl::Context *context = gl::getContext();
2047
2048 if (context)
2049 {
2050 return context->getError();
2051 }
2052
2053 return GL_NO_ERROR;
2054}
2055
2056void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2057{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002058 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002059
2060 try
2061 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002062 gl::Context *context = gl::getContext();
2063
2064 if (context)
2065 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002066 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002067 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002068 GLenum nativeType;
2069 unsigned int numParams = 0;
2070 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2071 return error(GL_INVALID_ENUM);
2072
2073 if (numParams == 0)
2074 return; // it is known that the pname is valid, but that there are no parameters to return.
2075
2076 if (nativeType == GL_BOOL)
2077 {
2078 GLboolean *boolParams = NULL;
2079 boolParams = new GLboolean[numParams];
2080
2081 context->getBooleanv(pname, boolParams);
2082
2083 for (unsigned int i = 0; i < numParams; ++i)
2084 {
2085 if (boolParams[i] == GL_FALSE)
2086 params[i] = 0.0f;
2087 else
2088 params[i] = 1.0f;
2089 }
2090
2091 delete [] boolParams;
2092 }
2093 else if (nativeType == GL_INT)
2094 {
2095 GLint *intParams = NULL;
2096 intParams = new GLint[numParams];
2097
2098 context->getIntegerv(pname, intParams);
2099
2100 for (unsigned int i = 0; i < numParams; ++i)
2101 {
2102 params[i] = (GLfloat)intParams[i];
2103 }
2104
2105 delete [] intParams;
2106 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002107 }
2108 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002109 }
2110 catch(std::bad_alloc&)
2111 {
2112 return error(GL_OUT_OF_MEMORY);
2113 }
2114}
2115
2116void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2117{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002118 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2119 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002120
2121 try
2122 {
2123 gl::Context *context = gl::getContext();
2124
2125 if (context)
2126 {
2127 if (context->framebuffer == 0)
2128 {
2129 return error(GL_INVALID_OPERATION);
2130 }
2131
2132 UNIMPLEMENTED(); // FIXME
2133 }
2134 }
2135 catch(std::bad_alloc&)
2136 {
2137 return error(GL_OUT_OF_MEMORY);
2138 }
2139}
2140
2141void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2142{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002143 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002144
2145 try
2146 {
2147 gl::Context *context = gl::getContext();
2148
2149 if (context)
2150 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002151 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002152 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002153 GLenum nativeType;
2154 unsigned int numParams = 0;
2155 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2156 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002157
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002158 if (numParams == 0)
2159 return; // it is known that pname is valid, but there are no parameters to return
2160
2161 if (nativeType == GL_BOOL)
2162 {
2163 GLboolean *boolParams = NULL;
2164 boolParams = new GLboolean[numParams];
2165
2166 context->getBooleanv(pname, boolParams);
2167
2168 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002169 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002170 if (boolParams[i] == GL_FALSE)
2171 params[i] = 0;
2172 else
2173 params[i] = 1;
2174 }
2175
2176 delete [] boolParams;
2177 }
2178 else if (nativeType == GL_FLOAT)
2179 {
2180 GLfloat *floatParams = NULL;
2181 floatParams = new GLfloat[numParams];
2182
2183 context->getFloatv(pname, floatParams);
2184
2185 for (unsigned int i = 0; i < numParams; ++i)
2186 {
2187 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002188 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002189 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002190 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002191 else
2192 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 +00002193 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002194
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002195 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002196 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002197 }
2198 }
2199 }
2200 catch(std::bad_alloc&)
2201 {
2202 return error(GL_OUT_OF_MEMORY);
2203 }
2204}
2205
2206void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2207{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002208 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002209
2210 try
2211 {
2212 gl::Context *context = gl::getContext();
2213
2214 if (context)
2215 {
2216 gl::Program *programObject = context->getProgram(program);
2217
2218 if (!programObject)
2219 {
2220 return error(GL_INVALID_VALUE);
2221 }
2222
2223 switch (pname)
2224 {
2225 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002226 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002227 return;
2228 case GL_LINK_STATUS:
2229 *params = programObject->isLinked();
2230 return;
2231 case GL_VALIDATE_STATUS:
2232 UNIMPLEMENTED(); // FIXME
2233 *params = GL_TRUE;
2234 return;
2235 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002236 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002237 return;
2238 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002239 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002240 return;
2241 case GL_ACTIVE_ATTRIBUTES:
2242 UNIMPLEMENTED(); // FIXME
2243 *params = 0;
2244 return;
2245 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2246 UNIMPLEMENTED(); // FIXME
2247 *params = 0;
2248 return;
2249 case GL_ACTIVE_UNIFORMS:
2250 UNIMPLEMENTED(); // FIXME
2251 *params = 0;
2252 return;
2253 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2254 UNIMPLEMENTED(); // FIXME
2255 *params = 0;
2256 return;
2257 default:
2258 return error(GL_INVALID_ENUM);
2259 }
2260 }
2261 }
2262 catch(std::bad_alloc&)
2263 {
2264 return error(GL_OUT_OF_MEMORY);
2265 }
2266}
2267
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002268void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002269{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002270 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 +00002271 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002272
2273 try
2274 {
2275 if (bufsize < 0)
2276 {
2277 return error(GL_INVALID_VALUE);
2278 }
2279
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002280 gl::Context *context = gl::getContext();
2281
2282 if (context)
2283 {
2284 gl::Program *programObject = context->getProgram(program);
2285
2286 if (!programObject)
2287 {
2288 return error(GL_INVALID_VALUE);
2289 }
2290
2291 programObject->getInfoLog(bufsize, length, infolog);
2292 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002293 }
2294 catch(std::bad_alloc&)
2295 {
2296 return error(GL_OUT_OF_MEMORY);
2297 }
2298}
2299
2300void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2301{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002302 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 +00002303
2304 try
2305 {
2306 UNIMPLEMENTED(); // FIXME
2307 }
2308 catch(std::bad_alloc&)
2309 {
2310 return error(GL_OUT_OF_MEMORY);
2311 }
2312}
2313
2314void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2315{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002316 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002317
2318 try
2319 {
2320 gl::Context *context = gl::getContext();
2321
2322 if (context)
2323 {
2324 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002325
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002326 if (!shaderObject)
2327 {
2328 return error(GL_INVALID_VALUE);
2329 }
2330
2331 switch (pname)
2332 {
2333 case GL_SHADER_TYPE:
2334 *params = shaderObject->getType();
2335 return;
2336 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002337 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002338 return;
2339 case GL_COMPILE_STATUS:
2340 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2341 return;
2342 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002343 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002344 return;
2345 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002346 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002347 return;
2348 default:
2349 return error(GL_INVALID_ENUM);
2350 }
2351 }
2352 }
2353 catch(std::bad_alloc&)
2354 {
2355 return error(GL_OUT_OF_MEMORY);
2356 }
2357}
2358
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002359void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002360{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002361 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 +00002362 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002363
2364 try
2365 {
2366 if (bufsize < 0)
2367 {
2368 return error(GL_INVALID_VALUE);
2369 }
2370
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002371 gl::Context *context = gl::getContext();
2372
2373 if (context)
2374 {
2375 gl::Shader *shaderObject = context->getShader(shader);
2376
2377 if (!shaderObject)
2378 {
2379 return error(GL_INVALID_VALUE);
2380 }
2381
2382 shaderObject->getInfoLog(bufsize, length, infolog);
2383 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002384 }
2385 catch(std::bad_alloc&)
2386 {
2387 return error(GL_OUT_OF_MEMORY);
2388 }
2389}
2390
2391void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2392{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002393 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2394 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002395
2396 try
2397 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002398 switch (shadertype)
2399 {
2400 case GL_VERTEX_SHADER:
2401 case GL_FRAGMENT_SHADER:
2402 break;
2403 default:
2404 return error(GL_INVALID_ENUM);
2405 }
2406
2407 switch (precisiontype)
2408 {
2409 case GL_LOW_FLOAT:
2410 case GL_MEDIUM_FLOAT:
2411 case GL_HIGH_FLOAT:
2412 // Assume IEEE 754 precision
2413 range[0] = 127;
2414 range[1] = 127;
2415 precision[0] = 23;
2416 precision[1] = 23;
2417 break;
2418 case GL_LOW_INT:
2419 case GL_MEDIUM_INT:
2420 case GL_HIGH_INT:
2421 // Some (most) hardware only supports single-precision floating-point numbers,
2422 // which can accurately represent integers up to +/-16777216
2423 range[0] = 24;
2424 range[1] = 24;
2425 precision[0] = 0;
2426 precision[1] = 0;
2427 break;
2428 default:
2429 return error(GL_INVALID_ENUM);
2430 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002431 }
2432 catch(std::bad_alloc&)
2433 {
2434 return error(GL_OUT_OF_MEMORY);
2435 }
2436}
2437
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002438void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002439{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002440 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 +00002441 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002442
2443 try
2444 {
2445 if (bufsize < 0)
2446 {
2447 return error(GL_INVALID_VALUE);
2448 }
2449
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002450 gl::Context *context = gl::getContext();
2451
2452 if (context)
2453 {
2454 gl::Shader *shaderObject = context->getShader(shader);
2455
2456 if (!shaderObject)
2457 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002458 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002459 }
2460
2461 shaderObject->getSource(bufsize, length, source);
2462 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002463 }
2464 catch(std::bad_alloc&)
2465 {
2466 return error(GL_OUT_OF_MEMORY);
2467 }
2468}
2469
2470const GLubyte* __stdcall glGetString(GLenum name)
2471{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002472 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002473
2474 try
2475 {
2476 switch (name)
2477 {
2478 case GL_VENDOR:
2479 return (GLubyte*)"TransGaming Inc.";
2480 case GL_RENDERER:
2481 return (GLubyte*)"ANGLE";
2482 case GL_VERSION:
2483 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2484 case GL_SHADING_LANGUAGE_VERSION:
2485 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2486 case GL_EXTENSIONS:
2487 return (GLubyte*)"";
2488 default:
2489 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2490 }
2491 }
2492 catch(std::bad_alloc&)
2493 {
2494 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2495 }
2496
2497 return NULL;
2498}
2499
2500void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2501{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002502 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 +00002503
2504 try
2505 {
2506 UNIMPLEMENTED(); // FIXME
2507 }
2508 catch(std::bad_alloc&)
2509 {
2510 return error(GL_OUT_OF_MEMORY);
2511 }
2512}
2513
2514void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2515{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002516 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 +00002517
2518 try
2519 {
2520 UNIMPLEMENTED(); // FIXME
2521 }
2522 catch(std::bad_alloc&)
2523 {
2524 return error(GL_OUT_OF_MEMORY);
2525 }
2526}
2527
2528void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2529{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002530 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002531
2532 try
2533 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002534 gl::Context *context = gl::getContext();
2535
2536 if (context)
2537 {
2538 if (program == 0)
2539 {
2540 return error(GL_INVALID_VALUE);
2541 }
2542
2543 gl::Program *programObject = context->getProgram(program);
2544
2545 if (!programObject || !programObject->isLinked())
2546 {
2547 return error(GL_INVALID_OPERATION);
2548 }
2549
2550 if (!programObject->getUniformfv(location, params))
2551 {
2552 return error(GL_INVALID_OPERATION);
2553 }
2554 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002555 }
2556 catch(std::bad_alloc&)
2557 {
2558 return error(GL_OUT_OF_MEMORY);
2559 }
2560}
2561
2562void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2563{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002564 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002565
2566 try
2567 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002568 gl::Context *context = gl::getContext();
2569
2570 if (context)
2571 {
2572 if (program == 0)
2573 {
2574 return error(GL_INVALID_VALUE);
2575 }
2576
2577 gl::Program *programObject = context->getProgram(program);
2578
2579 if (!programObject || !programObject->isLinked())
2580 {
2581 return error(GL_INVALID_OPERATION);
2582 }
2583
2584 if (!programObject)
2585 {
2586 return error(GL_INVALID_OPERATION);
2587 }
2588
2589 if (!programObject->getUniformiv(location, params))
2590 {
2591 return error(GL_INVALID_OPERATION);
2592 }
2593 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002594 }
2595 catch(std::bad_alloc&)
2596 {
2597 return error(GL_OUT_OF_MEMORY);
2598 }
2599}
2600
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002601int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002602{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002603 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002604
2605 try
2606 {
2607 gl::Context *context = gl::getContext();
2608
2609 if (strstr(name, "gl_") == name)
2610 {
2611 return -1;
2612 }
2613
2614 if (context)
2615 {
2616 gl::Program *programObject = context->getProgram(program);
2617
2618 if (!programObject)
2619 {
2620 return error(GL_INVALID_VALUE, -1);
2621 }
2622
2623 if (!programObject->isLinked())
2624 {
2625 return error(GL_INVALID_OPERATION, -1);
2626 }
2627
2628 return programObject->getUniformLocation(name);
2629 }
2630 }
2631 catch(std::bad_alloc&)
2632 {
2633 return error(GL_OUT_OF_MEMORY, -1);
2634 }
2635
2636 return -1;
2637}
2638
2639void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2640{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002641 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002642
2643 try
2644 {
2645 if (index >= gl::MAX_VERTEX_ATTRIBS)
2646 {
2647 return error(GL_INVALID_VALUE);
2648 }
2649
2650 UNIMPLEMENTED(); // FIXME
2651 }
2652 catch(std::bad_alloc&)
2653 {
2654 return error(GL_OUT_OF_MEMORY);
2655 }
2656}
2657
2658void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2659{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002660 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002661
2662 try
2663 {
2664 if (index >= gl::MAX_VERTEX_ATTRIBS)
2665 {
2666 return error(GL_INVALID_VALUE);
2667 }
2668
2669 UNIMPLEMENTED(); // FIXME
2670 }
2671 catch(std::bad_alloc&)
2672 {
2673 return error(GL_OUT_OF_MEMORY);
2674 }
2675}
2676
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002677void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002678{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002679 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002680
2681 try
2682 {
2683 if (index >= gl::MAX_VERTEX_ATTRIBS)
2684 {
2685 return error(GL_INVALID_VALUE);
2686 }
2687
2688 UNIMPLEMENTED(); // FIXME
2689 }
2690 catch(std::bad_alloc&)
2691 {
2692 return error(GL_OUT_OF_MEMORY);
2693 }
2694}
2695
2696void __stdcall glHint(GLenum target, GLenum mode)
2697{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002698 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002699
2700 try
2701 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002702 switch (target)
2703 {
2704 case GL_GENERATE_MIPMAP_HINT:
2705 switch (mode)
2706 {
2707 case GL_FASTEST:
2708 case GL_NICEST:
2709 case GL_DONT_CARE:
2710 break;
2711 default:
2712 return error(GL_INVALID_ENUM);
2713 }
2714 break;
2715 default:
2716 return error(GL_INVALID_ENUM);
2717 }
2718
2719 gl::Context *context = gl::getContext();
2720 if (context)
2721 {
2722 if (target == GL_GENERATE_MIPMAP_HINT)
2723 context->generateMipmapHint = mode;
2724 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002725 }
2726 catch(std::bad_alloc&)
2727 {
2728 return error(GL_OUT_OF_MEMORY);
2729 }
2730}
2731
2732GLboolean __stdcall glIsBuffer(GLuint buffer)
2733{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002734 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002735
2736 try
2737 {
2738 gl::Context *context = gl::getContext();
2739
2740 if (context && buffer)
2741 {
2742 gl::Buffer *bufferObject = context->getBuffer(buffer);
2743
2744 if (bufferObject)
2745 {
2746 return GL_TRUE;
2747 }
2748 }
2749 }
2750 catch(std::bad_alloc&)
2751 {
2752 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2753 }
2754
2755 return GL_FALSE;
2756}
2757
2758GLboolean __stdcall glIsEnabled(GLenum cap)
2759{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002760 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002761
2762 try
2763 {
2764 gl::Context *context = gl::getContext();
2765
2766 if (context)
2767 {
2768 switch (cap)
2769 {
2770 case GL_CULL_FACE: return context->cullFace;
2771 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
2772 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
2773 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
2774 case GL_SCISSOR_TEST: return context->scissorTest;
2775 case GL_STENCIL_TEST: return context->stencilTest;
2776 case GL_DEPTH_TEST: return context->depthTest;
2777 case GL_BLEND: return context->blend;
2778 case GL_DITHER: return context->dither;
2779 default:
2780 return error(GL_INVALID_ENUM, false);
2781 }
2782 }
2783 }
2784 catch(std::bad_alloc&)
2785 {
2786 return error(GL_OUT_OF_MEMORY, false);
2787 }
2788
2789 return false;
2790}
2791
2792GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
2793{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002794 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002795
2796 try
2797 {
2798 gl::Context *context = gl::getContext();
2799
2800 if (context && framebuffer)
2801 {
2802 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2803
2804 if (framebufferObject)
2805 {
2806 return GL_TRUE;
2807 }
2808 }
2809 }
2810 catch(std::bad_alloc&)
2811 {
2812 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2813 }
2814
2815 return GL_FALSE;
2816}
2817
2818GLboolean __stdcall glIsProgram(GLuint program)
2819{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002820 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002821
2822 try
2823 {
2824 gl::Context *context = gl::getContext();
2825
2826 if (context && program)
2827 {
2828 gl::Program *programObject = context->getProgram(program);
2829
2830 if (programObject)
2831 {
2832 return GL_TRUE;
2833 }
2834 }
2835 }
2836 catch(std::bad_alloc&)
2837 {
2838 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2839 }
2840
2841 return GL_FALSE;
2842}
2843
2844GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
2845{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002846 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002847
2848 try
2849 {
2850 gl::Context *context = gl::getContext();
2851
2852 if (context && renderbuffer)
2853 {
2854 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2855
2856 if (renderbufferObject)
2857 {
2858 return GL_TRUE;
2859 }
2860 }
2861 }
2862 catch(std::bad_alloc&)
2863 {
2864 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2865 }
2866
2867 return GL_FALSE;
2868}
2869
2870GLboolean __stdcall glIsShader(GLuint shader)
2871{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002872 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002873
2874 try
2875 {
2876 gl::Context *context = gl::getContext();
2877
2878 if (context && shader)
2879 {
2880 gl::Shader *shaderObject = context->getShader(shader);
2881
2882 if (shaderObject)
2883 {
2884 return GL_TRUE;
2885 }
2886 }
2887 }
2888 catch(std::bad_alloc&)
2889 {
2890 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2891 }
2892
2893 return GL_FALSE;
2894}
2895
2896GLboolean __stdcall glIsTexture(GLuint texture)
2897{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002898 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002899
2900 try
2901 {
2902 gl::Context *context = gl::getContext();
2903
2904 if (context && texture)
2905 {
2906 gl::Texture *textureObject = context->getTexture(texture);
2907
2908 if (textureObject)
2909 {
2910 return GL_TRUE;
2911 }
2912 }
2913 }
2914 catch(std::bad_alloc&)
2915 {
2916 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2917 }
2918
2919 return GL_FALSE;
2920}
2921
2922void __stdcall glLineWidth(GLfloat width)
2923{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002924 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002925
2926 try
2927 {
2928 if (width <= 0.0f)
2929 {
2930 return error(GL_INVALID_VALUE);
2931 }
2932
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002933 gl::Context *context = gl::getContext();
2934
2935 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002936 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002937 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002938 }
2939 }
2940 catch(std::bad_alloc&)
2941 {
2942 return error(GL_OUT_OF_MEMORY);
2943 }
2944}
2945
2946void __stdcall glLinkProgram(GLuint program)
2947{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002948 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002949
2950 try
2951 {
2952 gl::Context *context = gl::getContext();
2953
2954 if (context)
2955 {
2956 gl::Program *programObject = context->getProgram(program);
2957
2958 if (!programObject)
2959 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00002960 if (context->getShader(program))
2961 {
2962 return error(GL_INVALID_OPERATION);
2963 }
2964 else
2965 {
2966 return error(GL_INVALID_VALUE);
2967 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002968 }
2969
2970 programObject->link();
2971 }
2972 }
2973 catch(std::bad_alloc&)
2974 {
2975 return error(GL_OUT_OF_MEMORY);
2976 }
2977}
2978
2979void __stdcall glPixelStorei(GLenum pname, GLint param)
2980{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002981 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002982
2983 try
2984 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002985 gl::Context *context = gl::getContext();
2986
2987 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002988 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002989 switch (pname)
2990 {
2991 case GL_UNPACK_ALIGNMENT:
2992 if (param != 1 && param != 2 && param != 4 && param != 8)
2993 {
2994 return error(GL_INVALID_VALUE);
2995 }
2996
2997 context->unpackAlignment = param;
2998 break;
2999
3000 case GL_PACK_ALIGNMENT:
3001 if (param != 1 && param != 2 && param != 4 && param != 8)
3002 {
3003 return error(GL_INVALID_VALUE);
3004 }
3005
3006 context->packAlignment = param;
3007 break;
3008
3009 default:
3010 return error(GL_INVALID_ENUM);
3011 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003012 }
3013 }
3014 catch(std::bad_alloc&)
3015 {
3016 return error(GL_OUT_OF_MEMORY);
3017 }
3018}
3019
3020void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3021{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003022 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003023
3024 try
3025 {
3026 if (factor != 0.0f || units != 0.0f)
3027 {
3028 UNIMPLEMENTED(); // FIXME
3029 }
3030 }
3031 catch(std::bad_alloc&)
3032 {
3033 return error(GL_OUT_OF_MEMORY);
3034 }
3035}
3036
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003037void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003038{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003039 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003040 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003041 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003042
3043 try
3044 {
3045 if (width < 0 || height < 0)
3046 {
3047 return error(GL_INVALID_VALUE);
3048 }
3049
3050 switch (format)
3051 {
3052 case GL_RGBA:
3053 switch (type)
3054 {
3055 case GL_UNSIGNED_BYTE:
3056 break;
3057 default:
3058 return error(GL_INVALID_OPERATION);
3059 }
3060 break;
3061 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3062 switch (type)
3063 {
3064 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3065 break;
3066 default:
3067 return error(GL_INVALID_OPERATION);
3068 }
3069 break;
3070 default:
3071 return error(GL_INVALID_OPERATION);
3072 }
3073
3074 gl::Context *context = gl::getContext();
3075
3076 if (context)
3077 {
3078 context->readPixels(x, y, width, height, format, type, pixels);
3079 }
3080 }
3081 catch(std::bad_alloc&)
3082 {
3083 return error(GL_OUT_OF_MEMORY);
3084 }
3085}
3086
3087void __stdcall glReleaseShaderCompiler(void)
3088{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003089 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003090
3091 try
3092 {
3093 gl::Shader::releaseCompiler();
3094 }
3095 catch(std::bad_alloc&)
3096 {
3097 return error(GL_OUT_OF_MEMORY);
3098 }
3099}
3100
3101void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3102{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003103 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3104 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003105
3106 try
3107 {
3108 switch (target)
3109 {
3110 case GL_RENDERBUFFER:
3111 break;
3112 default:
3113 return error(GL_INVALID_ENUM);
3114 }
3115
3116 switch (internalformat)
3117 {
3118 case GL_DEPTH_COMPONENT16:
3119 case GL_RGBA4:
3120 case GL_RGB5_A1:
3121 case GL_RGB565:
3122 case GL_STENCIL_INDEX8:
3123 break;
3124 default:
3125 return error(GL_INVALID_ENUM);
3126 }
3127
3128 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3129 {
3130 return error(GL_INVALID_VALUE);
3131 }
3132
3133 gl::Context *context = gl::getContext();
3134
3135 if (context)
3136 {
3137 if (context->framebuffer == 0 || context->renderbuffer == 0)
3138 {
3139 return error(GL_INVALID_OPERATION);
3140 }
3141
3142 switch (internalformat)
3143 {
3144 case GL_DEPTH_COMPONENT16:
3145 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3146 break;
3147 case GL_RGBA4:
3148 case GL_RGB5_A1:
3149 case GL_RGB565:
3150 UNIMPLEMENTED(); // FIXME
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003151 // context->setRenderbuffer(new Colorbuffer(renderTarget));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003152 break;
3153 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003154 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003155 break;
3156 default:
3157 return error(GL_INVALID_ENUM);
3158 }
3159 }
3160 }
3161 catch(std::bad_alloc&)
3162 {
3163 return error(GL_OUT_OF_MEMORY);
3164 }
3165}
3166
3167void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3168{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003169 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003170
3171 try
3172 {
3173 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003174
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003175 if (context)
3176 {
3177 context->sampleCoverageValue = gl::clamp01(value);
3178 context->sampleCoverageInvert = invert;
3179 }
3180 }
3181 catch(std::bad_alloc&)
3182 {
3183 return error(GL_OUT_OF_MEMORY);
3184 }
3185}
3186
3187void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3188{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003189 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 +00003190
3191 try
3192 {
3193 if (width < 0 || height < 0)
3194 {
3195 return error(GL_INVALID_VALUE);
3196 }
3197
3198 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003199
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003200 if (context)
3201 {
3202 context->scissorX = x;
3203 context->scissorY = y;
3204 context->scissorWidth = width;
3205 context->scissorHeight = height;
3206 }
3207 }
3208 catch(std::bad_alloc&)
3209 {
3210 return error(GL_OUT_OF_MEMORY);
3211 }
3212}
3213
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003214void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003215{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003216 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003217 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003218 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003219
3220 try
3221 {
3222 if (n < 0 || length < 0)
3223 {
3224 return error(GL_INVALID_VALUE);
3225 }
3226
3227 UNIMPLEMENTED(); // FIXME
3228 }
3229 catch(std::bad_alloc&)
3230 {
3231 return error(GL_OUT_OF_MEMORY);
3232 }
3233}
3234
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003235void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003236{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003237 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 +00003238 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003239
3240 try
3241 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003242 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003243 {
3244 return error(GL_INVALID_VALUE);
3245 }
3246
3247 gl::Context *context = gl::getContext();
3248
3249 if (context)
3250 {
3251 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003252
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003253 if (!shaderObject)
3254 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003255 if (context->getProgram(shader))
3256 {
3257 return error(GL_INVALID_OPERATION);
3258 }
3259 else
3260 {
3261 return error(GL_INVALID_VALUE);
3262 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003263 }
3264
3265 shaderObject->setSource(count, string, length);
3266 }
3267 }
3268 catch(std::bad_alloc&)
3269 {
3270 return error(GL_OUT_OF_MEMORY);
3271 }
3272}
3273
3274void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3275{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003276 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003277}
3278
3279void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3280{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003281 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 +00003282
3283 try
3284 {
3285 switch (face)
3286 {
3287 case GL_FRONT:
3288 case GL_BACK:
3289 case GL_FRONT_AND_BACK:
3290 break;
3291 default:
3292 return error(GL_INVALID_ENUM);
3293 }
3294
3295 switch (func)
3296 {
3297 case GL_NEVER:
3298 case GL_ALWAYS:
3299 case GL_LESS:
3300 case GL_LEQUAL:
3301 case GL_EQUAL:
3302 case GL_GEQUAL:
3303 case GL_GREATER:
3304 case GL_NOTEQUAL:
3305 break;
3306 default:
3307 return error(GL_INVALID_ENUM);
3308 }
3309
3310 gl::Context *context = gl::getContext();
3311
3312 if (context)
3313 {
3314 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3315 {
3316 context->stencilFunc = func;
3317 context->stencilRef = ref;
3318 context->stencilMask = mask;
3319 }
3320
3321 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3322 {
3323 context->stencilBackFunc = func;
3324 context->stencilBackRef = ref;
3325 context->stencilBackMask = mask;
3326 }
3327 }
3328 }
3329 catch(std::bad_alloc&)
3330 {
3331 return error(GL_OUT_OF_MEMORY);
3332 }
3333}
3334
3335void __stdcall glStencilMask(GLuint mask)
3336{
3337 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3338}
3339
3340void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3341{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003342 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003343
3344 try
3345 {
3346 switch (face)
3347 {
3348 case GL_FRONT:
3349 case GL_BACK:
3350 case GL_FRONT_AND_BACK:
3351 break;
3352 default:
3353 return error(GL_INVALID_ENUM);
3354 }
3355
3356 gl::Context *context = gl::getContext();
3357
3358 if (context)
3359 {
3360 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3361 {
3362 context->stencilWritemask = mask;
3363 }
3364
3365 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3366 {
3367 context->stencilBackWritemask = mask;
3368 }
3369 }
3370 }
3371 catch(std::bad_alloc&)
3372 {
3373 return error(GL_OUT_OF_MEMORY);
3374 }
3375}
3376
3377void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3378{
3379 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3380}
3381
3382void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3383{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003384 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3385 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003386
3387 try
3388 {
3389 switch (face)
3390 {
3391 case GL_FRONT:
3392 case GL_BACK:
3393 case GL_FRONT_AND_BACK:
3394 break;
3395 default:
3396 return error(GL_INVALID_ENUM);
3397 }
3398
3399 switch (fail)
3400 {
3401 case GL_ZERO:
3402 case GL_KEEP:
3403 case GL_REPLACE:
3404 case GL_INCR:
3405 case GL_DECR:
3406 case GL_INVERT:
3407 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003408 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003409 break;
3410 default:
3411 return error(GL_INVALID_ENUM);
3412 }
3413
3414 switch (zfail)
3415 {
3416 case GL_ZERO:
3417 case GL_KEEP:
3418 case GL_REPLACE:
3419 case GL_INCR:
3420 case GL_DECR:
3421 case GL_INVERT:
3422 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003423 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003424 break;
3425 default:
3426 return error(GL_INVALID_ENUM);
3427 }
3428
3429 switch (zpass)
3430 {
3431 case GL_ZERO:
3432 case GL_KEEP:
3433 case GL_REPLACE:
3434 case GL_INCR:
3435 case GL_DECR:
3436 case GL_INVERT:
3437 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003438 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003439 break;
3440 default:
3441 return error(GL_INVALID_ENUM);
3442 }
3443
3444 gl::Context *context = gl::getContext();
3445
3446 if (context)
3447 {
3448 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3449 {
3450 context->stencilFail = fail;
3451 context->stencilPassDepthFail = zfail;
3452 context->stencilPassDepthPass = zpass;
3453 }
3454
3455 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3456 {
3457 context->stencilBackFail = fail;
3458 context->stencilBackPassDepthFail = zfail;
3459 context->stencilBackPassDepthPass = zpass;
3460 }
3461 }
3462 }
3463 catch(std::bad_alloc&)
3464 {
3465 return error(GL_OUT_OF_MEMORY);
3466 }
3467}
3468
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003469void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3470 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003471{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003472 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 +00003473 "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 +00003474 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003475
3476 try
3477 {
3478 if (level < 0 || width < 0 || height < 0)
3479 {
3480 return error(GL_INVALID_VALUE);
3481 }
3482
3483 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3484 {
3485 return error(GL_INVALID_VALUE);
3486 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003487
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003488 switch (target)
3489 {
3490 case GL_TEXTURE_2D:
3491 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3492 {
3493 return error(GL_INVALID_VALUE);
3494 }
3495 break;
3496 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3497 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3498 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3499 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3500 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3501 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3502 if (!gl::isPow2(width) || !gl::isPow2(height))
3503 {
3504 return error(GL_INVALID_VALUE);
3505 }
3506
3507 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3508 {
3509 return error(GL_INVALID_VALUE);
3510 }
3511 break;
3512 default:
3513 return error(GL_INVALID_ENUM);
3514 }
3515
3516 if (internalformat != format)
3517 {
3518 return error(GL_INVALID_OPERATION);
3519 }
3520
3521 switch (internalformat)
3522 {
3523 case GL_ALPHA:
3524 case GL_LUMINANCE:
3525 case GL_LUMINANCE_ALPHA:
3526 switch (type)
3527 {
3528 case GL_UNSIGNED_BYTE:
3529 break;
3530 default:
3531 return error(GL_INVALID_ENUM);
3532 }
3533 break;
3534 case GL_RGB:
3535 switch (type)
3536 {
3537 case GL_UNSIGNED_BYTE:
3538 case GL_UNSIGNED_SHORT_5_6_5:
3539 break;
3540 default:
3541 return error(GL_INVALID_ENUM);
3542 }
3543 break;
3544 case GL_RGBA:
3545 switch (type)
3546 {
3547 case GL_UNSIGNED_BYTE:
3548 case GL_UNSIGNED_SHORT_4_4_4_4:
3549 case GL_UNSIGNED_SHORT_5_5_5_1:
3550 break;
3551 default:
3552 return error(GL_INVALID_ENUM);
3553 }
3554 break;
3555 default:
3556 return error(GL_INVALID_VALUE);
3557 }
3558
3559 if (border != 0)
3560 {
3561 return error(GL_INVALID_VALUE);
3562 }
3563
3564 gl::Context *context = gl::getContext();
3565
3566 if (context)
3567 {
3568 if (target == GL_TEXTURE_2D)
3569 {
3570 gl::Texture2D *texture = context->getTexture2D();
3571
3572 if (!texture)
3573 {
3574 return error(GL_INVALID_OPERATION);
3575 }
3576
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003577 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003578 }
3579 else
3580 {
3581 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3582
3583 if (!texture)
3584 {
3585 return error(GL_INVALID_OPERATION);
3586 }
3587
3588 switch (target)
3589 {
3590 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003591 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003592 break;
3593 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003594 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003595 break;
3596 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003597 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003598 break;
3599 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003600 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003601 break;
3602 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003603 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003604 break;
3605 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003606 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003607 break;
3608 default: UNREACHABLE();
3609 }
3610 }
3611 }
3612 }
3613 catch(std::bad_alloc&)
3614 {
3615 return error(GL_OUT_OF_MEMORY);
3616 }
3617}
3618
3619void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3620{
3621 glTexParameteri(target, pname, (GLint)param);
3622}
3623
3624void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3625{
3626 glTexParameteri(target, pname, (GLint)*params);
3627}
3628
3629void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3630{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003631 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003632
3633 try
3634 {
3635 gl::Context *context = gl::getContext();
3636
3637 if (context)
3638 {
3639 gl::Texture *texture;
3640
3641 switch (target)
3642 {
3643 case GL_TEXTURE_2D:
3644 texture = context->getTexture2D();
3645 break;
3646 case GL_TEXTURE_CUBE_MAP:
3647 texture = context->getTextureCubeMap();
3648 break;
3649 default:
3650 return error(GL_INVALID_ENUM);
3651 }
3652
3653 switch (pname)
3654 {
3655 case GL_TEXTURE_WRAP_S:
3656 if (!texture->setWrapS((GLenum)param))
3657 {
3658 return error(GL_INVALID_ENUM);
3659 }
3660 break;
3661 case GL_TEXTURE_WRAP_T:
3662 if (!texture->setWrapT((GLenum)param))
3663 {
3664 return error(GL_INVALID_ENUM);
3665 }
3666 break;
3667 case GL_TEXTURE_MIN_FILTER:
3668 if (!texture->setMinFilter((GLenum)param))
3669 {
3670 return error(GL_INVALID_ENUM);
3671 }
3672 break;
3673 case GL_TEXTURE_MAG_FILTER:
3674 if (!texture->setMagFilter((GLenum)param))
3675 {
3676 return error(GL_INVALID_ENUM);
3677 }
3678 break;
3679 default:
3680 return error(GL_INVALID_ENUM);
3681 }
3682 }
3683 }
3684 catch(std::bad_alloc&)
3685 {
3686 return error(GL_OUT_OF_MEMORY);
3687 }
3688}
3689
3690void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3691{
3692 glTexParameteri(target, pname, *params);
3693}
3694
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003695void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3696 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003697{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003698 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3699 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003700 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003701 target, level, xoffset, yoffset, width, height, format, type, pixels);
3702
3703 try
3704 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003705 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
3706 {
3707 return error(GL_INVALID_ENUM);
3708 }
3709
3710 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003711 {
3712 return error(GL_INVALID_VALUE);
3713 }
3714
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003715 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
3716 {
3717 return error(GL_INVALID_VALUE);
3718 }
3719
3720 if (!es2dx::CheckTextureFormatType(format, type))
3721 {
3722 return error(GL_INVALID_ENUM);
3723 }
3724
3725 if (width == 0 || height == 0 || pixels == NULL)
3726 {
3727 return;
3728 }
3729
3730 gl::Context *context = gl::getContext();
3731
3732 if (context)
3733 {
3734 if (target == GL_TEXTURE_2D)
3735 {
3736 gl::Texture2D *texture = context->getTexture2D();
3737
3738 if (!texture)
3739 {
3740 return error(GL_INVALID_OPERATION);
3741 }
3742
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003743 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003744 }
3745 else if (es2dx::IsCubemapTextureTarget(target))
3746 {
3747 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3748
3749 if (!texture)
3750 {
3751 return error(GL_INVALID_OPERATION);
3752 }
3753
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003754 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003755 }
3756 else
3757 {
3758 UNREACHABLE();
3759 }
3760 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003761 }
3762 catch(std::bad_alloc&)
3763 {
3764 return error(GL_OUT_OF_MEMORY);
3765 }
3766}
3767
3768void __stdcall glUniform1f(GLint location, GLfloat x)
3769{
3770 glUniform1fv(location, 1, &x);
3771}
3772
3773void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
3774{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003775 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003776
3777 try
3778 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003779 if (count < 0)
3780 {
3781 return error(GL_INVALID_VALUE);
3782 }
3783
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003784 if (location == -1)
3785 {
3786 return;
3787 }
3788
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003789 gl::Context *context = gl::getContext();
3790
3791 if (context)
3792 {
3793 gl::Program *program = context->getCurrentProgram();
3794
3795 if (!program)
3796 {
3797 return error(GL_INVALID_OPERATION);
3798 }
3799
3800 if (!program->setUniform1fv(location, count, v))
3801 {
3802 return error(GL_INVALID_OPERATION);
3803 }
3804 }
3805 }
3806 catch(std::bad_alloc&)
3807 {
3808 return error(GL_OUT_OF_MEMORY);
3809 }
3810}
3811
3812void __stdcall glUniform1i(GLint location, GLint x)
3813{
3814 glUniform1iv(location, 1, &x);
3815}
3816
3817void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
3818{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003819 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003820
3821 try
3822 {
3823 if (count < 0)
3824 {
3825 return error(GL_INVALID_VALUE);
3826 }
3827
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003828 if (location == -1)
3829 {
3830 return;
3831 }
3832
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003833 gl::Context *context = gl::getContext();
3834
3835 if (context)
3836 {
3837 gl::Program *program = context->getCurrentProgram();
3838
3839 if (!program)
3840 {
3841 return error(GL_INVALID_OPERATION);
3842 }
3843
3844 if (!program->setUniform1iv(location, count, v))
3845 {
3846 return error(GL_INVALID_OPERATION);
3847 }
3848 }
3849 }
3850 catch(std::bad_alloc&)
3851 {
3852 return error(GL_OUT_OF_MEMORY);
3853 }
3854}
3855
3856void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
3857{
3858 GLfloat xy[2] = {x, y};
3859
3860 glUniform2fv(location, 1, (GLfloat*)&xy);
3861}
3862
3863void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
3864{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003865 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003866
3867 try
3868 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003869 if (count < 0)
3870 {
3871 return error(GL_INVALID_VALUE);
3872 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003873
3874 if (location == -1)
3875 {
3876 return;
3877 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003878
3879 gl::Context *context = gl::getContext();
3880
3881 if (context)
3882 {
3883 gl::Program *program = context->getCurrentProgram();
3884
3885 if (!program)
3886 {
3887 return error(GL_INVALID_OPERATION);
3888 }
3889
3890 if (!program->setUniform2fv(location, count, v))
3891 {
3892 return error(GL_INVALID_OPERATION);
3893 }
3894 }
3895 }
3896 catch(std::bad_alloc&)
3897 {
3898 return error(GL_OUT_OF_MEMORY);
3899 }
3900}
3901
3902void __stdcall glUniform2i(GLint location, GLint x, GLint y)
3903{
3904 GLint xy[4] = {x, y};
3905
3906 glUniform2iv(location, 1, (GLint*)&xy);
3907}
3908
3909void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
3910{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003911 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003912
3913 try
3914 {
3915 if (count < 0)
3916 {
3917 return error(GL_INVALID_VALUE);
3918 }
3919
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003920 if (location == -1)
3921 {
3922 return;
3923 }
3924
3925 gl::Context *context = gl::getContext();
3926
3927 if (context)
3928 {
3929 gl::Program *program = context->getCurrentProgram();
3930
3931 if (!program)
3932 {
3933 return error(GL_INVALID_OPERATION);
3934 }
3935
3936 if (!program->setUniform2iv(location, count, v))
3937 {
3938 return error(GL_INVALID_OPERATION);
3939 }
3940 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003941 }
3942 catch(std::bad_alloc&)
3943 {
3944 return error(GL_OUT_OF_MEMORY);
3945 }
3946}
3947
3948void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
3949{
3950 GLfloat xyz[3] = {x, y, z};
3951
3952 glUniform3fv(location, 1, (GLfloat*)&xyz);
3953}
3954
3955void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
3956{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003957 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003958
3959 try
3960 {
3961 if (count < 0)
3962 {
3963 return error(GL_INVALID_VALUE);
3964 }
3965
3966 if (location == -1)
3967 {
3968 return;
3969 }
3970
3971 gl::Context *context = gl::getContext();
3972
3973 if (context)
3974 {
3975 gl::Program *program = context->getCurrentProgram();
3976
3977 if (!program)
3978 {
3979 return error(GL_INVALID_OPERATION);
3980 }
3981
3982 if (!program->setUniform3fv(location, count, v))
3983 {
3984 return error(GL_INVALID_OPERATION);
3985 }
3986 }
3987 }
3988 catch(std::bad_alloc&)
3989 {
3990 return error(GL_OUT_OF_MEMORY);
3991 }
3992}
3993
3994void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
3995{
3996 GLint xyz[3] = {x, y, z};
3997
3998 glUniform3iv(location, 1, (GLint*)&xyz);
3999}
4000
4001void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4002{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004003 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004004
4005 try
4006 {
4007 if (count < 0)
4008 {
4009 return error(GL_INVALID_VALUE);
4010 }
4011
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004012 if (location == -1)
4013 {
4014 return;
4015 }
4016
4017 gl::Context *context = gl::getContext();
4018
4019 if (context)
4020 {
4021 gl::Program *program = context->getCurrentProgram();
4022
4023 if (!program)
4024 {
4025 return error(GL_INVALID_OPERATION);
4026 }
4027
4028 if (!program->setUniform3iv(location, count, v))
4029 {
4030 return error(GL_INVALID_OPERATION);
4031 }
4032 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004033 }
4034 catch(std::bad_alloc&)
4035 {
4036 return error(GL_OUT_OF_MEMORY);
4037 }
4038}
4039
4040void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4041{
4042 GLfloat xyzw[4] = {x, y, z, w};
4043
4044 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4045}
4046
4047void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4048{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004049 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004050
4051 try
4052 {
4053 if (count < 0)
4054 {
4055 return error(GL_INVALID_VALUE);
4056 }
4057
4058 if (location == -1)
4059 {
4060 return;
4061 }
4062
4063 gl::Context *context = gl::getContext();
4064
4065 if (context)
4066 {
4067 gl::Program *program = context->getCurrentProgram();
4068
4069 if (!program)
4070 {
4071 return error(GL_INVALID_OPERATION);
4072 }
4073
4074 if (!program->setUniform4fv(location, count, v))
4075 {
4076 return error(GL_INVALID_OPERATION);
4077 }
4078 }
4079 }
4080 catch(std::bad_alloc&)
4081 {
4082 return error(GL_OUT_OF_MEMORY);
4083 }
4084}
4085
4086void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4087{
4088 GLint xyzw[4] = {x, y, z, w};
4089
4090 glUniform4iv(location, 1, (GLint*)&xyzw);
4091}
4092
4093void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4094{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004095 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004096
4097 try
4098 {
4099 if (count < 0)
4100 {
4101 return error(GL_INVALID_VALUE);
4102 }
4103
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004104 if (location == -1)
4105 {
4106 return;
4107 }
4108
4109 gl::Context *context = gl::getContext();
4110
4111 if (context)
4112 {
4113 gl::Program *program = context->getCurrentProgram();
4114
4115 if (!program)
4116 {
4117 return error(GL_INVALID_OPERATION);
4118 }
4119
4120 if (!program->setUniform4iv(location, count, v))
4121 {
4122 return error(GL_INVALID_OPERATION);
4123 }
4124 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004125 }
4126 catch(std::bad_alloc&)
4127 {
4128 return error(GL_OUT_OF_MEMORY);
4129 }
4130}
4131
4132void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4133{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004134 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4135 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004136
4137 try
4138 {
4139 if (count < 0 || transpose != GL_FALSE)
4140 {
4141 return error(GL_INVALID_VALUE);
4142 }
4143
4144 if (location == -1)
4145 {
4146 return;
4147 }
4148
4149 gl::Context *context = gl::getContext();
4150
4151 if (context)
4152 {
4153 gl::Program *program = context->getCurrentProgram();
4154
4155 if (!program)
4156 {
4157 return error(GL_INVALID_OPERATION);
4158 }
4159
4160 if (!program->setUniformMatrix2fv(location, count, value))
4161 {
4162 return error(GL_INVALID_OPERATION);
4163 }
4164 }
4165 }
4166 catch(std::bad_alloc&)
4167 {
4168 return error(GL_OUT_OF_MEMORY);
4169 }
4170}
4171
4172void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4173{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004174 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4175 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004176
4177 try
4178 {
4179 if (count < 0 || transpose != GL_FALSE)
4180 {
4181 return error(GL_INVALID_VALUE);
4182 }
4183
4184 if (location == -1)
4185 {
4186 return;
4187 }
4188
4189 gl::Context *context = gl::getContext();
4190
4191 if (context)
4192 {
4193 gl::Program *program = context->getCurrentProgram();
4194
4195 if (!program)
4196 {
4197 return error(GL_INVALID_OPERATION);
4198 }
4199
4200 if (!program->setUniformMatrix3fv(location, count, value))
4201 {
4202 return error(GL_INVALID_OPERATION);
4203 }
4204 }
4205 }
4206 catch(std::bad_alloc&)
4207 {
4208 return error(GL_OUT_OF_MEMORY);
4209 }
4210}
4211
4212void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4213{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004214 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4215 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004216
4217 try
4218 {
4219 if (count < 0 || transpose != GL_FALSE)
4220 {
4221 return error(GL_INVALID_VALUE);
4222 }
4223
4224 if (location == -1)
4225 {
4226 return;
4227 }
4228
4229 gl::Context *context = gl::getContext();
4230
4231 if (context)
4232 {
4233 gl::Program *program = context->getCurrentProgram();
4234
4235 if (!program)
4236 {
4237 return error(GL_INVALID_OPERATION);
4238 }
4239
4240 if (!program->setUniformMatrix4fv(location, count, value))
4241 {
4242 return error(GL_INVALID_OPERATION);
4243 }
4244 }
4245 }
4246 catch(std::bad_alloc&)
4247 {
4248 return error(GL_OUT_OF_MEMORY);
4249 }
4250}
4251
4252void __stdcall glUseProgram(GLuint program)
4253{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004254 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004255
4256 try
4257 {
4258 gl::Context *context = gl::getContext();
4259
4260 if (context)
4261 {
4262 gl::Program *programObject = context->getProgram(program);
4263
4264 if (programObject && !programObject->isLinked())
4265 {
4266 return error(GL_INVALID_OPERATION);
4267 }
4268
4269 context->useProgram(program);
4270 }
4271 }
4272 catch(std::bad_alloc&)
4273 {
4274 return error(GL_OUT_OF_MEMORY);
4275 }
4276}
4277
4278void __stdcall glValidateProgram(GLuint program)
4279{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004280 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004281
4282 try
4283 {
4284 UNIMPLEMENTED(); // FIXME
4285 }
4286 catch(std::bad_alloc&)
4287 {
4288 return error(GL_OUT_OF_MEMORY);
4289 }
4290}
4291
4292void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4293{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004294 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004295
4296 try
4297 {
4298 if (index >= gl::MAX_VERTEX_ATTRIBS)
4299 {
4300 return error(GL_INVALID_VALUE);
4301 }
4302
4303 UNIMPLEMENTED(); // FIXME
4304 }
4305 catch(std::bad_alloc&)
4306 {
4307 return error(GL_OUT_OF_MEMORY);
4308 }
4309}
4310
4311void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4312{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004313 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004314
4315 try
4316 {
4317 if (index >= gl::MAX_VERTEX_ATTRIBS)
4318 {
4319 return error(GL_INVALID_VALUE);
4320 }
4321
4322 UNIMPLEMENTED(); // FIXME
4323 }
4324 catch(std::bad_alloc&)
4325 {
4326 return error(GL_OUT_OF_MEMORY);
4327 }
4328}
4329
4330void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4331{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004332 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004333
4334 try
4335 {
4336 if (index >= gl::MAX_VERTEX_ATTRIBS)
4337 {
4338 return error(GL_INVALID_VALUE);
4339 }
4340
4341 UNIMPLEMENTED(); // FIXME
4342 }
4343 catch(std::bad_alloc&)
4344 {
4345 return error(GL_OUT_OF_MEMORY);
4346 }
4347}
4348
4349void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4350{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004351 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004352
4353 try
4354 {
4355 if (index >= gl::MAX_VERTEX_ATTRIBS)
4356 {
4357 return error(GL_INVALID_VALUE);
4358 }
4359
4360 UNIMPLEMENTED(); // FIXME
4361 }
4362 catch(std::bad_alloc&)
4363 {
4364 return error(GL_OUT_OF_MEMORY);
4365 }
4366}
4367
4368void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4369{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004370 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 +00004371
4372 try
4373 {
4374 if (index >= gl::MAX_VERTEX_ATTRIBS)
4375 {
4376 return error(GL_INVALID_VALUE);
4377 }
4378
4379 UNIMPLEMENTED(); // FIXME
4380 }
4381 catch(std::bad_alloc&)
4382 {
4383 return error(GL_OUT_OF_MEMORY);
4384 }
4385}
4386
4387void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4388{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004389 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004390
4391 try
4392 {
4393 if (index >= gl::MAX_VERTEX_ATTRIBS)
4394 {
4395 return error(GL_INVALID_VALUE);
4396 }
4397
4398 UNIMPLEMENTED(); // FIXME
4399 }
4400 catch(std::bad_alloc&)
4401 {
4402 return error(GL_OUT_OF_MEMORY);
4403 }
4404}
4405
4406void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4407{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004408 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 +00004409
4410 try
4411 {
4412 if (index >= gl::MAX_VERTEX_ATTRIBS)
4413 {
4414 return error(GL_INVALID_VALUE);
4415 }
4416
4417 UNIMPLEMENTED(); // FIXME
4418 }
4419 catch(std::bad_alloc&)
4420 {
4421 return error(GL_OUT_OF_MEMORY);
4422 }
4423}
4424
4425void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4426{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004427 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004428
4429 try
4430 {
4431 if (index >= gl::MAX_VERTEX_ATTRIBS)
4432 {
4433 return error(GL_INVALID_VALUE);
4434 }
4435
4436 UNIMPLEMENTED(); // FIXME
4437 }
4438 catch(std::bad_alloc&)
4439 {
4440 return error(GL_OUT_OF_MEMORY);
4441 }
4442}
4443
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004444void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004445{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004446 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004447 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004448 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004449
4450 try
4451 {
4452 if (index >= gl::MAX_VERTEX_ATTRIBS)
4453 {
4454 return error(GL_INVALID_VALUE);
4455 }
4456
4457 if (size < 1 || size > 4)
4458 {
4459 return error(GL_INVALID_VALUE);
4460 }
4461
4462 switch (type)
4463 {
4464 case GL_BYTE:
4465 case GL_UNSIGNED_BYTE:
4466 case GL_SHORT:
4467 case GL_UNSIGNED_SHORT:
4468 case GL_FIXED:
4469 case GL_FLOAT:
4470 break;
4471 default:
4472 return error(GL_INVALID_ENUM);
4473 }
4474
4475 if (stride < 0)
4476 {
4477 return error(GL_INVALID_VALUE);
4478 }
4479
4480 gl::Context *context = gl::getContext();
4481
4482 if (context)
4483 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004484 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4485 context->vertexAttribute[index].mSize = size;
4486 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004487 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004488 context->vertexAttribute[index].mStride = stride;
4489 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004490 }
4491 }
4492 catch(std::bad_alloc&)
4493 {
4494 return error(GL_OUT_OF_MEMORY);
4495 }
4496}
4497
4498void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4499{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004500 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 +00004501
4502 try
4503 {
4504 if (width < 0 || height < 0)
4505 {
4506 return error(GL_INVALID_VALUE);
4507 }
4508
4509 gl::Context *context = gl::getContext();
4510
4511 if (context)
4512 {
4513 context->viewportX = x;
4514 context->viewportY = y;
4515 context->viewportWidth = width;
4516 context->viewportHeight = height;
4517 }
4518 }
4519 catch(std::bad_alloc&)
4520 {
4521 return error(GL_OUT_OF_MEMORY);
4522 }
4523}
4524
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004525void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4526 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004527{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004528 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4529 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004530 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004531 target, level, internalformat, width, height, depth, border, format, type, pixels);
4532
4533 try
4534 {
4535 UNIMPLEMENTED(); // FIXME
4536 }
4537 catch(std::bad_alloc&)
4538 {
4539 return error(GL_OUT_OF_MEMORY);
4540 }
4541}
4542}