blob: 799cedf0d67cbf507a7513ae8569f147c7a195fe [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 {
1905 return error(GL_INVALID_VALUE);
1906 }
1907
1908 return programObject->getAttachedShaders(maxcount, count, shaders);
1909 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001910 }
1911 catch(std::bad_alloc&)
1912 {
1913 return error(GL_OUT_OF_MEMORY);
1914 }
1915}
1916
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001917int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001918{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001919 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001920
1921 try
1922 {
1923 gl::Context *context = gl::getContext();
1924
1925 if (context)
1926 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001927
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001928 gl::Program *programObject = context->getProgram(program);
1929
1930 if (!programObject)
1931 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001932 if (context->getShader(program))
1933 {
1934 return error(GL_INVALID_OPERATION, -1);
1935 }
1936 else
1937 {
1938 return error(GL_INVALID_VALUE, -1);
1939 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001940 }
1941
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00001942 if (!programObject->isLinked())
1943 {
1944 return error(GL_INVALID_OPERATION, -1);
1945 }
1946
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001947 return programObject->getAttributeLocation(name);
1948 }
1949 }
1950 catch(std::bad_alloc&)
1951 {
1952 return error(GL_OUT_OF_MEMORY, -1);
1953 }
1954
1955 return -1;
1956}
1957
1958void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1959{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001960 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001961
1962 try
1963 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001964 gl::Context *context = gl::getContext();
1965
1966 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001967 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001968 if (!(context->getBooleanv(pname, params)))
1969 {
1970 GLenum nativeType;
1971 unsigned int numParams = 0;
1972 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1973 return error(GL_INVALID_ENUM);
1974
1975 if (numParams == 0)
1976 return; // it is known that the pname is valid, but there are no parameters to return
1977
1978 if (nativeType == GL_FLOAT)
1979 {
1980 GLfloat *floatParams = NULL;
1981 floatParams = new GLfloat[numParams];
1982
1983 context->getFloatv(pname, floatParams);
1984
1985 for (unsigned int i = 0; i < numParams; ++i)
1986 {
1987 if (floatParams[i] == 0.0f)
1988 params[i] = GL_FALSE;
1989 else
1990 params[i] = GL_TRUE;
1991 }
1992
1993 delete [] floatParams;
1994 }
1995 else if (nativeType == GL_INT)
1996 {
1997 GLint *intParams = NULL;
1998 intParams = new GLint[numParams];
1999
2000 context->getIntegerv(pname, intParams);
2001
2002 for (unsigned int i = 0; i < numParams; ++i)
2003 {
2004 if (intParams[i] == 0)
2005 params[i] = GL_FALSE;
2006 else
2007 params[i] = GL_TRUE;
2008 }
2009
2010 delete [] intParams;
2011 }
2012 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002013 }
2014 }
2015 catch(std::bad_alloc&)
2016 {
2017 return error(GL_OUT_OF_MEMORY);
2018 }
2019}
2020
2021void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2022{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002023 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 +00002024
2025 try
2026 {
2027 UNIMPLEMENTED(); // FIXME
2028 }
2029 catch(std::bad_alloc&)
2030 {
2031 return error(GL_OUT_OF_MEMORY);
2032 }
2033}
2034
2035GLenum __stdcall glGetError(void)
2036{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002037 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002038
2039 gl::Context *context = gl::getContext();
2040
2041 if (context)
2042 {
2043 return context->getError();
2044 }
2045
2046 return GL_NO_ERROR;
2047}
2048
2049void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2050{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002051 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002052
2053 try
2054 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002055 gl::Context *context = gl::getContext();
2056
2057 if (context)
2058 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002059 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002060 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002061 GLenum nativeType;
2062 unsigned int numParams = 0;
2063 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2064 return error(GL_INVALID_ENUM);
2065
2066 if (numParams == 0)
2067 return; // it is known that the pname is valid, but that there are no parameters to return.
2068
2069 if (nativeType == GL_BOOL)
2070 {
2071 GLboolean *boolParams = NULL;
2072 boolParams = new GLboolean[numParams];
2073
2074 context->getBooleanv(pname, boolParams);
2075
2076 for (unsigned int i = 0; i < numParams; ++i)
2077 {
2078 if (boolParams[i] == GL_FALSE)
2079 params[i] = 0.0f;
2080 else
2081 params[i] = 1.0f;
2082 }
2083
2084 delete [] boolParams;
2085 }
2086 else if (nativeType == GL_INT)
2087 {
2088 GLint *intParams = NULL;
2089 intParams = new GLint[numParams];
2090
2091 context->getIntegerv(pname, intParams);
2092
2093 for (unsigned int i = 0; i < numParams; ++i)
2094 {
2095 params[i] = (GLfloat)intParams[i];
2096 }
2097
2098 delete [] intParams;
2099 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002100 }
2101 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002102 }
2103 catch(std::bad_alloc&)
2104 {
2105 return error(GL_OUT_OF_MEMORY);
2106 }
2107}
2108
2109void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2110{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002111 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2112 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002113
2114 try
2115 {
2116 gl::Context *context = gl::getContext();
2117
2118 if (context)
2119 {
2120 if (context->framebuffer == 0)
2121 {
2122 return error(GL_INVALID_OPERATION);
2123 }
2124
2125 UNIMPLEMENTED(); // FIXME
2126 }
2127 }
2128 catch(std::bad_alloc&)
2129 {
2130 return error(GL_OUT_OF_MEMORY);
2131 }
2132}
2133
2134void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2135{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002136 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002137
2138 try
2139 {
2140 gl::Context *context = gl::getContext();
2141
2142 if (context)
2143 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002144 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002145 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002146 GLenum nativeType;
2147 unsigned int numParams = 0;
2148 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2149 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002150
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002151 if (numParams == 0)
2152 return; // it is known that pname is valid, but there are no parameters to return
2153
2154 if (nativeType == GL_BOOL)
2155 {
2156 GLboolean *boolParams = NULL;
2157 boolParams = new GLboolean[numParams];
2158
2159 context->getBooleanv(pname, boolParams);
2160
2161 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002162 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002163 if (boolParams[i] == GL_FALSE)
2164 params[i] = 0;
2165 else
2166 params[i] = 1;
2167 }
2168
2169 delete [] boolParams;
2170 }
2171 else if (nativeType == GL_FLOAT)
2172 {
2173 GLfloat *floatParams = NULL;
2174 floatParams = new GLfloat[numParams];
2175
2176 context->getFloatv(pname, floatParams);
2177
2178 for (unsigned int i = 0; i < numParams; ++i)
2179 {
2180 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002181 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002182 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002183 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002184 else
2185 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 +00002186 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002187
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002188 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002189 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002190 }
2191 }
2192 }
2193 catch(std::bad_alloc&)
2194 {
2195 return error(GL_OUT_OF_MEMORY);
2196 }
2197}
2198
2199void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2200{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002201 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002202
2203 try
2204 {
2205 gl::Context *context = gl::getContext();
2206
2207 if (context)
2208 {
2209 gl::Program *programObject = context->getProgram(program);
2210
2211 if (!programObject)
2212 {
2213 return error(GL_INVALID_VALUE);
2214 }
2215
2216 switch (pname)
2217 {
2218 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002219 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002220 return;
2221 case GL_LINK_STATUS:
2222 *params = programObject->isLinked();
2223 return;
2224 case GL_VALIDATE_STATUS:
2225 UNIMPLEMENTED(); // FIXME
2226 *params = GL_TRUE;
2227 return;
2228 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002229 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002230 return;
2231 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002232 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002233 return;
2234 case GL_ACTIVE_ATTRIBUTES:
2235 UNIMPLEMENTED(); // FIXME
2236 *params = 0;
2237 return;
2238 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2239 UNIMPLEMENTED(); // FIXME
2240 *params = 0;
2241 return;
2242 case GL_ACTIVE_UNIFORMS:
2243 UNIMPLEMENTED(); // FIXME
2244 *params = 0;
2245 return;
2246 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2247 UNIMPLEMENTED(); // FIXME
2248 *params = 0;
2249 return;
2250 default:
2251 return error(GL_INVALID_ENUM);
2252 }
2253 }
2254 }
2255 catch(std::bad_alloc&)
2256 {
2257 return error(GL_OUT_OF_MEMORY);
2258 }
2259}
2260
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002261void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002262{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002263 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 +00002264 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002265
2266 try
2267 {
2268 if (bufsize < 0)
2269 {
2270 return error(GL_INVALID_VALUE);
2271 }
2272
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002273 gl::Context *context = gl::getContext();
2274
2275 if (context)
2276 {
2277 gl::Program *programObject = context->getProgram(program);
2278
2279 if (!programObject)
2280 {
2281 return error(GL_INVALID_VALUE);
2282 }
2283
2284 programObject->getInfoLog(bufsize, length, infolog);
2285 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002286 }
2287 catch(std::bad_alloc&)
2288 {
2289 return error(GL_OUT_OF_MEMORY);
2290 }
2291}
2292
2293void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2294{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002295 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 +00002296
2297 try
2298 {
2299 UNIMPLEMENTED(); // FIXME
2300 }
2301 catch(std::bad_alloc&)
2302 {
2303 return error(GL_OUT_OF_MEMORY);
2304 }
2305}
2306
2307void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2308{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002309 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002310
2311 try
2312 {
2313 gl::Context *context = gl::getContext();
2314
2315 if (context)
2316 {
2317 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002318
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002319 if (!shaderObject)
2320 {
2321 return error(GL_INVALID_VALUE);
2322 }
2323
2324 switch (pname)
2325 {
2326 case GL_SHADER_TYPE:
2327 *params = shaderObject->getType();
2328 return;
2329 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002330 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002331 return;
2332 case GL_COMPILE_STATUS:
2333 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2334 return;
2335 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002336 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002337 return;
2338 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002339 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002340 return;
2341 default:
2342 return error(GL_INVALID_ENUM);
2343 }
2344 }
2345 }
2346 catch(std::bad_alloc&)
2347 {
2348 return error(GL_OUT_OF_MEMORY);
2349 }
2350}
2351
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002352void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002353{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002354 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 +00002355 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002356
2357 try
2358 {
2359 if (bufsize < 0)
2360 {
2361 return error(GL_INVALID_VALUE);
2362 }
2363
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002364 gl::Context *context = gl::getContext();
2365
2366 if (context)
2367 {
2368 gl::Shader *shaderObject = context->getShader(shader);
2369
2370 if (!shaderObject)
2371 {
2372 return error(GL_INVALID_VALUE);
2373 }
2374
2375 shaderObject->getInfoLog(bufsize, length, infolog);
2376 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002377 }
2378 catch(std::bad_alloc&)
2379 {
2380 return error(GL_OUT_OF_MEMORY);
2381 }
2382}
2383
2384void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2385{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002386 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2387 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002388
2389 try
2390 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002391 switch (shadertype)
2392 {
2393 case GL_VERTEX_SHADER:
2394 case GL_FRAGMENT_SHADER:
2395 break;
2396 default:
2397 return error(GL_INVALID_ENUM);
2398 }
2399
2400 switch (precisiontype)
2401 {
2402 case GL_LOW_FLOAT:
2403 case GL_MEDIUM_FLOAT:
2404 case GL_HIGH_FLOAT:
2405 // Assume IEEE 754 precision
2406 range[0] = 127;
2407 range[1] = 127;
2408 precision[0] = 23;
2409 precision[1] = 23;
2410 break;
2411 case GL_LOW_INT:
2412 case GL_MEDIUM_INT:
2413 case GL_HIGH_INT:
2414 // Some (most) hardware only supports single-precision floating-point numbers,
2415 // which can accurately represent integers up to +/-16777216
2416 range[0] = 24;
2417 range[1] = 24;
2418 precision[0] = 0;
2419 precision[1] = 0;
2420 break;
2421 default:
2422 return error(GL_INVALID_ENUM);
2423 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002424 }
2425 catch(std::bad_alloc&)
2426 {
2427 return error(GL_OUT_OF_MEMORY);
2428 }
2429}
2430
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002431void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002432{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002433 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 +00002434 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002435
2436 try
2437 {
2438 if (bufsize < 0)
2439 {
2440 return error(GL_INVALID_VALUE);
2441 }
2442
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002443 gl::Context *context = gl::getContext();
2444
2445 if (context)
2446 {
2447 gl::Shader *shaderObject = context->getShader(shader);
2448
2449 if (!shaderObject)
2450 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002451 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002452 }
2453
2454 shaderObject->getSource(bufsize, length, source);
2455 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002456 }
2457 catch(std::bad_alloc&)
2458 {
2459 return error(GL_OUT_OF_MEMORY);
2460 }
2461}
2462
2463const GLubyte* __stdcall glGetString(GLenum name)
2464{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002465 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002466
2467 try
2468 {
2469 switch (name)
2470 {
2471 case GL_VENDOR:
2472 return (GLubyte*)"TransGaming Inc.";
2473 case GL_RENDERER:
2474 return (GLubyte*)"ANGLE";
2475 case GL_VERSION:
2476 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2477 case GL_SHADING_LANGUAGE_VERSION:
2478 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2479 case GL_EXTENSIONS:
2480 return (GLubyte*)"";
2481 default:
2482 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2483 }
2484 }
2485 catch(std::bad_alloc&)
2486 {
2487 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2488 }
2489
2490 return NULL;
2491}
2492
2493void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2494{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002495 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 +00002496
2497 try
2498 {
2499 UNIMPLEMENTED(); // FIXME
2500 }
2501 catch(std::bad_alloc&)
2502 {
2503 return error(GL_OUT_OF_MEMORY);
2504 }
2505}
2506
2507void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2508{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002509 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 +00002510
2511 try
2512 {
2513 UNIMPLEMENTED(); // FIXME
2514 }
2515 catch(std::bad_alloc&)
2516 {
2517 return error(GL_OUT_OF_MEMORY);
2518 }
2519}
2520
2521void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2522{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002523 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002524
2525 try
2526 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002527 gl::Context *context = gl::getContext();
2528
2529 if (context)
2530 {
2531 if (program == 0)
2532 {
2533 return error(GL_INVALID_VALUE);
2534 }
2535
2536 gl::Program *programObject = context->getProgram(program);
2537
2538 if (!programObject || !programObject->isLinked())
2539 {
2540 return error(GL_INVALID_OPERATION);
2541 }
2542
2543 if (!programObject->getUniformfv(location, params))
2544 {
2545 return error(GL_INVALID_OPERATION);
2546 }
2547 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002548 }
2549 catch(std::bad_alloc&)
2550 {
2551 return error(GL_OUT_OF_MEMORY);
2552 }
2553}
2554
2555void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2556{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002557 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002558
2559 try
2560 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002561 gl::Context *context = gl::getContext();
2562
2563 if (context)
2564 {
2565 if (program == 0)
2566 {
2567 return error(GL_INVALID_VALUE);
2568 }
2569
2570 gl::Program *programObject = context->getProgram(program);
2571
2572 if (!programObject || !programObject->isLinked())
2573 {
2574 return error(GL_INVALID_OPERATION);
2575 }
2576
2577 if (!programObject)
2578 {
2579 return error(GL_INVALID_OPERATION);
2580 }
2581
2582 if (!programObject->getUniformiv(location, params))
2583 {
2584 return error(GL_INVALID_OPERATION);
2585 }
2586 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002587 }
2588 catch(std::bad_alloc&)
2589 {
2590 return error(GL_OUT_OF_MEMORY);
2591 }
2592}
2593
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002594int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002595{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002596 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002597
2598 try
2599 {
2600 gl::Context *context = gl::getContext();
2601
2602 if (strstr(name, "gl_") == name)
2603 {
2604 return -1;
2605 }
2606
2607 if (context)
2608 {
2609 gl::Program *programObject = context->getProgram(program);
2610
2611 if (!programObject)
2612 {
2613 return error(GL_INVALID_VALUE, -1);
2614 }
2615
2616 if (!programObject->isLinked())
2617 {
2618 return error(GL_INVALID_OPERATION, -1);
2619 }
2620
2621 return programObject->getUniformLocation(name);
2622 }
2623 }
2624 catch(std::bad_alloc&)
2625 {
2626 return error(GL_OUT_OF_MEMORY, -1);
2627 }
2628
2629 return -1;
2630}
2631
2632void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2633{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002634 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002635
2636 try
2637 {
2638 if (index >= gl::MAX_VERTEX_ATTRIBS)
2639 {
2640 return error(GL_INVALID_VALUE);
2641 }
2642
2643 UNIMPLEMENTED(); // FIXME
2644 }
2645 catch(std::bad_alloc&)
2646 {
2647 return error(GL_OUT_OF_MEMORY);
2648 }
2649}
2650
2651void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2652{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002653 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002654
2655 try
2656 {
2657 if (index >= gl::MAX_VERTEX_ATTRIBS)
2658 {
2659 return error(GL_INVALID_VALUE);
2660 }
2661
2662 UNIMPLEMENTED(); // FIXME
2663 }
2664 catch(std::bad_alloc&)
2665 {
2666 return error(GL_OUT_OF_MEMORY);
2667 }
2668}
2669
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002670void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002671{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002672 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002673
2674 try
2675 {
2676 if (index >= gl::MAX_VERTEX_ATTRIBS)
2677 {
2678 return error(GL_INVALID_VALUE);
2679 }
2680
2681 UNIMPLEMENTED(); // FIXME
2682 }
2683 catch(std::bad_alloc&)
2684 {
2685 return error(GL_OUT_OF_MEMORY);
2686 }
2687}
2688
2689void __stdcall glHint(GLenum target, GLenum mode)
2690{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002691 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002692
2693 try
2694 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002695 switch (target)
2696 {
2697 case GL_GENERATE_MIPMAP_HINT:
2698 switch (mode)
2699 {
2700 case GL_FASTEST:
2701 case GL_NICEST:
2702 case GL_DONT_CARE:
2703 break;
2704 default:
2705 return error(GL_INVALID_ENUM);
2706 }
2707 break;
2708 default:
2709 return error(GL_INVALID_ENUM);
2710 }
2711
2712 gl::Context *context = gl::getContext();
2713 if (context)
2714 {
2715 if (target == GL_GENERATE_MIPMAP_HINT)
2716 context->generateMipmapHint = mode;
2717 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002718 }
2719 catch(std::bad_alloc&)
2720 {
2721 return error(GL_OUT_OF_MEMORY);
2722 }
2723}
2724
2725GLboolean __stdcall glIsBuffer(GLuint buffer)
2726{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002727 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002728
2729 try
2730 {
2731 gl::Context *context = gl::getContext();
2732
2733 if (context && buffer)
2734 {
2735 gl::Buffer *bufferObject = context->getBuffer(buffer);
2736
2737 if (bufferObject)
2738 {
2739 return GL_TRUE;
2740 }
2741 }
2742 }
2743 catch(std::bad_alloc&)
2744 {
2745 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2746 }
2747
2748 return GL_FALSE;
2749}
2750
2751GLboolean __stdcall glIsEnabled(GLenum cap)
2752{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002753 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002754
2755 try
2756 {
2757 gl::Context *context = gl::getContext();
2758
2759 if (context)
2760 {
2761 switch (cap)
2762 {
2763 case GL_CULL_FACE: return context->cullFace;
2764 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
2765 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
2766 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
2767 case GL_SCISSOR_TEST: return context->scissorTest;
2768 case GL_STENCIL_TEST: return context->stencilTest;
2769 case GL_DEPTH_TEST: return context->depthTest;
2770 case GL_BLEND: return context->blend;
2771 case GL_DITHER: return context->dither;
2772 default:
2773 return error(GL_INVALID_ENUM, false);
2774 }
2775 }
2776 }
2777 catch(std::bad_alloc&)
2778 {
2779 return error(GL_OUT_OF_MEMORY, false);
2780 }
2781
2782 return false;
2783}
2784
2785GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
2786{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002787 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002788
2789 try
2790 {
2791 gl::Context *context = gl::getContext();
2792
2793 if (context && framebuffer)
2794 {
2795 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2796
2797 if (framebufferObject)
2798 {
2799 return GL_TRUE;
2800 }
2801 }
2802 }
2803 catch(std::bad_alloc&)
2804 {
2805 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2806 }
2807
2808 return GL_FALSE;
2809}
2810
2811GLboolean __stdcall glIsProgram(GLuint program)
2812{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002813 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002814
2815 try
2816 {
2817 gl::Context *context = gl::getContext();
2818
2819 if (context && program)
2820 {
2821 gl::Program *programObject = context->getProgram(program);
2822
2823 if (programObject)
2824 {
2825 return GL_TRUE;
2826 }
2827 }
2828 }
2829 catch(std::bad_alloc&)
2830 {
2831 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2832 }
2833
2834 return GL_FALSE;
2835}
2836
2837GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
2838{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002839 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002840
2841 try
2842 {
2843 gl::Context *context = gl::getContext();
2844
2845 if (context && renderbuffer)
2846 {
2847 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2848
2849 if (renderbufferObject)
2850 {
2851 return GL_TRUE;
2852 }
2853 }
2854 }
2855 catch(std::bad_alloc&)
2856 {
2857 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2858 }
2859
2860 return GL_FALSE;
2861}
2862
2863GLboolean __stdcall glIsShader(GLuint shader)
2864{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002865 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002866
2867 try
2868 {
2869 gl::Context *context = gl::getContext();
2870
2871 if (context && shader)
2872 {
2873 gl::Shader *shaderObject = context->getShader(shader);
2874
2875 if (shaderObject)
2876 {
2877 return GL_TRUE;
2878 }
2879 }
2880 }
2881 catch(std::bad_alloc&)
2882 {
2883 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2884 }
2885
2886 return GL_FALSE;
2887}
2888
2889GLboolean __stdcall glIsTexture(GLuint texture)
2890{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002891 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002892
2893 try
2894 {
2895 gl::Context *context = gl::getContext();
2896
2897 if (context && texture)
2898 {
2899 gl::Texture *textureObject = context->getTexture(texture);
2900
2901 if (textureObject)
2902 {
2903 return GL_TRUE;
2904 }
2905 }
2906 }
2907 catch(std::bad_alloc&)
2908 {
2909 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2910 }
2911
2912 return GL_FALSE;
2913}
2914
2915void __stdcall glLineWidth(GLfloat width)
2916{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002917 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002918
2919 try
2920 {
2921 if (width <= 0.0f)
2922 {
2923 return error(GL_INVALID_VALUE);
2924 }
2925
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002926 gl::Context *context = gl::getContext();
2927
2928 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002929 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002930 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002931 }
2932 }
2933 catch(std::bad_alloc&)
2934 {
2935 return error(GL_OUT_OF_MEMORY);
2936 }
2937}
2938
2939void __stdcall glLinkProgram(GLuint program)
2940{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002941 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002942
2943 try
2944 {
2945 gl::Context *context = gl::getContext();
2946
2947 if (context)
2948 {
2949 gl::Program *programObject = context->getProgram(program);
2950
2951 if (!programObject)
2952 {
2953 return error(GL_INVALID_VALUE);
2954 }
2955
2956 programObject->link();
2957 }
2958 }
2959 catch(std::bad_alloc&)
2960 {
2961 return error(GL_OUT_OF_MEMORY);
2962 }
2963}
2964
2965void __stdcall glPixelStorei(GLenum pname, GLint param)
2966{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002967 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002968
2969 try
2970 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002971 gl::Context *context = gl::getContext();
2972
2973 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002974 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002975 switch (pname)
2976 {
2977 case GL_UNPACK_ALIGNMENT:
2978 if (param != 1 && param != 2 && param != 4 && param != 8)
2979 {
2980 return error(GL_INVALID_VALUE);
2981 }
2982
2983 context->unpackAlignment = param;
2984 break;
2985
2986 case GL_PACK_ALIGNMENT:
2987 if (param != 1 && param != 2 && param != 4 && param != 8)
2988 {
2989 return error(GL_INVALID_VALUE);
2990 }
2991
2992 context->packAlignment = param;
2993 break;
2994
2995 default:
2996 return error(GL_INVALID_ENUM);
2997 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002998 }
2999 }
3000 catch(std::bad_alloc&)
3001 {
3002 return error(GL_OUT_OF_MEMORY);
3003 }
3004}
3005
3006void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3007{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003008 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003009
3010 try
3011 {
3012 if (factor != 0.0f || units != 0.0f)
3013 {
3014 UNIMPLEMENTED(); // FIXME
3015 }
3016 }
3017 catch(std::bad_alloc&)
3018 {
3019 return error(GL_OUT_OF_MEMORY);
3020 }
3021}
3022
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003023void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003024{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003025 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003026 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003027 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003028
3029 try
3030 {
3031 if (width < 0 || height < 0)
3032 {
3033 return error(GL_INVALID_VALUE);
3034 }
3035
3036 switch (format)
3037 {
3038 case GL_RGBA:
3039 switch (type)
3040 {
3041 case GL_UNSIGNED_BYTE:
3042 break;
3043 default:
3044 return error(GL_INVALID_OPERATION);
3045 }
3046 break;
3047 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3048 switch (type)
3049 {
3050 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3051 break;
3052 default:
3053 return error(GL_INVALID_OPERATION);
3054 }
3055 break;
3056 default:
3057 return error(GL_INVALID_OPERATION);
3058 }
3059
3060 gl::Context *context = gl::getContext();
3061
3062 if (context)
3063 {
3064 context->readPixels(x, y, width, height, format, type, pixels);
3065 }
3066 }
3067 catch(std::bad_alloc&)
3068 {
3069 return error(GL_OUT_OF_MEMORY);
3070 }
3071}
3072
3073void __stdcall glReleaseShaderCompiler(void)
3074{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003075 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003076
3077 try
3078 {
3079 gl::Shader::releaseCompiler();
3080 }
3081 catch(std::bad_alloc&)
3082 {
3083 return error(GL_OUT_OF_MEMORY);
3084 }
3085}
3086
3087void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3088{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003089 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3090 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003091
3092 try
3093 {
3094 switch (target)
3095 {
3096 case GL_RENDERBUFFER:
3097 break;
3098 default:
3099 return error(GL_INVALID_ENUM);
3100 }
3101
3102 switch (internalformat)
3103 {
3104 case GL_DEPTH_COMPONENT16:
3105 case GL_RGBA4:
3106 case GL_RGB5_A1:
3107 case GL_RGB565:
3108 case GL_STENCIL_INDEX8:
3109 break;
3110 default:
3111 return error(GL_INVALID_ENUM);
3112 }
3113
3114 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3115 {
3116 return error(GL_INVALID_VALUE);
3117 }
3118
3119 gl::Context *context = gl::getContext();
3120
3121 if (context)
3122 {
3123 if (context->framebuffer == 0 || context->renderbuffer == 0)
3124 {
3125 return error(GL_INVALID_OPERATION);
3126 }
3127
3128 switch (internalformat)
3129 {
3130 case GL_DEPTH_COMPONENT16:
3131 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3132 break;
3133 case GL_RGBA4:
3134 case GL_RGB5_A1:
3135 case GL_RGB565:
3136 UNIMPLEMENTED(); // FIXME
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003137 // context->setRenderbuffer(new Colorbuffer(renderTarget));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003138 break;
3139 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003140 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003141 break;
3142 default:
3143 return error(GL_INVALID_ENUM);
3144 }
3145 }
3146 }
3147 catch(std::bad_alloc&)
3148 {
3149 return error(GL_OUT_OF_MEMORY);
3150 }
3151}
3152
3153void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3154{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003155 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003156
3157 try
3158 {
3159 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003160
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003161 if (context)
3162 {
3163 context->sampleCoverageValue = gl::clamp01(value);
3164 context->sampleCoverageInvert = invert;
3165 }
3166 }
3167 catch(std::bad_alloc&)
3168 {
3169 return error(GL_OUT_OF_MEMORY);
3170 }
3171}
3172
3173void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3174{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003175 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 +00003176
3177 try
3178 {
3179 if (width < 0 || height < 0)
3180 {
3181 return error(GL_INVALID_VALUE);
3182 }
3183
3184 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003185
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003186 if (context)
3187 {
3188 context->scissorX = x;
3189 context->scissorY = y;
3190 context->scissorWidth = width;
3191 context->scissorHeight = height;
3192 }
3193 }
3194 catch(std::bad_alloc&)
3195 {
3196 return error(GL_OUT_OF_MEMORY);
3197 }
3198}
3199
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003200void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003201{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003202 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003203 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003204 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003205
3206 try
3207 {
3208 if (n < 0 || length < 0)
3209 {
3210 return error(GL_INVALID_VALUE);
3211 }
3212
3213 UNIMPLEMENTED(); // FIXME
3214 }
3215 catch(std::bad_alloc&)
3216 {
3217 return error(GL_OUT_OF_MEMORY);
3218 }
3219}
3220
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003221void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003222{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003223 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 +00003224 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003225
3226 try
3227 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003228 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003229 {
3230 return error(GL_INVALID_VALUE);
3231 }
3232
3233 gl::Context *context = gl::getContext();
3234
3235 if (context)
3236 {
3237 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003238
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003239 if (!shaderObject)
3240 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003241 if (context->getProgram(shader))
3242 {
3243 return error(GL_INVALID_OPERATION);
3244 }
3245 else
3246 {
3247 return error(GL_INVALID_VALUE);
3248 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003249 }
3250
3251 shaderObject->setSource(count, string, length);
3252 }
3253 }
3254 catch(std::bad_alloc&)
3255 {
3256 return error(GL_OUT_OF_MEMORY);
3257 }
3258}
3259
3260void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3261{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003262 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003263}
3264
3265void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3266{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003267 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 +00003268
3269 try
3270 {
3271 switch (face)
3272 {
3273 case GL_FRONT:
3274 case GL_BACK:
3275 case GL_FRONT_AND_BACK:
3276 break;
3277 default:
3278 return error(GL_INVALID_ENUM);
3279 }
3280
3281 switch (func)
3282 {
3283 case GL_NEVER:
3284 case GL_ALWAYS:
3285 case GL_LESS:
3286 case GL_LEQUAL:
3287 case GL_EQUAL:
3288 case GL_GEQUAL:
3289 case GL_GREATER:
3290 case GL_NOTEQUAL:
3291 break;
3292 default:
3293 return error(GL_INVALID_ENUM);
3294 }
3295
3296 gl::Context *context = gl::getContext();
3297
3298 if (context)
3299 {
3300 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3301 {
3302 context->stencilFunc = func;
3303 context->stencilRef = ref;
3304 context->stencilMask = mask;
3305 }
3306
3307 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3308 {
3309 context->stencilBackFunc = func;
3310 context->stencilBackRef = ref;
3311 context->stencilBackMask = mask;
3312 }
3313 }
3314 }
3315 catch(std::bad_alloc&)
3316 {
3317 return error(GL_OUT_OF_MEMORY);
3318 }
3319}
3320
3321void __stdcall glStencilMask(GLuint mask)
3322{
3323 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3324}
3325
3326void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3327{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003328 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003329
3330 try
3331 {
3332 switch (face)
3333 {
3334 case GL_FRONT:
3335 case GL_BACK:
3336 case GL_FRONT_AND_BACK:
3337 break;
3338 default:
3339 return error(GL_INVALID_ENUM);
3340 }
3341
3342 gl::Context *context = gl::getContext();
3343
3344 if (context)
3345 {
3346 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3347 {
3348 context->stencilWritemask = mask;
3349 }
3350
3351 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3352 {
3353 context->stencilBackWritemask = mask;
3354 }
3355 }
3356 }
3357 catch(std::bad_alloc&)
3358 {
3359 return error(GL_OUT_OF_MEMORY);
3360 }
3361}
3362
3363void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3364{
3365 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3366}
3367
3368void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3369{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003370 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3371 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003372
3373 try
3374 {
3375 switch (face)
3376 {
3377 case GL_FRONT:
3378 case GL_BACK:
3379 case GL_FRONT_AND_BACK:
3380 break;
3381 default:
3382 return error(GL_INVALID_ENUM);
3383 }
3384
3385 switch (fail)
3386 {
3387 case GL_ZERO:
3388 case GL_KEEP:
3389 case GL_REPLACE:
3390 case GL_INCR:
3391 case GL_DECR:
3392 case GL_INVERT:
3393 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003394 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003395 break;
3396 default:
3397 return error(GL_INVALID_ENUM);
3398 }
3399
3400 switch (zfail)
3401 {
3402 case GL_ZERO:
3403 case GL_KEEP:
3404 case GL_REPLACE:
3405 case GL_INCR:
3406 case GL_DECR:
3407 case GL_INVERT:
3408 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003409 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003410 break;
3411 default:
3412 return error(GL_INVALID_ENUM);
3413 }
3414
3415 switch (zpass)
3416 {
3417 case GL_ZERO:
3418 case GL_KEEP:
3419 case GL_REPLACE:
3420 case GL_INCR:
3421 case GL_DECR:
3422 case GL_INVERT:
3423 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003424 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003425 break;
3426 default:
3427 return error(GL_INVALID_ENUM);
3428 }
3429
3430 gl::Context *context = gl::getContext();
3431
3432 if (context)
3433 {
3434 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3435 {
3436 context->stencilFail = fail;
3437 context->stencilPassDepthFail = zfail;
3438 context->stencilPassDepthPass = zpass;
3439 }
3440
3441 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3442 {
3443 context->stencilBackFail = fail;
3444 context->stencilBackPassDepthFail = zfail;
3445 context->stencilBackPassDepthPass = zpass;
3446 }
3447 }
3448 }
3449 catch(std::bad_alloc&)
3450 {
3451 return error(GL_OUT_OF_MEMORY);
3452 }
3453}
3454
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003455void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3456 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003457{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003458 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 +00003459 "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 +00003460 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003461
3462 try
3463 {
3464 if (level < 0 || width < 0 || height < 0)
3465 {
3466 return error(GL_INVALID_VALUE);
3467 }
3468
3469 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3470 {
3471 return error(GL_INVALID_VALUE);
3472 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003473
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003474 switch (target)
3475 {
3476 case GL_TEXTURE_2D:
3477 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3478 {
3479 return error(GL_INVALID_VALUE);
3480 }
3481 break;
3482 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3483 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3484 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3485 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3486 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3487 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3488 if (!gl::isPow2(width) || !gl::isPow2(height))
3489 {
3490 return error(GL_INVALID_VALUE);
3491 }
3492
3493 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3494 {
3495 return error(GL_INVALID_VALUE);
3496 }
3497 break;
3498 default:
3499 return error(GL_INVALID_ENUM);
3500 }
3501
3502 if (internalformat != format)
3503 {
3504 return error(GL_INVALID_OPERATION);
3505 }
3506
3507 switch (internalformat)
3508 {
3509 case GL_ALPHA:
3510 case GL_LUMINANCE:
3511 case GL_LUMINANCE_ALPHA:
3512 switch (type)
3513 {
3514 case GL_UNSIGNED_BYTE:
3515 break;
3516 default:
3517 return error(GL_INVALID_ENUM);
3518 }
3519 break;
3520 case GL_RGB:
3521 switch (type)
3522 {
3523 case GL_UNSIGNED_BYTE:
3524 case GL_UNSIGNED_SHORT_5_6_5:
3525 break;
3526 default:
3527 return error(GL_INVALID_ENUM);
3528 }
3529 break;
3530 case GL_RGBA:
3531 switch (type)
3532 {
3533 case GL_UNSIGNED_BYTE:
3534 case GL_UNSIGNED_SHORT_4_4_4_4:
3535 case GL_UNSIGNED_SHORT_5_5_5_1:
3536 break;
3537 default:
3538 return error(GL_INVALID_ENUM);
3539 }
3540 break;
3541 default:
3542 return error(GL_INVALID_VALUE);
3543 }
3544
3545 if (border != 0)
3546 {
3547 return error(GL_INVALID_VALUE);
3548 }
3549
3550 gl::Context *context = gl::getContext();
3551
3552 if (context)
3553 {
3554 if (target == GL_TEXTURE_2D)
3555 {
3556 gl::Texture2D *texture = context->getTexture2D();
3557
3558 if (!texture)
3559 {
3560 return error(GL_INVALID_OPERATION);
3561 }
3562
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003563 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003564 }
3565 else
3566 {
3567 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3568
3569 if (!texture)
3570 {
3571 return error(GL_INVALID_OPERATION);
3572 }
3573
3574 switch (target)
3575 {
3576 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003577 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003578 break;
3579 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003580 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003581 break;
3582 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003583 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003584 break;
3585 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003586 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003587 break;
3588 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003589 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003590 break;
3591 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003592 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003593 break;
3594 default: UNREACHABLE();
3595 }
3596 }
3597 }
3598 }
3599 catch(std::bad_alloc&)
3600 {
3601 return error(GL_OUT_OF_MEMORY);
3602 }
3603}
3604
3605void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3606{
3607 glTexParameteri(target, pname, (GLint)param);
3608}
3609
3610void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3611{
3612 glTexParameteri(target, pname, (GLint)*params);
3613}
3614
3615void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3616{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003617 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003618
3619 try
3620 {
3621 gl::Context *context = gl::getContext();
3622
3623 if (context)
3624 {
3625 gl::Texture *texture;
3626
3627 switch (target)
3628 {
3629 case GL_TEXTURE_2D:
3630 texture = context->getTexture2D();
3631 break;
3632 case GL_TEXTURE_CUBE_MAP:
3633 texture = context->getTextureCubeMap();
3634 break;
3635 default:
3636 return error(GL_INVALID_ENUM);
3637 }
3638
3639 switch (pname)
3640 {
3641 case GL_TEXTURE_WRAP_S:
3642 if (!texture->setWrapS((GLenum)param))
3643 {
3644 return error(GL_INVALID_ENUM);
3645 }
3646 break;
3647 case GL_TEXTURE_WRAP_T:
3648 if (!texture->setWrapT((GLenum)param))
3649 {
3650 return error(GL_INVALID_ENUM);
3651 }
3652 break;
3653 case GL_TEXTURE_MIN_FILTER:
3654 if (!texture->setMinFilter((GLenum)param))
3655 {
3656 return error(GL_INVALID_ENUM);
3657 }
3658 break;
3659 case GL_TEXTURE_MAG_FILTER:
3660 if (!texture->setMagFilter((GLenum)param))
3661 {
3662 return error(GL_INVALID_ENUM);
3663 }
3664 break;
3665 default:
3666 return error(GL_INVALID_ENUM);
3667 }
3668 }
3669 }
3670 catch(std::bad_alloc&)
3671 {
3672 return error(GL_OUT_OF_MEMORY);
3673 }
3674}
3675
3676void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3677{
3678 glTexParameteri(target, pname, *params);
3679}
3680
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003681void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3682 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003683{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003684 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3685 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003686 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003687 target, level, xoffset, yoffset, width, height, format, type, pixels);
3688
3689 try
3690 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003691 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
3692 {
3693 return error(GL_INVALID_ENUM);
3694 }
3695
3696 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003697 {
3698 return error(GL_INVALID_VALUE);
3699 }
3700
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003701 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
3702 {
3703 return error(GL_INVALID_VALUE);
3704 }
3705
3706 if (!es2dx::CheckTextureFormatType(format, type))
3707 {
3708 return error(GL_INVALID_ENUM);
3709 }
3710
3711 if (width == 0 || height == 0 || pixels == NULL)
3712 {
3713 return;
3714 }
3715
3716 gl::Context *context = gl::getContext();
3717
3718 if (context)
3719 {
3720 if (target == GL_TEXTURE_2D)
3721 {
3722 gl::Texture2D *texture = context->getTexture2D();
3723
3724 if (!texture)
3725 {
3726 return error(GL_INVALID_OPERATION);
3727 }
3728
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003729 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003730 }
3731 else if (es2dx::IsCubemapTextureTarget(target))
3732 {
3733 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3734
3735 if (!texture)
3736 {
3737 return error(GL_INVALID_OPERATION);
3738 }
3739
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003740 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003741 }
3742 else
3743 {
3744 UNREACHABLE();
3745 }
3746 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003747 }
3748 catch(std::bad_alloc&)
3749 {
3750 return error(GL_OUT_OF_MEMORY);
3751 }
3752}
3753
3754void __stdcall glUniform1f(GLint location, GLfloat x)
3755{
3756 glUniform1fv(location, 1, &x);
3757}
3758
3759void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
3760{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003761 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003762
3763 try
3764 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003765 if (count < 0)
3766 {
3767 return error(GL_INVALID_VALUE);
3768 }
3769
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003770 if (location == -1)
3771 {
3772 return;
3773 }
3774
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003775 gl::Context *context = gl::getContext();
3776
3777 if (context)
3778 {
3779 gl::Program *program = context->getCurrentProgram();
3780
3781 if (!program)
3782 {
3783 return error(GL_INVALID_OPERATION);
3784 }
3785
3786 if (!program->setUniform1fv(location, count, v))
3787 {
3788 return error(GL_INVALID_OPERATION);
3789 }
3790 }
3791 }
3792 catch(std::bad_alloc&)
3793 {
3794 return error(GL_OUT_OF_MEMORY);
3795 }
3796}
3797
3798void __stdcall glUniform1i(GLint location, GLint x)
3799{
3800 glUniform1iv(location, 1, &x);
3801}
3802
3803void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
3804{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003805 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003806
3807 try
3808 {
3809 if (count < 0)
3810 {
3811 return error(GL_INVALID_VALUE);
3812 }
3813
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003814 if (location == -1)
3815 {
3816 return;
3817 }
3818
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003819 gl::Context *context = gl::getContext();
3820
3821 if (context)
3822 {
3823 gl::Program *program = context->getCurrentProgram();
3824
3825 if (!program)
3826 {
3827 return error(GL_INVALID_OPERATION);
3828 }
3829
3830 if (!program->setUniform1iv(location, count, v))
3831 {
3832 return error(GL_INVALID_OPERATION);
3833 }
3834 }
3835 }
3836 catch(std::bad_alloc&)
3837 {
3838 return error(GL_OUT_OF_MEMORY);
3839 }
3840}
3841
3842void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
3843{
3844 GLfloat xy[2] = {x, y};
3845
3846 glUniform2fv(location, 1, (GLfloat*)&xy);
3847}
3848
3849void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
3850{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003851 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003852
3853 try
3854 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003855 if (count < 0)
3856 {
3857 return error(GL_INVALID_VALUE);
3858 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003859
3860 if (location == -1)
3861 {
3862 return;
3863 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003864
3865 gl::Context *context = gl::getContext();
3866
3867 if (context)
3868 {
3869 gl::Program *program = context->getCurrentProgram();
3870
3871 if (!program)
3872 {
3873 return error(GL_INVALID_OPERATION);
3874 }
3875
3876 if (!program->setUniform2fv(location, count, v))
3877 {
3878 return error(GL_INVALID_OPERATION);
3879 }
3880 }
3881 }
3882 catch(std::bad_alloc&)
3883 {
3884 return error(GL_OUT_OF_MEMORY);
3885 }
3886}
3887
3888void __stdcall glUniform2i(GLint location, GLint x, GLint y)
3889{
3890 GLint xy[4] = {x, y};
3891
3892 glUniform2iv(location, 1, (GLint*)&xy);
3893}
3894
3895void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
3896{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003897 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003898
3899 try
3900 {
3901 if (count < 0)
3902 {
3903 return error(GL_INVALID_VALUE);
3904 }
3905
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003906 if (location == -1)
3907 {
3908 return;
3909 }
3910
3911 gl::Context *context = gl::getContext();
3912
3913 if (context)
3914 {
3915 gl::Program *program = context->getCurrentProgram();
3916
3917 if (!program)
3918 {
3919 return error(GL_INVALID_OPERATION);
3920 }
3921
3922 if (!program->setUniform2iv(location, count, v))
3923 {
3924 return error(GL_INVALID_OPERATION);
3925 }
3926 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003927 }
3928 catch(std::bad_alloc&)
3929 {
3930 return error(GL_OUT_OF_MEMORY);
3931 }
3932}
3933
3934void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
3935{
3936 GLfloat xyz[3] = {x, y, z};
3937
3938 glUniform3fv(location, 1, (GLfloat*)&xyz);
3939}
3940
3941void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
3942{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003943 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003944
3945 try
3946 {
3947 if (count < 0)
3948 {
3949 return error(GL_INVALID_VALUE);
3950 }
3951
3952 if (location == -1)
3953 {
3954 return;
3955 }
3956
3957 gl::Context *context = gl::getContext();
3958
3959 if (context)
3960 {
3961 gl::Program *program = context->getCurrentProgram();
3962
3963 if (!program)
3964 {
3965 return error(GL_INVALID_OPERATION);
3966 }
3967
3968 if (!program->setUniform3fv(location, count, v))
3969 {
3970 return error(GL_INVALID_OPERATION);
3971 }
3972 }
3973 }
3974 catch(std::bad_alloc&)
3975 {
3976 return error(GL_OUT_OF_MEMORY);
3977 }
3978}
3979
3980void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
3981{
3982 GLint xyz[3] = {x, y, z};
3983
3984 glUniform3iv(location, 1, (GLint*)&xyz);
3985}
3986
3987void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
3988{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003989 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003990
3991 try
3992 {
3993 if (count < 0)
3994 {
3995 return error(GL_INVALID_VALUE);
3996 }
3997
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003998 if (location == -1)
3999 {
4000 return;
4001 }
4002
4003 gl::Context *context = gl::getContext();
4004
4005 if (context)
4006 {
4007 gl::Program *program = context->getCurrentProgram();
4008
4009 if (!program)
4010 {
4011 return error(GL_INVALID_OPERATION);
4012 }
4013
4014 if (!program->setUniform3iv(location, count, v))
4015 {
4016 return error(GL_INVALID_OPERATION);
4017 }
4018 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004019 }
4020 catch(std::bad_alloc&)
4021 {
4022 return error(GL_OUT_OF_MEMORY);
4023 }
4024}
4025
4026void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4027{
4028 GLfloat xyzw[4] = {x, y, z, w};
4029
4030 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4031}
4032
4033void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4034{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004035 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004036
4037 try
4038 {
4039 if (count < 0)
4040 {
4041 return error(GL_INVALID_VALUE);
4042 }
4043
4044 if (location == -1)
4045 {
4046 return;
4047 }
4048
4049 gl::Context *context = gl::getContext();
4050
4051 if (context)
4052 {
4053 gl::Program *program = context->getCurrentProgram();
4054
4055 if (!program)
4056 {
4057 return error(GL_INVALID_OPERATION);
4058 }
4059
4060 if (!program->setUniform4fv(location, count, v))
4061 {
4062 return error(GL_INVALID_OPERATION);
4063 }
4064 }
4065 }
4066 catch(std::bad_alloc&)
4067 {
4068 return error(GL_OUT_OF_MEMORY);
4069 }
4070}
4071
4072void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4073{
4074 GLint xyzw[4] = {x, y, z, w};
4075
4076 glUniform4iv(location, 1, (GLint*)&xyzw);
4077}
4078
4079void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4080{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004081 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004082
4083 try
4084 {
4085 if (count < 0)
4086 {
4087 return error(GL_INVALID_VALUE);
4088 }
4089
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004090 if (location == -1)
4091 {
4092 return;
4093 }
4094
4095 gl::Context *context = gl::getContext();
4096
4097 if (context)
4098 {
4099 gl::Program *program = context->getCurrentProgram();
4100
4101 if (!program)
4102 {
4103 return error(GL_INVALID_OPERATION);
4104 }
4105
4106 if (!program->setUniform4iv(location, count, v))
4107 {
4108 return error(GL_INVALID_OPERATION);
4109 }
4110 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004111 }
4112 catch(std::bad_alloc&)
4113 {
4114 return error(GL_OUT_OF_MEMORY);
4115 }
4116}
4117
4118void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4119{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004120 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4121 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004122
4123 try
4124 {
4125 if (count < 0 || transpose != GL_FALSE)
4126 {
4127 return error(GL_INVALID_VALUE);
4128 }
4129
4130 if (location == -1)
4131 {
4132 return;
4133 }
4134
4135 gl::Context *context = gl::getContext();
4136
4137 if (context)
4138 {
4139 gl::Program *program = context->getCurrentProgram();
4140
4141 if (!program)
4142 {
4143 return error(GL_INVALID_OPERATION);
4144 }
4145
4146 if (!program->setUniformMatrix2fv(location, count, value))
4147 {
4148 return error(GL_INVALID_OPERATION);
4149 }
4150 }
4151 }
4152 catch(std::bad_alloc&)
4153 {
4154 return error(GL_OUT_OF_MEMORY);
4155 }
4156}
4157
4158void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4159{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004160 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4161 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004162
4163 try
4164 {
4165 if (count < 0 || transpose != GL_FALSE)
4166 {
4167 return error(GL_INVALID_VALUE);
4168 }
4169
4170 if (location == -1)
4171 {
4172 return;
4173 }
4174
4175 gl::Context *context = gl::getContext();
4176
4177 if (context)
4178 {
4179 gl::Program *program = context->getCurrentProgram();
4180
4181 if (!program)
4182 {
4183 return error(GL_INVALID_OPERATION);
4184 }
4185
4186 if (!program->setUniformMatrix3fv(location, count, value))
4187 {
4188 return error(GL_INVALID_OPERATION);
4189 }
4190 }
4191 }
4192 catch(std::bad_alloc&)
4193 {
4194 return error(GL_OUT_OF_MEMORY);
4195 }
4196}
4197
4198void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4199{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004200 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4201 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004202
4203 try
4204 {
4205 if (count < 0 || transpose != GL_FALSE)
4206 {
4207 return error(GL_INVALID_VALUE);
4208 }
4209
4210 if (location == -1)
4211 {
4212 return;
4213 }
4214
4215 gl::Context *context = gl::getContext();
4216
4217 if (context)
4218 {
4219 gl::Program *program = context->getCurrentProgram();
4220
4221 if (!program)
4222 {
4223 return error(GL_INVALID_OPERATION);
4224 }
4225
4226 if (!program->setUniformMatrix4fv(location, count, value))
4227 {
4228 return error(GL_INVALID_OPERATION);
4229 }
4230 }
4231 }
4232 catch(std::bad_alloc&)
4233 {
4234 return error(GL_OUT_OF_MEMORY);
4235 }
4236}
4237
4238void __stdcall glUseProgram(GLuint program)
4239{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004240 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004241
4242 try
4243 {
4244 gl::Context *context = gl::getContext();
4245
4246 if (context)
4247 {
4248 gl::Program *programObject = context->getProgram(program);
4249
4250 if (programObject && !programObject->isLinked())
4251 {
4252 return error(GL_INVALID_OPERATION);
4253 }
4254
4255 context->useProgram(program);
4256 }
4257 }
4258 catch(std::bad_alloc&)
4259 {
4260 return error(GL_OUT_OF_MEMORY);
4261 }
4262}
4263
4264void __stdcall glValidateProgram(GLuint program)
4265{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004266 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004267
4268 try
4269 {
4270 UNIMPLEMENTED(); // FIXME
4271 }
4272 catch(std::bad_alloc&)
4273 {
4274 return error(GL_OUT_OF_MEMORY);
4275 }
4276}
4277
4278void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4279{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004280 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004281
4282 try
4283 {
4284 if (index >= gl::MAX_VERTEX_ATTRIBS)
4285 {
4286 return error(GL_INVALID_VALUE);
4287 }
4288
4289 UNIMPLEMENTED(); // FIXME
4290 }
4291 catch(std::bad_alloc&)
4292 {
4293 return error(GL_OUT_OF_MEMORY);
4294 }
4295}
4296
4297void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4298{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004299 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004300
4301 try
4302 {
4303 if (index >= gl::MAX_VERTEX_ATTRIBS)
4304 {
4305 return error(GL_INVALID_VALUE);
4306 }
4307
4308 UNIMPLEMENTED(); // FIXME
4309 }
4310 catch(std::bad_alloc&)
4311 {
4312 return error(GL_OUT_OF_MEMORY);
4313 }
4314}
4315
4316void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4317{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004318 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004319
4320 try
4321 {
4322 if (index >= gl::MAX_VERTEX_ATTRIBS)
4323 {
4324 return error(GL_INVALID_VALUE);
4325 }
4326
4327 UNIMPLEMENTED(); // FIXME
4328 }
4329 catch(std::bad_alloc&)
4330 {
4331 return error(GL_OUT_OF_MEMORY);
4332 }
4333}
4334
4335void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4336{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004337 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004338
4339 try
4340 {
4341 if (index >= gl::MAX_VERTEX_ATTRIBS)
4342 {
4343 return error(GL_INVALID_VALUE);
4344 }
4345
4346 UNIMPLEMENTED(); // FIXME
4347 }
4348 catch(std::bad_alloc&)
4349 {
4350 return error(GL_OUT_OF_MEMORY);
4351 }
4352}
4353
4354void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4355{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004356 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 +00004357
4358 try
4359 {
4360 if (index >= gl::MAX_VERTEX_ATTRIBS)
4361 {
4362 return error(GL_INVALID_VALUE);
4363 }
4364
4365 UNIMPLEMENTED(); // FIXME
4366 }
4367 catch(std::bad_alloc&)
4368 {
4369 return error(GL_OUT_OF_MEMORY);
4370 }
4371}
4372
4373void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4374{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004375 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004376
4377 try
4378 {
4379 if (index >= gl::MAX_VERTEX_ATTRIBS)
4380 {
4381 return error(GL_INVALID_VALUE);
4382 }
4383
4384 UNIMPLEMENTED(); // FIXME
4385 }
4386 catch(std::bad_alloc&)
4387 {
4388 return error(GL_OUT_OF_MEMORY);
4389 }
4390}
4391
4392void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4393{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004394 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 +00004395
4396 try
4397 {
4398 if (index >= gl::MAX_VERTEX_ATTRIBS)
4399 {
4400 return error(GL_INVALID_VALUE);
4401 }
4402
4403 UNIMPLEMENTED(); // FIXME
4404 }
4405 catch(std::bad_alloc&)
4406 {
4407 return error(GL_OUT_OF_MEMORY);
4408 }
4409}
4410
4411void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4412{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004413 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004414
4415 try
4416 {
4417 if (index >= gl::MAX_VERTEX_ATTRIBS)
4418 {
4419 return error(GL_INVALID_VALUE);
4420 }
4421
4422 UNIMPLEMENTED(); // FIXME
4423 }
4424 catch(std::bad_alloc&)
4425 {
4426 return error(GL_OUT_OF_MEMORY);
4427 }
4428}
4429
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004430void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004431{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004432 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004433 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004434 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004435
4436 try
4437 {
4438 if (index >= gl::MAX_VERTEX_ATTRIBS)
4439 {
4440 return error(GL_INVALID_VALUE);
4441 }
4442
4443 if (size < 1 || size > 4)
4444 {
4445 return error(GL_INVALID_VALUE);
4446 }
4447
4448 switch (type)
4449 {
4450 case GL_BYTE:
4451 case GL_UNSIGNED_BYTE:
4452 case GL_SHORT:
4453 case GL_UNSIGNED_SHORT:
4454 case GL_FIXED:
4455 case GL_FLOAT:
4456 break;
4457 default:
4458 return error(GL_INVALID_ENUM);
4459 }
4460
4461 if (stride < 0)
4462 {
4463 return error(GL_INVALID_VALUE);
4464 }
4465
4466 gl::Context *context = gl::getContext();
4467
4468 if (context)
4469 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004470 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4471 context->vertexAttribute[index].mSize = size;
4472 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004473 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004474 context->vertexAttribute[index].mStride = stride;
4475 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004476 }
4477 }
4478 catch(std::bad_alloc&)
4479 {
4480 return error(GL_OUT_OF_MEMORY);
4481 }
4482}
4483
4484void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4485{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004486 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 +00004487
4488 try
4489 {
4490 if (width < 0 || height < 0)
4491 {
4492 return error(GL_INVALID_VALUE);
4493 }
4494
4495 gl::Context *context = gl::getContext();
4496
4497 if (context)
4498 {
4499 context->viewportX = x;
4500 context->viewportY = y;
4501 context->viewportWidth = width;
4502 context->viewportHeight = height;
4503 }
4504 }
4505 catch(std::bad_alloc&)
4506 {
4507 return error(GL_OUT_OF_MEMORY);
4508 }
4509}
4510
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004511void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4512 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004513{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004514 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4515 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004516 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004517 target, level, internalformat, width, height, depth, border, format, type, pixels);
4518
4519 try
4520 {
4521 UNIMPLEMENTED(); // FIXME
4522 }
4523 catch(std::bad_alloc&)
4524 {
4525 return error(GL_OUT_OF_MEMORY);
4526 }
4527}
4528}