blob: 651f9fd517bf555268ec6d6370d4e9b786969d25 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016#include "Context.h"
17#include "main.h"
18#include "Program.h"
19#include "Shader.h"
20#include "Buffer.h"
21#include "Texture.h"
22#include "Renderbuffer.h"
23#include "Framebuffer.h"
24#include "mathutil.h"
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000025#include "common/debug.h"
daniel@transgaming.com00c75962010-03-11 20:36:15 +000026#include "utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027
28extern "C"
29{
30
31void __stdcall glActiveTexture(GLenum texture)
32{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000033 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034
35 try
36 {
37 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
38 {
39 return error(GL_INVALID_ENUM);
40 }
41
42 gl::Context *context = gl::getContext();
43
44 if (context)
45 {
46 context->activeSampler = texture - GL_TEXTURE0;
47 }
48 }
49 catch(std::bad_alloc&)
50 {
51 return error(GL_OUT_OF_MEMORY);
52 }
53}
54
55void __stdcall glAttachShader(GLuint program, GLuint shader)
56{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000057 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000058
59 try
60 {
61 gl::Context *context = gl::getContext();
62
63 if (context)
64 {
65 gl::Program *programObject = context->getProgram(program);
66 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000067
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000068 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000069 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000070 if (context->getShader(program))
71 {
72 return error(GL_INVALID_OPERATION);
73 }
74 else
75 {
76 return error(GL_INVALID_VALUE);
77 }
78 }
79
80 if (!shaderObject)
81 {
82 if (context->getProgram(shader))
83 {
84 return error(GL_INVALID_OPERATION);
85 }
86 else
87 {
88 return error(GL_INVALID_VALUE);
89 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090 }
91
92 if (!programObject->attachShader(shaderObject))
93 {
94 return error(GL_INVALID_OPERATION);
95 }
96 }
97 }
98 catch(std::bad_alloc&)
99 {
100 return error(GL_OUT_OF_MEMORY);
101 }
102}
103
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000104void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000105{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000106 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107
108 try
109 {
110 if (index >= gl::MAX_VERTEX_ATTRIBS)
111 {
112 return error(GL_INVALID_VALUE);
113 }
114
115 gl::Context *context = gl::getContext();
116
117 if (context)
118 {
119 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000120
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000121 if (!programObject)
122 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000123 if (context->getShader(program))
124 {
125 return error(GL_INVALID_OPERATION);
126 }
127 else
128 {
129 return error(GL_INVALID_VALUE);
130 }
131 }
132
133 if (strncmp(name, "gl_", 3) == 0)
134 {
135 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000136 }
137
138 programObject->bindAttributeLocation(index, name);
139 }
140 }
141 catch(std::bad_alloc&)
142 {
143 return error(GL_OUT_OF_MEMORY);
144 }
145}
146
147void __stdcall glBindBuffer(GLenum target, GLuint buffer)
148{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000149 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150
151 try
152 {
153 gl::Context *context = gl::getContext();
154
155 if (context)
156 {
157 switch (target)
158 {
159 case GL_ARRAY_BUFFER:
160 context->bindArrayBuffer(buffer);
161 return;
162 case GL_ELEMENT_ARRAY_BUFFER:
163 context->bindElementArrayBuffer(buffer);
164 return;
165 default:
166 return error(GL_INVALID_ENUM);
167 }
168 }
169 }
170 catch(std::bad_alloc&)
171 {
172 return error(GL_OUT_OF_MEMORY);
173 }
174}
175
176void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
177{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000178 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000179
180 try
181 {
182 if (target != GL_FRAMEBUFFER)
183 {
184 return error(GL_INVALID_ENUM);
185 }
186
187 gl::Context *context = gl::getContext();
188
189 if (context)
190 {
191 context->bindFramebuffer(framebuffer);
192 }
193 }
194 catch(std::bad_alloc&)
195 {
196 return error(GL_OUT_OF_MEMORY);
197 }
198}
199
200void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
201{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000202 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203
204 try
205 {
206 if (target != GL_RENDERBUFFER)
207 {
208 return error(GL_INVALID_ENUM);
209 }
210
211 gl::Context *context = gl::getContext();
212
213 if (context)
214 {
215 context->bindRenderbuffer(renderbuffer);
216 }
217 }
218 catch(std::bad_alloc&)
219 {
220 return error(GL_OUT_OF_MEMORY);
221 }
222}
223
224void __stdcall glBindTexture(GLenum target, GLuint texture)
225{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000226 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227
228 try
229 {
230 gl::Context *context = gl::getContext();
231
232 if (context)
233 {
234 gl::Texture *textureObject = context->getTexture(texture);
235
236 if (textureObject && textureObject->getTarget() != target && texture != 0)
237 {
238 return error(GL_INVALID_OPERATION);
239 }
240
241 switch (target)
242 {
243 case GL_TEXTURE_2D:
244 context->bindTexture2D(texture);
245 return;
246 case GL_TEXTURE_CUBE_MAP:
247 context->bindTextureCubeMap(texture);
248 return;
249 default:
250 return error(GL_INVALID_ENUM);
251 }
252 }
253 }
254 catch(std::bad_alloc&)
255 {
256 return error(GL_OUT_OF_MEMORY);
257 }
258}
259
260void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
261{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000262 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
263 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264
265 try
266 {
267 gl::Context* context = gl::getContext();
268
269 if (context)
270 {
271 context->blendColor.red = gl::clamp01(red);
272 context->blendColor.blue = gl::clamp01(blue);
273 context->blendColor.green = gl::clamp01(green);
274 context->blendColor.alpha = gl::clamp01(alpha);
275 }
276 }
277 catch(std::bad_alloc&)
278 {
279 return error(GL_OUT_OF_MEMORY);
280 }
281}
282
283void __stdcall glBlendEquation(GLenum mode)
284{
285 glBlendEquationSeparate(mode, mode);
286}
287
288void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
289{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000290 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000291
292 try
293 {
294 switch (modeRGB)
295 {
296 case GL_FUNC_ADD:
297 case GL_FUNC_SUBTRACT:
298 case GL_FUNC_REVERSE_SUBTRACT:
299 break;
300 default:
301 return error(GL_INVALID_ENUM);
302 }
303
304 switch (modeAlpha)
305 {
306 case GL_FUNC_ADD:
307 case GL_FUNC_SUBTRACT:
308 case GL_FUNC_REVERSE_SUBTRACT:
309 break;
310 default:
311 return error(GL_INVALID_ENUM);
312 }
313
314 gl::Context *context = gl::getContext();
315
316 if (context)
317 {
318 context->blendEquationRGB = modeRGB;
319 context->blendEquationAlpha = modeAlpha;
320 }
321 }
322 catch(std::bad_alloc&)
323 {
324 return error(GL_OUT_OF_MEMORY);
325 }
326}
327
328void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
329{
330 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
331}
332
333void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
334{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000335 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
336 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000337
338 try
339 {
340 switch (srcRGB)
341 {
342 case GL_ZERO:
343 case GL_ONE:
344 case GL_SRC_COLOR:
345 case GL_ONE_MINUS_SRC_COLOR:
346 case GL_DST_COLOR:
347 case GL_ONE_MINUS_DST_COLOR:
348 case GL_SRC_ALPHA:
349 case GL_ONE_MINUS_SRC_ALPHA:
350 case GL_DST_ALPHA:
351 case GL_ONE_MINUS_DST_ALPHA:
352 case GL_CONSTANT_COLOR:
353 case GL_ONE_MINUS_CONSTANT_COLOR:
354 case GL_CONSTANT_ALPHA:
355 case GL_ONE_MINUS_CONSTANT_ALPHA:
356 case GL_SRC_ALPHA_SATURATE:
357 break;
358 default:
359 return error(GL_INVALID_ENUM);
360 }
361
362 switch (dstRGB)
363 {
364 case GL_ZERO:
365 case GL_ONE:
366 case GL_SRC_COLOR:
367 case GL_ONE_MINUS_SRC_COLOR:
368 case GL_DST_COLOR:
369 case GL_ONE_MINUS_DST_COLOR:
370 case GL_SRC_ALPHA:
371 case GL_ONE_MINUS_SRC_ALPHA:
372 case GL_DST_ALPHA:
373 case GL_ONE_MINUS_DST_ALPHA:
374 case GL_CONSTANT_COLOR:
375 case GL_ONE_MINUS_CONSTANT_COLOR:
376 case GL_CONSTANT_ALPHA:
377 case GL_ONE_MINUS_CONSTANT_ALPHA:
378 break;
379 default:
380 return error(GL_INVALID_ENUM);
381 }
382
383 switch (srcAlpha)
384 {
385 case GL_ZERO:
386 case GL_ONE:
387 case GL_SRC_COLOR:
388 case GL_ONE_MINUS_SRC_COLOR:
389 case GL_DST_COLOR:
390 case GL_ONE_MINUS_DST_COLOR:
391 case GL_SRC_ALPHA:
392 case GL_ONE_MINUS_SRC_ALPHA:
393 case GL_DST_ALPHA:
394 case GL_ONE_MINUS_DST_ALPHA:
395 case GL_CONSTANT_COLOR:
396 case GL_ONE_MINUS_CONSTANT_COLOR:
397 case GL_CONSTANT_ALPHA:
398 case GL_ONE_MINUS_CONSTANT_ALPHA:
399 case GL_SRC_ALPHA_SATURATE:
400 break;
401 default:
402 return error(GL_INVALID_ENUM);
403 }
404
405 switch (dstAlpha)
406 {
407 case GL_ZERO:
408 case GL_ONE:
409 case GL_SRC_COLOR:
410 case GL_ONE_MINUS_SRC_COLOR:
411 case GL_DST_COLOR:
412 case GL_ONE_MINUS_DST_COLOR:
413 case GL_SRC_ALPHA:
414 case GL_ONE_MINUS_SRC_ALPHA:
415 case GL_DST_ALPHA:
416 case GL_ONE_MINUS_DST_ALPHA:
417 case GL_CONSTANT_COLOR:
418 case GL_ONE_MINUS_CONSTANT_COLOR:
419 case GL_CONSTANT_ALPHA:
420 case GL_ONE_MINUS_CONSTANT_ALPHA:
421 break;
422 default:
423 return error(GL_INVALID_ENUM);
424 }
425
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000426 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
427 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
428
429 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
430 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
431
432 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000433 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000434 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
435 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000436 }
437
438 gl::Context *context = gl::getContext();
439
440 if (context)
441 {
442 context->sourceBlendRGB = srcRGB;
443 context->sourceBlendAlpha = srcAlpha;
444 context->destBlendRGB = dstRGB;
445 context->destBlendAlpha = dstAlpha;
446 }
447 }
448 catch(std::bad_alloc&)
449 {
450 return error(GL_OUT_OF_MEMORY);
451 }
452}
453
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000454void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000455{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000456 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000457 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000458
459 try
460 {
461 if (size < 0)
462 {
463 return error(GL_INVALID_VALUE);
464 }
465
466 switch (usage)
467 {
468 case GL_STREAM_DRAW:
469 case GL_STATIC_DRAW:
470 case GL_DYNAMIC_DRAW:
471 break;
472 default:
473 return error(GL_INVALID_ENUM);
474 }
475
476 gl::Context *context = gl::getContext();
477
478 if (context)
479 {
480 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000481
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000482 switch (target)
483 {
484 case GL_ARRAY_BUFFER:
485 buffer = context->getArrayBuffer();
486 break;
487 case GL_ELEMENT_ARRAY_BUFFER:
488 buffer = context->getElementArrayBuffer();
489 break;
490 default:
491 return error(GL_INVALID_ENUM);
492 }
493
494 if (!buffer)
495 {
496 return error(GL_INVALID_OPERATION);
497 }
498
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000499 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000500 }
501 }
502 catch(std::bad_alloc&)
503 {
504 return error(GL_OUT_OF_MEMORY);
505 }
506}
507
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000508void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000509{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000510 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000511 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512
513 try
514 {
515 if (size < 0)
516 {
517 return error(GL_INVALID_VALUE);
518 }
519
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000520 if (data == NULL)
521 {
522 return;
523 }
524
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000525 gl::Context *context = gl::getContext();
526
527 if (context)
528 {
529 gl::Buffer *buffer;
530
531 switch (target)
532 {
533 case GL_ARRAY_BUFFER:
534 buffer = context->getArrayBuffer();
535 break;
536 case GL_ELEMENT_ARRAY_BUFFER:
537 buffer = context->getElementArrayBuffer();
538 break;
539 default:
540 return error(GL_INVALID_ENUM);
541 }
542
543 if (!buffer)
544 {
545 return error(GL_INVALID_OPERATION);
546 }
547
548 GLenum err = buffer->bufferSubData(data, size, offset);
549
550 if (err != GL_NO_ERROR)
551 {
552 return error(err);
553 }
554 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000555 }
556 catch(std::bad_alloc&)
557 {
558 return error(GL_OUT_OF_MEMORY);
559 }
560}
561
562GLenum __stdcall glCheckFramebufferStatus(GLenum target)
563{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000564 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000565
566 try
567 {
568 if (target != GL_FRAMEBUFFER)
569 {
570 return error(GL_INVALID_ENUM, 0);
571 }
572
573 gl::Context *context = gl::getContext();
574
575 if (context)
576 {
577 gl::Framebuffer *framebuffer = context->getFramebuffer();
578
579 return framebuffer->completeness();
580 }
581 }
582 catch(std::bad_alloc&)
583 {
584 return error(GL_OUT_OF_MEMORY, 0);
585 }
586
587 return 0;
588}
589
590void __stdcall glClear(GLbitfield mask)
591{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000592 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000593
594 try
595 {
596 gl::Context *context = gl::getContext();
597
598 if (context)
599 {
600 context->clear(mask);
601 }
602 }
603 catch(std::bad_alloc&)
604 {
605 return error(GL_OUT_OF_MEMORY);
606 }
607}
608
609void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
610{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000611 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
612 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000613
614 try
615 {
616 gl::Context *context = gl::getContext();
617
618 if (context)
619 {
620 context->setClearColor(red, green, blue, alpha);
621 }
622 }
623 catch(std::bad_alloc&)
624 {
625 return error(GL_OUT_OF_MEMORY);
626 }
627}
628
629void __stdcall glClearDepthf(GLclampf depth)
630{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000631 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000632
633 try
634 {
635 gl::Context *context = gl::getContext();
636
637 if (context)
638 {
639 context->setClearDepth(depth);
640 }
641 }
642 catch(std::bad_alloc&)
643 {
644 return error(GL_OUT_OF_MEMORY);
645 }
646}
647
648void __stdcall glClearStencil(GLint s)
649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000650 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000651
652 try
653 {
654 gl::Context *context = gl::getContext();
655
656 if (context)
657 {
658 context->setClearStencil(s);
659 }
660 }
661 catch(std::bad_alloc&)
662 {
663 return error(GL_OUT_OF_MEMORY);
664 }
665}
666
667void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
668{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000669 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
670 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000671
672 try
673 {
674 gl::Context *context = gl::getContext();
675
676 if (context)
677 {
678 context->colorMaskRed = red != GL_FALSE;
679 context->colorMaskGreen = green != GL_FALSE;
680 context->colorMaskBlue = blue != GL_FALSE;
681 context->colorMaskAlpha = alpha != GL_FALSE;
682 }
683 }
684 catch(std::bad_alloc&)
685 {
686 return error(GL_OUT_OF_MEMORY);
687 }
688}
689
690void __stdcall glCompileShader(GLuint shader)
691{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000692 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000693
694 try
695 {
696 gl::Context *context = gl::getContext();
697
698 if (context)
699 {
700 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000701
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000702 if (!shaderObject)
703 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000704 if (context->getProgram(shader))
705 {
706 return error(GL_INVALID_OPERATION);
707 }
708 else
709 {
710 return error(GL_INVALID_VALUE);
711 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000712 }
713
714 shaderObject->compile();
715 }
716 }
717 catch(std::bad_alloc&)
718 {
719 return error(GL_OUT_OF_MEMORY);
720 }
721}
722
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000723void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
724 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000725{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000726 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000727 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000728 target, level, internalformat, width, height, border, imageSize, data);
729
730 try
731 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000732 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
733 {
734 return error(GL_INVALID_ENUM);
735 }
736
737 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000738 {
739 return error(GL_INVALID_VALUE);
740 }
741
daniel@transgaming.com41430492010-03-11 20:36:18 +0000742 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
743 {
744 return error(GL_INVALID_VALUE);
745 }
746
747 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748 }
749 catch(std::bad_alloc&)
750 {
751 return error(GL_OUT_OF_MEMORY);
752 }
753}
754
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000755void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
756 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000757{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000758 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
759 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000760 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000761 target, level, xoffset, yoffset, width, height, format, imageSize, data);
762
763 try
764 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000765 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
766 {
767 return error(GL_INVALID_ENUM);
768 }
769
770 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000771 {
772 return error(GL_INVALID_VALUE);
773 }
774
daniel@transgaming.com41430492010-03-11 20:36:18 +0000775 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
776 {
777 return error(GL_INVALID_VALUE);
778 }
779
780 if (xoffset != 0 || yoffset != 0)
781 {
782 return error(GL_INVALID_OPERATION);
783 }
784
785 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000786 }
787 catch(std::bad_alloc&)
788 {
789 return error(GL_OUT_OF_MEMORY);
790 }
791}
792
793void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
794{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000795 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
796 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000797 target, level, internalformat, x, y, width, height, border);
798
799 try
800 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000801 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000802 {
803 return error(GL_INVALID_VALUE);
804 }
805
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000806 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
807 {
808 return error(GL_INVALID_VALUE);
809 }
810
811 switch (target)
812 {
813 case GL_TEXTURE_2D:
814 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
815 {
816 return error(GL_INVALID_VALUE);
817 }
818 break;
819 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
820 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
821 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
822 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
823 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
824 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
825 if (!gl::isPow2(width) || !gl::isPow2(height))
826 {
827 return error(GL_INVALID_VALUE);
828 }
829
830 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
831 {
832 return error(GL_INVALID_VALUE);
833 }
834 break;
835 default:
836 return error(GL_INVALID_ENUM);
837 }
838
839 switch (internalformat)
840 {
841 case GL_ALPHA:
842 case GL_LUMINANCE:
843 case GL_LUMINANCE_ALPHA:
844 case GL_RGB:
845 case GL_RGBA:
846 break;
847 default:
848 return error(GL_INVALID_VALUE);
849 }
850
851 if (border != 0)
852 {
853 return error(GL_INVALID_VALUE);
854 }
855
856 gl::Context *context = gl::getContext();
857
858 if (context)
859 {
860 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
861
862 if (target == GL_TEXTURE_2D)
863 {
864 gl::Texture2D *texture = context->getTexture2D();
865
866 if (!texture)
867 {
868 return error(GL_INVALID_OPERATION);
869 }
870
871 texture->copyImage(level, internalformat, x, y, width, height, source);
872 }
873 else if (es2dx::IsCubemapTextureTarget(target))
874 {
875 gl::TextureCubeMap *texture = context->getTextureCubeMap();
876
877 if (!texture)
878 {
879 return error(GL_INVALID_OPERATION);
880 }
881
882 texture->copyImage(target, level, internalformat, x, y, width, height, source);
883 }
884 else
885 {
886 UNREACHABLE();
887 }
888 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000889 }
890 catch(std::bad_alloc&)
891 {
892 return error(GL_OUT_OF_MEMORY);
893 }
894}
895
896void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
897{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000898 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
899 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000900 target, level, xoffset, yoffset, x, y, width, height);
901
902 try
903 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000904 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
905 {
906 return error(GL_INVALID_ENUM);
907 }
908
909 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000910 {
911 return error(GL_INVALID_VALUE);
912 }
913
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000914 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
915 {
916 return error(GL_INVALID_VALUE);
917 }
918
919 if (width == 0 || height == 0)
920 {
921 return;
922 }
923
924 gl::Context *context = gl::getContext();
925
926 if (context)
927 {
928 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
929
930 if (target == GL_TEXTURE_2D)
931 {
932 gl::Texture2D *texture = context->getTexture2D();
933
934 if (!texture)
935 {
936 return error(GL_INVALID_OPERATION);
937 }
938
939 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
940 }
941 else if (es2dx::IsCubemapTextureTarget(target))
942 {
943 gl::TextureCubeMap *texture = context->getTextureCubeMap();
944
945 if (!texture)
946 {
947 return error(GL_INVALID_OPERATION);
948 }
949
950 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
951 }
952 else
953 {
954 UNREACHABLE();
955 }
956 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000957 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000958
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000959 catch(std::bad_alloc&)
960 {
961 return error(GL_OUT_OF_MEMORY);
962 }
963}
964
965GLuint __stdcall glCreateProgram(void)
966{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000967 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000968
969 try
970 {
971 gl::Context *context = gl::getContext();
972
973 if (context)
974 {
975 return context->createProgram();
976 }
977 }
978 catch(std::bad_alloc&)
979 {
980 return error(GL_OUT_OF_MEMORY, 0);
981 }
982
983 return 0;
984}
985
986GLuint __stdcall glCreateShader(GLenum type)
987{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000988 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000989
990 try
991 {
992 gl::Context *context = gl::getContext();
993
994 if (context)
995 {
996 switch (type)
997 {
998 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000999 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001000 return context->createShader(type);
1001 default:
1002 return error(GL_INVALID_ENUM, 0);
1003 }
1004 }
1005 }
1006 catch(std::bad_alloc&)
1007 {
1008 return error(GL_OUT_OF_MEMORY, 0);
1009 }
1010
1011 return 0;
1012}
1013
1014void __stdcall glCullFace(GLenum mode)
1015{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001016 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001017
1018 try
1019 {
1020 switch (mode)
1021 {
1022 case GL_FRONT:
1023 case GL_BACK:
1024 case GL_FRONT_AND_BACK:
1025 {
1026 gl::Context *context = gl::getContext();
1027
1028 if (context)
1029 {
1030 context->cullMode = mode;
1031 }
1032 }
1033 break;
1034 default:
1035 return error(GL_INVALID_ENUM);
1036 }
1037 }
1038 catch(std::bad_alloc&)
1039 {
1040 return error(GL_OUT_OF_MEMORY);
1041 }
1042}
1043
1044void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1045{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001046 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001047
1048 try
1049 {
1050 if (n < 0)
1051 {
1052 return error(GL_INVALID_VALUE);
1053 }
1054
1055 gl::Context *context = gl::getContext();
1056
1057 if (context)
1058 {
1059 for (int i = 0; i < n; i++)
1060 {
1061 context->deleteBuffer(buffers[i]);
1062 }
1063 }
1064 }
1065 catch(std::bad_alloc&)
1066 {
1067 return error(GL_OUT_OF_MEMORY);
1068 }
1069}
1070
1071void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1072{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001073 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001074
1075 try
1076 {
1077 if (n < 0)
1078 {
1079 return error(GL_INVALID_VALUE);
1080 }
1081
1082 gl::Context *context = gl::getContext();
1083
1084 if (context)
1085 {
1086 for (int i = 0; i < n; i++)
1087 {
1088 if (framebuffers[i] != 0)
1089 {
1090 context->deleteFramebuffer(framebuffers[i]);
1091 }
1092 }
1093 }
1094 }
1095 catch(std::bad_alloc&)
1096 {
1097 return error(GL_OUT_OF_MEMORY);
1098 }
1099}
1100
1101void __stdcall glDeleteProgram(GLuint program)
1102{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001103 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001104
1105 try
1106 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001107 if (program == 0)
1108 {
1109 return;
1110 }
1111
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001112 gl::Context *context = gl::getContext();
1113
1114 if (context)
1115 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001116 if (!context->getProgram(program))
1117 {
1118 if(context->getShader(program))
1119 {
1120 return error(GL_INVALID_OPERATION);
1121 }
1122 else
1123 {
1124 return error(GL_INVALID_VALUE);
1125 }
1126 }
1127
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001128 context->deleteProgram(program);
1129 }
1130 }
1131 catch(std::bad_alloc&)
1132 {
1133 return error(GL_OUT_OF_MEMORY);
1134 }
1135}
1136
1137void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1138{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001139 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001140
1141 try
1142 {
1143 if (n < 0)
1144 {
1145 return error(GL_INVALID_VALUE);
1146 }
1147
1148 gl::Context *context = gl::getContext();
1149
1150 if (context)
1151 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001152 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001153 {
1154 context->deleteRenderbuffer(renderbuffers[i]);
1155 }
1156 }
1157 }
1158 catch(std::bad_alloc&)
1159 {
1160 return error(GL_OUT_OF_MEMORY);
1161 }
1162}
1163
1164void __stdcall glDeleteShader(GLuint shader)
1165{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001166 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001167
1168 try
1169 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001170 if (shader == 0)
1171 {
1172 return;
1173 }
1174
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001175 gl::Context *context = gl::getContext();
1176
1177 if (context)
1178 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001179 if (!context->getShader(shader))
1180 {
1181 if(context->getProgram(shader))
1182 {
1183 return error(GL_INVALID_OPERATION);
1184 }
1185 else
1186 {
1187 return error(GL_INVALID_VALUE);
1188 }
1189 }
1190
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001191 context->deleteShader(shader);
1192 }
1193 }
1194 catch(std::bad_alloc&)
1195 {
1196 return error(GL_OUT_OF_MEMORY);
1197 }
1198}
1199
1200void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1201{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001202 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001203
1204 try
1205 {
1206 if (n < 0)
1207 {
1208 return error(GL_INVALID_VALUE);
1209 }
1210
1211 gl::Context *context = gl::getContext();
1212
1213 if (context)
1214 {
1215 for (int i = 0; i < n; i++)
1216 {
1217 if (textures[i] != 0)
1218 {
1219 context->deleteTexture(textures[i]);
1220 }
1221 }
1222 }
1223 }
1224 catch(std::bad_alloc&)
1225 {
1226 return error(GL_OUT_OF_MEMORY);
1227 }
1228}
1229
1230void __stdcall glDepthFunc(GLenum func)
1231{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001232 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001233
1234 try
1235 {
1236 switch (func)
1237 {
1238 case GL_NEVER:
1239 case GL_ALWAYS:
1240 case GL_LESS:
1241 case GL_LEQUAL:
1242 case GL_EQUAL:
1243 case GL_GREATER:
1244 case GL_GEQUAL:
1245 case GL_NOTEQUAL:
1246 break;
1247 default:
1248 return error(GL_INVALID_ENUM);
1249 }
1250
1251 gl::Context *context = gl::getContext();
1252
1253 if (context)
1254 {
1255 context->depthFunc = func;
1256 }
1257 }
1258 catch(std::bad_alloc&)
1259 {
1260 return error(GL_OUT_OF_MEMORY);
1261 }
1262}
1263
1264void __stdcall glDepthMask(GLboolean flag)
1265{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001266 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001267
1268 try
1269 {
1270 gl::Context *context = gl::getContext();
1271
1272 if (context)
1273 {
1274 context->depthMask = flag != GL_FALSE;
1275 }
1276 }
1277 catch(std::bad_alloc&)
1278 {
1279 return error(GL_OUT_OF_MEMORY);
1280 }
1281}
1282
1283void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1284{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001285 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001286
1287 try
1288 {
1289 gl::Context *context = gl::getContext();
1290
1291 if (context)
1292 {
1293 context->zNear = zNear;
1294 context->zFar = zFar;
1295 }
1296 }
1297 catch(std::bad_alloc&)
1298 {
1299 return error(GL_OUT_OF_MEMORY);
1300 }
1301}
1302
1303void __stdcall glDetachShader(GLuint program, GLuint shader)
1304{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001305 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001306
1307 try
1308 {
1309 gl::Context *context = gl::getContext();
1310
1311 if (context)
1312 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001313
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001314 gl::Program *programObject = context->getProgram(program);
1315 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001316
1317 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001318 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001319 gl::Shader *shaderByProgramHandle;
1320 shaderByProgramHandle = context->getShader(program);
1321 if (!shaderByProgramHandle)
1322 {
1323 return error(GL_INVALID_VALUE);
1324 }
1325 else
1326 {
1327 return error(GL_INVALID_OPERATION);
1328 }
1329 }
1330
1331 if (!shaderObject)
1332 {
1333 gl::Program *programByShaderHandle = context->getProgram(shader);
1334 if (!programByShaderHandle)
1335 {
1336 return error(GL_INVALID_VALUE);
1337 }
1338 else
1339 {
1340 return error(GL_INVALID_OPERATION);
1341 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001342 }
1343
1344 if (!programObject->detachShader(shaderObject))
1345 {
1346 return error(GL_INVALID_OPERATION);
1347 }
1348
1349 if (shaderObject->isDeletable())
1350 {
1351 context->deleteShader(shader);
1352 }
1353 }
1354 }
1355 catch(std::bad_alloc&)
1356 {
1357 return error(GL_OUT_OF_MEMORY);
1358 }
1359}
1360
1361void __stdcall glDisable(GLenum cap)
1362{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001363 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001364
1365 try
1366 {
1367 gl::Context *context = gl::getContext();
1368
1369 if (context)
1370 {
1371 switch (cap)
1372 {
1373 case GL_CULL_FACE: context->cullFace = false; break;
1374 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1375 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1376 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1377 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1378 case GL_STENCIL_TEST: context->stencilTest = false; break;
1379 case GL_DEPTH_TEST: context->depthTest = false; break;
1380 case GL_BLEND: context->blend = false; break;
1381 case GL_DITHER: context->dither = false; break;
1382 default:
1383 return error(GL_INVALID_ENUM);
1384 }
1385 }
1386 }
1387 catch(std::bad_alloc&)
1388 {
1389 return error(GL_OUT_OF_MEMORY);
1390 }
1391}
1392
1393void __stdcall glDisableVertexAttribArray(GLuint index)
1394{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001395 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001396
1397 try
1398 {
1399 if (index >= gl::MAX_VERTEX_ATTRIBS)
1400 {
1401 return error(GL_INVALID_VALUE);
1402 }
1403
1404 gl::Context *context = gl::getContext();
1405
1406 if (context)
1407 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001408 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001409 }
1410 }
1411 catch(std::bad_alloc&)
1412 {
1413 return error(GL_OUT_OF_MEMORY);
1414 }
1415}
1416
1417void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1418{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001419 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001420
1421 try
1422 {
1423 if (count < 0 || first < 0)
1424 {
1425 return error(GL_INVALID_VALUE);
1426 }
1427
1428 gl::Context *context = gl::getContext();
1429
1430 if (context)
1431 {
1432 context->drawArrays(mode, first, count);
1433 }
1434 }
1435 catch(std::bad_alloc&)
1436 {
1437 return error(GL_OUT_OF_MEMORY);
1438 }
1439}
1440
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001441void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001442{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001443 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001444 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001445
1446 try
1447 {
1448 if (count < 0)
1449 {
1450 return error(GL_INVALID_VALUE);
1451 }
1452
1453 switch (type)
1454 {
1455 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001456 case GL_UNSIGNED_SHORT:
1457 break;
1458 default:
1459 return error(GL_INVALID_ENUM);
1460 }
1461
1462 gl::Context *context = gl::getContext();
1463
1464 if (context)
1465 {
1466 context->drawElements(mode, count, type, indices);
1467 }
1468 }
1469 catch(std::bad_alloc&)
1470 {
1471 return error(GL_OUT_OF_MEMORY);
1472 }
1473}
1474
1475void __stdcall glEnable(GLenum cap)
1476{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001477 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001478
1479 try
1480 {
1481 gl::Context *context = gl::getContext();
1482
1483 if (context)
1484 {
1485 switch (cap)
1486 {
1487 case GL_CULL_FACE: context->cullFace = true; break;
1488 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1489 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1490 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1491 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1492 case GL_STENCIL_TEST: context->stencilTest = true; break;
1493 case GL_DEPTH_TEST: context->depthTest = true; break;
1494 case GL_BLEND: context->blend = true; break;
1495 case GL_DITHER: context->dither = true; break;
1496 default:
1497 return error(GL_INVALID_ENUM);
1498 }
1499 }
1500 }
1501 catch(std::bad_alloc&)
1502 {
1503 return error(GL_OUT_OF_MEMORY);
1504 }
1505}
1506
1507void __stdcall glEnableVertexAttribArray(GLuint index)
1508{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001509 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001510
1511 try
1512 {
1513 if (index >= gl::MAX_VERTEX_ATTRIBS)
1514 {
1515 return error(GL_INVALID_VALUE);
1516 }
1517
1518 gl::Context *context = gl::getContext();
1519
1520 if (context)
1521 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001522 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001523 }
1524 }
1525 catch(std::bad_alloc&)
1526 {
1527 return error(GL_OUT_OF_MEMORY);
1528 }
1529}
1530
1531void __stdcall glFinish(void)
1532{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001533 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001534
1535 try
1536 {
1537 gl::Context *context = gl::getContext();
1538
1539 if (context)
1540 {
1541 context->finish();
1542 }
1543 }
1544 catch(std::bad_alloc&)
1545 {
1546 return error(GL_OUT_OF_MEMORY);
1547 }
1548}
1549
1550void __stdcall glFlush(void)
1551{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001552 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001553
1554 try
1555 {
1556 gl::Context *context = gl::getContext();
1557
1558 if (context)
1559 {
1560 context->flush();
1561 }
1562 }
1563 catch(std::bad_alloc&)
1564 {
1565 return error(GL_OUT_OF_MEMORY);
1566 }
1567}
1568
1569void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1570{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001571 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1572 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001573
1574 try
1575 {
1576 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1577 {
1578 return error(GL_INVALID_ENUM);
1579 }
1580
1581 gl::Context *context = gl::getContext();
1582
1583 if (context)
1584 {
1585 gl::Framebuffer *framebuffer = context->getFramebuffer();
1586
1587 if (context->framebuffer == 0 || !framebuffer)
1588 {
1589 return error(GL_INVALID_OPERATION);
1590 }
1591
1592 switch (attachment)
1593 {
1594 case GL_COLOR_ATTACHMENT0:
1595 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1596 break;
1597 case GL_DEPTH_ATTACHMENT:
1598 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1599 break;
1600 case GL_STENCIL_ATTACHMENT:
1601 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1602 break;
1603 default:
1604 return error(GL_INVALID_ENUM);
1605 }
1606 }
1607 }
1608 catch(std::bad_alloc&)
1609 {
1610 return error(GL_OUT_OF_MEMORY);
1611 }
1612}
1613
1614void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1615{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001616 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1617 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001618
1619 try
1620 {
1621 if (target != GL_FRAMEBUFFER)
1622 {
1623 return error(GL_INVALID_ENUM);
1624 }
1625
1626 switch (attachment)
1627 {
1628 case GL_COLOR_ATTACHMENT0:
1629 break;
1630 default:
1631 return error(GL_INVALID_ENUM);
1632 }
1633
1634 gl::Context *context = gl::getContext();
1635
1636 if (context)
1637 {
1638 if (texture)
1639 {
1640 switch (textarget)
1641 {
1642 case GL_TEXTURE_2D:
1643 if (!context->getTexture2D())
1644 {
1645 return error(GL_INVALID_OPERATION);
1646 }
1647 break;
1648 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1649 UNIMPLEMENTED(); // FIXME
1650 break;
1651 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1652 UNIMPLEMENTED(); // FIXME
1653 break;
1654 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1655 UNIMPLEMENTED(); // FIXME
1656 break;
1657 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1658 UNIMPLEMENTED(); // FIXME
1659 break;
1660 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1661 UNIMPLEMENTED(); // FIXME
1662 break;
1663 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1664 UNIMPLEMENTED(); // FIXME
1665 break;
1666 default:
1667 return error(GL_INVALID_ENUM);
1668 }
1669
1670 if (level != 0)
1671 {
1672 return error(GL_INVALID_VALUE);
1673 }
1674 }
1675
1676 gl::Framebuffer *framebuffer = context->getFramebuffer();
1677
1678 if (context->framebuffer == 0 || !framebuffer)
1679 {
1680 return error(GL_INVALID_OPERATION);
1681 }
1682
1683 framebuffer->setColorbuffer(GL_TEXTURE, texture);
1684 }
1685 }
1686 catch(std::bad_alloc&)
1687 {
1688 return error(GL_OUT_OF_MEMORY);
1689 }
1690}
1691
1692void __stdcall glFrontFace(GLenum mode)
1693{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001694 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001695
1696 try
1697 {
1698 switch (mode)
1699 {
1700 case GL_CW:
1701 case GL_CCW:
1702 {
1703 gl::Context *context = gl::getContext();
1704
1705 if (context)
1706 {
1707 context->frontFace = mode;
1708 }
1709 }
1710 break;
1711 default:
1712 return error(GL_INVALID_ENUM);
1713 }
1714 }
1715 catch(std::bad_alloc&)
1716 {
1717 return error(GL_OUT_OF_MEMORY);
1718 }
1719}
1720
1721void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1722{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001723 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001724
1725 try
1726 {
1727 if (n < 0)
1728 {
1729 return error(GL_INVALID_VALUE);
1730 }
1731
1732 gl::Context *context = gl::getContext();
1733
1734 if (context)
1735 {
1736 for (int i = 0; i < n; i++)
1737 {
1738 buffers[i] = context->createBuffer();
1739 }
1740 }
1741 }
1742 catch(std::bad_alloc&)
1743 {
1744 return error(GL_OUT_OF_MEMORY);
1745 }
1746}
1747
1748void __stdcall glGenerateMipmap(GLenum target)
1749{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001750 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001751
1752 try
1753 {
1754 UNIMPLEMENTED(); // FIXME
1755 }
1756 catch(std::bad_alloc&)
1757 {
1758 return error(GL_OUT_OF_MEMORY);
1759 }
1760}
1761
1762void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1763{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001764 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001765
1766 try
1767 {
1768 if (n < 0)
1769 {
1770 return error(GL_INVALID_VALUE);
1771 }
1772
1773 gl::Context *context = gl::getContext();
1774
1775 if (context)
1776 {
1777 for (int i = 0; i < n; i++)
1778 {
1779 framebuffers[i] = context->createFramebuffer();
1780 }
1781 }
1782 }
1783 catch(std::bad_alloc&)
1784 {
1785 return error(GL_OUT_OF_MEMORY);
1786 }
1787}
1788
1789void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1790{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001791 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001792
1793 try
1794 {
1795 if (n < 0)
1796 {
1797 return error(GL_INVALID_VALUE);
1798 }
1799
1800 gl::Context *context = gl::getContext();
1801
1802 if (context)
1803 {
1804 for (int i = 0; i < n; i++)
1805 {
1806 renderbuffers[i] = context->createRenderbuffer();
1807 }
1808 }
1809 }
1810 catch(std::bad_alloc&)
1811 {
1812 return error(GL_OUT_OF_MEMORY);
1813 }
1814}
1815
1816void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1817{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001818 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001819
1820 try
1821 {
1822 if (n < 0)
1823 {
1824 return error(GL_INVALID_VALUE);
1825 }
1826
1827 gl::Context *context = gl::getContext();
1828
1829 if (context)
1830 {
1831 for (int i = 0; i < n; i++)
1832 {
1833 textures[i] = context->createTexture();
1834 }
1835 }
1836 }
1837 catch(std::bad_alloc&)
1838 {
1839 return error(GL_OUT_OF_MEMORY);
1840 }
1841}
1842
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001843void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001844{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001845 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001846 "GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001847 program, index, bufsize, length, size, type, name);
1848
1849 try
1850 {
1851 if (bufsize < 0)
1852 {
1853 return error(GL_INVALID_VALUE);
1854 }
1855
1856 UNIMPLEMENTED(); // FIXME
1857 }
1858 catch(std::bad_alloc&)
1859 {
1860 return error(GL_OUT_OF_MEMORY);
1861 }
1862}
1863
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001864void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001865{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001866 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001867 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001868 program, index, bufsize, length, size, type, name);
1869
1870 try
1871 {
1872 if (bufsize < 0)
1873 {
1874 return error(GL_INVALID_VALUE);
1875 }
1876
1877 UNIMPLEMENTED(); // FIXME
1878 }
1879 catch(std::bad_alloc&)
1880 {
1881 return error(GL_OUT_OF_MEMORY);
1882 }
1883}
1884
1885void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1886{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001887 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1888 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001889
1890 try
1891 {
1892 if (maxcount < 0)
1893 {
1894 return error(GL_INVALID_VALUE);
1895 }
1896
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001897 gl::Context *context = gl::getContext();
1898
1899 if (context)
1900 {
1901 gl::Program *programObject = context->getProgram(program);
1902
1903 if (!programObject)
1904 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001905 if (context->getShader(program))
1906 {
1907 return error(GL_INVALID_OPERATION);
1908 }
1909 else
1910 {
1911 return error(GL_INVALID_VALUE);
1912 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001913 }
1914
1915 return programObject->getAttachedShaders(maxcount, count, shaders);
1916 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001917 }
1918 catch(std::bad_alloc&)
1919 {
1920 return error(GL_OUT_OF_MEMORY);
1921 }
1922}
1923
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001924int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001925{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001926 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001927
1928 try
1929 {
1930 gl::Context *context = gl::getContext();
1931
1932 if (context)
1933 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001934
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001935 gl::Program *programObject = context->getProgram(program);
1936
1937 if (!programObject)
1938 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001939 if (context->getShader(program))
1940 {
1941 return error(GL_INVALID_OPERATION, -1);
1942 }
1943 else
1944 {
1945 return error(GL_INVALID_VALUE, -1);
1946 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001947 }
1948
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00001949 if (!programObject->isLinked())
1950 {
1951 return error(GL_INVALID_OPERATION, -1);
1952 }
1953
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001954 return programObject->getAttributeLocation(name);
1955 }
1956 }
1957 catch(std::bad_alloc&)
1958 {
1959 return error(GL_OUT_OF_MEMORY, -1);
1960 }
1961
1962 return -1;
1963}
1964
1965void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1966{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001967 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001968
1969 try
1970 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001971 gl::Context *context = gl::getContext();
1972
1973 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001974 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001975 if (!(context->getBooleanv(pname, params)))
1976 {
1977 GLenum nativeType;
1978 unsigned int numParams = 0;
1979 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1980 return error(GL_INVALID_ENUM);
1981
1982 if (numParams == 0)
1983 return; // it is known that the pname is valid, but there are no parameters to return
1984
1985 if (nativeType == GL_FLOAT)
1986 {
1987 GLfloat *floatParams = NULL;
1988 floatParams = new GLfloat[numParams];
1989
1990 context->getFloatv(pname, floatParams);
1991
1992 for (unsigned int i = 0; i < numParams; ++i)
1993 {
1994 if (floatParams[i] == 0.0f)
1995 params[i] = GL_FALSE;
1996 else
1997 params[i] = GL_TRUE;
1998 }
1999
2000 delete [] floatParams;
2001 }
2002 else if (nativeType == GL_INT)
2003 {
2004 GLint *intParams = NULL;
2005 intParams = new GLint[numParams];
2006
2007 context->getIntegerv(pname, intParams);
2008
2009 for (unsigned int i = 0; i < numParams; ++i)
2010 {
2011 if (intParams[i] == 0)
2012 params[i] = GL_FALSE;
2013 else
2014 params[i] = GL_TRUE;
2015 }
2016
2017 delete [] intParams;
2018 }
2019 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002020 }
2021 }
2022 catch(std::bad_alloc&)
2023 {
2024 return error(GL_OUT_OF_MEMORY);
2025 }
2026}
2027
2028void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2029{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002030 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002031
2032 try
2033 {
2034 UNIMPLEMENTED(); // FIXME
2035 }
2036 catch(std::bad_alloc&)
2037 {
2038 return error(GL_OUT_OF_MEMORY);
2039 }
2040}
2041
2042GLenum __stdcall glGetError(void)
2043{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002044 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002045
2046 gl::Context *context = gl::getContext();
2047
2048 if (context)
2049 {
2050 return context->getError();
2051 }
2052
2053 return GL_NO_ERROR;
2054}
2055
2056void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2057{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002058 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002059
2060 try
2061 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002062 gl::Context *context = gl::getContext();
2063
2064 if (context)
2065 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002066 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002067 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002068 GLenum nativeType;
2069 unsigned int numParams = 0;
2070 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2071 return error(GL_INVALID_ENUM);
2072
2073 if (numParams == 0)
2074 return; // it is known that the pname is valid, but that there are no parameters to return.
2075
2076 if (nativeType == GL_BOOL)
2077 {
2078 GLboolean *boolParams = NULL;
2079 boolParams = new GLboolean[numParams];
2080
2081 context->getBooleanv(pname, boolParams);
2082
2083 for (unsigned int i = 0; i < numParams; ++i)
2084 {
2085 if (boolParams[i] == GL_FALSE)
2086 params[i] = 0.0f;
2087 else
2088 params[i] = 1.0f;
2089 }
2090
2091 delete [] boolParams;
2092 }
2093 else if (nativeType == GL_INT)
2094 {
2095 GLint *intParams = NULL;
2096 intParams = new GLint[numParams];
2097
2098 context->getIntegerv(pname, intParams);
2099
2100 for (unsigned int i = 0; i < numParams; ++i)
2101 {
2102 params[i] = (GLfloat)intParams[i];
2103 }
2104
2105 delete [] intParams;
2106 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002107 }
2108 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002109 }
2110 catch(std::bad_alloc&)
2111 {
2112 return error(GL_OUT_OF_MEMORY);
2113 }
2114}
2115
2116void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2117{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002118 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2119 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002120
2121 try
2122 {
2123 gl::Context *context = gl::getContext();
2124
2125 if (context)
2126 {
2127 if (context->framebuffer == 0)
2128 {
2129 return error(GL_INVALID_OPERATION);
2130 }
2131
2132 UNIMPLEMENTED(); // FIXME
2133 }
2134 }
2135 catch(std::bad_alloc&)
2136 {
2137 return error(GL_OUT_OF_MEMORY);
2138 }
2139}
2140
2141void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2142{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002143 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002144
2145 try
2146 {
2147 gl::Context *context = gl::getContext();
2148
2149 if (context)
2150 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002151 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002152 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002153 GLenum nativeType;
2154 unsigned int numParams = 0;
2155 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2156 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002157
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002158 if (numParams == 0)
2159 return; // it is known that pname is valid, but there are no parameters to return
2160
2161 if (nativeType == GL_BOOL)
2162 {
2163 GLboolean *boolParams = NULL;
2164 boolParams = new GLboolean[numParams];
2165
2166 context->getBooleanv(pname, boolParams);
2167
2168 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002169 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002170 if (boolParams[i] == GL_FALSE)
2171 params[i] = 0;
2172 else
2173 params[i] = 1;
2174 }
2175
2176 delete [] boolParams;
2177 }
2178 else if (nativeType == GL_FLOAT)
2179 {
2180 GLfloat *floatParams = NULL;
2181 floatParams = new GLfloat[numParams];
2182
2183 context->getFloatv(pname, floatParams);
2184
2185 for (unsigned int i = 0; i < numParams; ++i)
2186 {
2187 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002188 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002189 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002190 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002191 else
2192 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002193 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002194
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002195 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002196 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002197 }
2198 }
2199 }
2200 catch(std::bad_alloc&)
2201 {
2202 return error(GL_OUT_OF_MEMORY);
2203 }
2204}
2205
2206void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2207{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002208 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002209
2210 try
2211 {
2212 gl::Context *context = gl::getContext();
2213
2214 if (context)
2215 {
2216 gl::Program *programObject = context->getProgram(program);
2217
2218 if (!programObject)
2219 {
2220 return error(GL_INVALID_VALUE);
2221 }
2222
2223 switch (pname)
2224 {
2225 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002226 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002227 return;
2228 case GL_LINK_STATUS:
2229 *params = programObject->isLinked();
2230 return;
2231 case GL_VALIDATE_STATUS:
2232 UNIMPLEMENTED(); // FIXME
2233 *params = GL_TRUE;
2234 return;
2235 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002236 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002237 return;
2238 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002239 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002240 return;
2241 case GL_ACTIVE_ATTRIBUTES:
2242 UNIMPLEMENTED(); // FIXME
2243 *params = 0;
2244 return;
2245 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2246 UNIMPLEMENTED(); // FIXME
2247 *params = 0;
2248 return;
2249 case GL_ACTIVE_UNIFORMS:
2250 UNIMPLEMENTED(); // FIXME
2251 *params = 0;
2252 return;
2253 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2254 UNIMPLEMENTED(); // FIXME
2255 *params = 0;
2256 return;
2257 default:
2258 return error(GL_INVALID_ENUM);
2259 }
2260 }
2261 }
2262 catch(std::bad_alloc&)
2263 {
2264 return error(GL_OUT_OF_MEMORY);
2265 }
2266}
2267
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002268void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002269{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002270 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002271 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002272
2273 try
2274 {
2275 if (bufsize < 0)
2276 {
2277 return error(GL_INVALID_VALUE);
2278 }
2279
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002280 gl::Context *context = gl::getContext();
2281
2282 if (context)
2283 {
2284 gl::Program *programObject = context->getProgram(program);
2285
2286 if (!programObject)
2287 {
2288 return error(GL_INVALID_VALUE);
2289 }
2290
2291 programObject->getInfoLog(bufsize, length, infolog);
2292 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002293 }
2294 catch(std::bad_alloc&)
2295 {
2296 return error(GL_OUT_OF_MEMORY);
2297 }
2298}
2299
2300void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2301{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002302 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002303
2304 try
2305 {
2306 UNIMPLEMENTED(); // FIXME
2307 }
2308 catch(std::bad_alloc&)
2309 {
2310 return error(GL_OUT_OF_MEMORY);
2311 }
2312}
2313
2314void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2315{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002316 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002317
2318 try
2319 {
2320 gl::Context *context = gl::getContext();
2321
2322 if (context)
2323 {
2324 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002325
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002326 if (!shaderObject)
2327 {
2328 return error(GL_INVALID_VALUE);
2329 }
2330
2331 switch (pname)
2332 {
2333 case GL_SHADER_TYPE:
2334 *params = shaderObject->getType();
2335 return;
2336 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002337 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002338 return;
2339 case GL_COMPILE_STATUS:
2340 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2341 return;
2342 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002343 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002344 return;
2345 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002346 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002347 return;
2348 default:
2349 return error(GL_INVALID_ENUM);
2350 }
2351 }
2352 }
2353 catch(std::bad_alloc&)
2354 {
2355 return error(GL_OUT_OF_MEMORY);
2356 }
2357}
2358
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002359void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002360{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002361 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002362 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002363
2364 try
2365 {
2366 if (bufsize < 0)
2367 {
2368 return error(GL_INVALID_VALUE);
2369 }
2370
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002371 gl::Context *context = gl::getContext();
2372
2373 if (context)
2374 {
2375 gl::Shader *shaderObject = context->getShader(shader);
2376
2377 if (!shaderObject)
2378 {
2379 return error(GL_INVALID_VALUE);
2380 }
2381
2382 shaderObject->getInfoLog(bufsize, length, infolog);
2383 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002384 }
2385 catch(std::bad_alloc&)
2386 {
2387 return error(GL_OUT_OF_MEMORY);
2388 }
2389}
2390
2391void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2392{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002393 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2394 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002395
2396 try
2397 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002398 switch (shadertype)
2399 {
2400 case GL_VERTEX_SHADER:
2401 case GL_FRAGMENT_SHADER:
2402 break;
2403 default:
2404 return error(GL_INVALID_ENUM);
2405 }
2406
2407 switch (precisiontype)
2408 {
2409 case GL_LOW_FLOAT:
2410 case GL_MEDIUM_FLOAT:
2411 case GL_HIGH_FLOAT:
2412 // Assume IEEE 754 precision
2413 range[0] = 127;
2414 range[1] = 127;
2415 precision[0] = 23;
2416 precision[1] = 23;
2417 break;
2418 case GL_LOW_INT:
2419 case GL_MEDIUM_INT:
2420 case GL_HIGH_INT:
2421 // Some (most) hardware only supports single-precision floating-point numbers,
2422 // which can accurately represent integers up to +/-16777216
2423 range[0] = 24;
2424 range[1] = 24;
2425 precision[0] = 0;
2426 precision[1] = 0;
2427 break;
2428 default:
2429 return error(GL_INVALID_ENUM);
2430 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002431 }
2432 catch(std::bad_alloc&)
2433 {
2434 return error(GL_OUT_OF_MEMORY);
2435 }
2436}
2437
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002438void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002439{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002440 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002441 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002442
2443 try
2444 {
2445 if (bufsize < 0)
2446 {
2447 return error(GL_INVALID_VALUE);
2448 }
2449
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002450 gl::Context *context = gl::getContext();
2451
2452 if (context)
2453 {
2454 gl::Shader *shaderObject = context->getShader(shader);
2455
2456 if (!shaderObject)
2457 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002458 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002459 }
2460
2461 shaderObject->getSource(bufsize, length, source);
2462 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002463 }
2464 catch(std::bad_alloc&)
2465 {
2466 return error(GL_OUT_OF_MEMORY);
2467 }
2468}
2469
2470const GLubyte* __stdcall glGetString(GLenum name)
2471{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002472 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002473
2474 try
2475 {
2476 switch (name)
2477 {
2478 case GL_VENDOR:
2479 return (GLubyte*)"TransGaming Inc.";
2480 case GL_RENDERER:
2481 return (GLubyte*)"ANGLE";
2482 case GL_VERSION:
2483 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2484 case GL_SHADING_LANGUAGE_VERSION:
2485 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2486 case GL_EXTENSIONS:
2487 return (GLubyte*)"";
2488 default:
2489 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2490 }
2491 }
2492 catch(std::bad_alloc&)
2493 {
2494 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2495 }
2496
2497 return NULL;
2498}
2499
2500void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2501{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002502 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002503
2504 try
2505 {
2506 UNIMPLEMENTED(); // FIXME
2507 }
2508 catch(std::bad_alloc&)
2509 {
2510 return error(GL_OUT_OF_MEMORY);
2511 }
2512}
2513
2514void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2515{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002516 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002517
2518 try
2519 {
2520 UNIMPLEMENTED(); // FIXME
2521 }
2522 catch(std::bad_alloc&)
2523 {
2524 return error(GL_OUT_OF_MEMORY);
2525 }
2526}
2527
2528void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2529{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002530 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002531
2532 try
2533 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002534 gl::Context *context = gl::getContext();
2535
2536 if (context)
2537 {
2538 if (program == 0)
2539 {
2540 return error(GL_INVALID_VALUE);
2541 }
2542
2543 gl::Program *programObject = context->getProgram(program);
2544
2545 if (!programObject || !programObject->isLinked())
2546 {
2547 return error(GL_INVALID_OPERATION);
2548 }
2549
2550 if (!programObject->getUniformfv(location, params))
2551 {
2552 return error(GL_INVALID_OPERATION);
2553 }
2554 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002555 }
2556 catch(std::bad_alloc&)
2557 {
2558 return error(GL_OUT_OF_MEMORY);
2559 }
2560}
2561
2562void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2563{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002564 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002565
2566 try
2567 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002568 gl::Context *context = gl::getContext();
2569
2570 if (context)
2571 {
2572 if (program == 0)
2573 {
2574 return error(GL_INVALID_VALUE);
2575 }
2576
2577 gl::Program *programObject = context->getProgram(program);
2578
2579 if (!programObject || !programObject->isLinked())
2580 {
2581 return error(GL_INVALID_OPERATION);
2582 }
2583
2584 if (!programObject)
2585 {
2586 return error(GL_INVALID_OPERATION);
2587 }
2588
2589 if (!programObject->getUniformiv(location, params))
2590 {
2591 return error(GL_INVALID_OPERATION);
2592 }
2593 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002594 }
2595 catch(std::bad_alloc&)
2596 {
2597 return error(GL_OUT_OF_MEMORY);
2598 }
2599}
2600
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002601int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002602{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002603 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002604
2605 try
2606 {
2607 gl::Context *context = gl::getContext();
2608
2609 if (strstr(name, "gl_") == name)
2610 {
2611 return -1;
2612 }
2613
2614 if (context)
2615 {
2616 gl::Program *programObject = context->getProgram(program);
2617
2618 if (!programObject)
2619 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002620 if (context->getShader(program))
2621 {
2622 return error(GL_INVALID_OPERATION, -1);
2623 }
2624 else
2625 {
2626 return error(GL_INVALID_VALUE, -1);
2627 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002628 }
2629
2630 if (!programObject->isLinked())
2631 {
2632 return error(GL_INVALID_OPERATION, -1);
2633 }
2634
2635 return programObject->getUniformLocation(name);
2636 }
2637 }
2638 catch(std::bad_alloc&)
2639 {
2640 return error(GL_OUT_OF_MEMORY, -1);
2641 }
2642
2643 return -1;
2644}
2645
2646void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2647{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002648 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002649
2650 try
2651 {
2652 if (index >= gl::MAX_VERTEX_ATTRIBS)
2653 {
2654 return error(GL_INVALID_VALUE);
2655 }
2656
2657 UNIMPLEMENTED(); // FIXME
2658 }
2659 catch(std::bad_alloc&)
2660 {
2661 return error(GL_OUT_OF_MEMORY);
2662 }
2663}
2664
2665void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2666{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002667 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002668
2669 try
2670 {
2671 if (index >= gl::MAX_VERTEX_ATTRIBS)
2672 {
2673 return error(GL_INVALID_VALUE);
2674 }
2675
2676 UNIMPLEMENTED(); // FIXME
2677 }
2678 catch(std::bad_alloc&)
2679 {
2680 return error(GL_OUT_OF_MEMORY);
2681 }
2682}
2683
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002684void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002685{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002686 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002687
2688 try
2689 {
2690 if (index >= gl::MAX_VERTEX_ATTRIBS)
2691 {
2692 return error(GL_INVALID_VALUE);
2693 }
2694
2695 UNIMPLEMENTED(); // FIXME
2696 }
2697 catch(std::bad_alloc&)
2698 {
2699 return error(GL_OUT_OF_MEMORY);
2700 }
2701}
2702
2703void __stdcall glHint(GLenum target, GLenum mode)
2704{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002705 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002706
2707 try
2708 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002709 switch (target)
2710 {
2711 case GL_GENERATE_MIPMAP_HINT:
2712 switch (mode)
2713 {
2714 case GL_FASTEST:
2715 case GL_NICEST:
2716 case GL_DONT_CARE:
2717 break;
2718 default:
2719 return error(GL_INVALID_ENUM);
2720 }
2721 break;
2722 default:
2723 return error(GL_INVALID_ENUM);
2724 }
2725
2726 gl::Context *context = gl::getContext();
2727 if (context)
2728 {
2729 if (target == GL_GENERATE_MIPMAP_HINT)
2730 context->generateMipmapHint = mode;
2731 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002732 }
2733 catch(std::bad_alloc&)
2734 {
2735 return error(GL_OUT_OF_MEMORY);
2736 }
2737}
2738
2739GLboolean __stdcall glIsBuffer(GLuint buffer)
2740{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002741 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002742
2743 try
2744 {
2745 gl::Context *context = gl::getContext();
2746
2747 if (context && buffer)
2748 {
2749 gl::Buffer *bufferObject = context->getBuffer(buffer);
2750
2751 if (bufferObject)
2752 {
2753 return GL_TRUE;
2754 }
2755 }
2756 }
2757 catch(std::bad_alloc&)
2758 {
2759 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2760 }
2761
2762 return GL_FALSE;
2763}
2764
2765GLboolean __stdcall glIsEnabled(GLenum cap)
2766{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002767 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002768
2769 try
2770 {
2771 gl::Context *context = gl::getContext();
2772
2773 if (context)
2774 {
2775 switch (cap)
2776 {
2777 case GL_CULL_FACE: return context->cullFace;
2778 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
2779 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
2780 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
2781 case GL_SCISSOR_TEST: return context->scissorTest;
2782 case GL_STENCIL_TEST: return context->stencilTest;
2783 case GL_DEPTH_TEST: return context->depthTest;
2784 case GL_BLEND: return context->blend;
2785 case GL_DITHER: return context->dither;
2786 default:
2787 return error(GL_INVALID_ENUM, false);
2788 }
2789 }
2790 }
2791 catch(std::bad_alloc&)
2792 {
2793 return error(GL_OUT_OF_MEMORY, false);
2794 }
2795
2796 return false;
2797}
2798
2799GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
2800{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002801 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002802
2803 try
2804 {
2805 gl::Context *context = gl::getContext();
2806
2807 if (context && framebuffer)
2808 {
2809 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2810
2811 if (framebufferObject)
2812 {
2813 return GL_TRUE;
2814 }
2815 }
2816 }
2817 catch(std::bad_alloc&)
2818 {
2819 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2820 }
2821
2822 return GL_FALSE;
2823}
2824
2825GLboolean __stdcall glIsProgram(GLuint program)
2826{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002827 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002828
2829 try
2830 {
2831 gl::Context *context = gl::getContext();
2832
2833 if (context && program)
2834 {
2835 gl::Program *programObject = context->getProgram(program);
2836
2837 if (programObject)
2838 {
2839 return GL_TRUE;
2840 }
2841 }
2842 }
2843 catch(std::bad_alloc&)
2844 {
2845 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2846 }
2847
2848 return GL_FALSE;
2849}
2850
2851GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
2852{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002853 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002854
2855 try
2856 {
2857 gl::Context *context = gl::getContext();
2858
2859 if (context && renderbuffer)
2860 {
2861 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2862
2863 if (renderbufferObject)
2864 {
2865 return GL_TRUE;
2866 }
2867 }
2868 }
2869 catch(std::bad_alloc&)
2870 {
2871 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2872 }
2873
2874 return GL_FALSE;
2875}
2876
2877GLboolean __stdcall glIsShader(GLuint shader)
2878{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002879 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002880
2881 try
2882 {
2883 gl::Context *context = gl::getContext();
2884
2885 if (context && shader)
2886 {
2887 gl::Shader *shaderObject = context->getShader(shader);
2888
2889 if (shaderObject)
2890 {
2891 return GL_TRUE;
2892 }
2893 }
2894 }
2895 catch(std::bad_alloc&)
2896 {
2897 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2898 }
2899
2900 return GL_FALSE;
2901}
2902
2903GLboolean __stdcall glIsTexture(GLuint texture)
2904{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002905 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002906
2907 try
2908 {
2909 gl::Context *context = gl::getContext();
2910
2911 if (context && texture)
2912 {
2913 gl::Texture *textureObject = context->getTexture(texture);
2914
2915 if (textureObject)
2916 {
2917 return GL_TRUE;
2918 }
2919 }
2920 }
2921 catch(std::bad_alloc&)
2922 {
2923 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2924 }
2925
2926 return GL_FALSE;
2927}
2928
2929void __stdcall glLineWidth(GLfloat width)
2930{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002931 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002932
2933 try
2934 {
2935 if (width <= 0.0f)
2936 {
2937 return error(GL_INVALID_VALUE);
2938 }
2939
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002940 gl::Context *context = gl::getContext();
2941
2942 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002943 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002944 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002945 }
2946 }
2947 catch(std::bad_alloc&)
2948 {
2949 return error(GL_OUT_OF_MEMORY);
2950 }
2951}
2952
2953void __stdcall glLinkProgram(GLuint program)
2954{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002955 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002956
2957 try
2958 {
2959 gl::Context *context = gl::getContext();
2960
2961 if (context)
2962 {
2963 gl::Program *programObject = context->getProgram(program);
2964
2965 if (!programObject)
2966 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00002967 if (context->getShader(program))
2968 {
2969 return error(GL_INVALID_OPERATION);
2970 }
2971 else
2972 {
2973 return error(GL_INVALID_VALUE);
2974 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002975 }
2976
2977 programObject->link();
2978 }
2979 }
2980 catch(std::bad_alloc&)
2981 {
2982 return error(GL_OUT_OF_MEMORY);
2983 }
2984}
2985
2986void __stdcall glPixelStorei(GLenum pname, GLint param)
2987{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002988 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002989
2990 try
2991 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002992 gl::Context *context = gl::getContext();
2993
2994 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002995 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002996 switch (pname)
2997 {
2998 case GL_UNPACK_ALIGNMENT:
2999 if (param != 1 && param != 2 && param != 4 && param != 8)
3000 {
3001 return error(GL_INVALID_VALUE);
3002 }
3003
3004 context->unpackAlignment = param;
3005 break;
3006
3007 case GL_PACK_ALIGNMENT:
3008 if (param != 1 && param != 2 && param != 4 && param != 8)
3009 {
3010 return error(GL_INVALID_VALUE);
3011 }
3012
3013 context->packAlignment = param;
3014 break;
3015
3016 default:
3017 return error(GL_INVALID_ENUM);
3018 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003019 }
3020 }
3021 catch(std::bad_alloc&)
3022 {
3023 return error(GL_OUT_OF_MEMORY);
3024 }
3025}
3026
3027void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3028{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003029 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003030
3031 try
3032 {
3033 if (factor != 0.0f || units != 0.0f)
3034 {
3035 UNIMPLEMENTED(); // FIXME
3036 }
3037 }
3038 catch(std::bad_alloc&)
3039 {
3040 return error(GL_OUT_OF_MEMORY);
3041 }
3042}
3043
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003044void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003045{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003046 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003047 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003048 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003049
3050 try
3051 {
3052 if (width < 0 || height < 0)
3053 {
3054 return error(GL_INVALID_VALUE);
3055 }
3056
3057 switch (format)
3058 {
3059 case GL_RGBA:
3060 switch (type)
3061 {
3062 case GL_UNSIGNED_BYTE:
3063 break;
3064 default:
3065 return error(GL_INVALID_OPERATION);
3066 }
3067 break;
3068 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3069 switch (type)
3070 {
3071 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3072 break;
3073 default:
3074 return error(GL_INVALID_OPERATION);
3075 }
3076 break;
3077 default:
3078 return error(GL_INVALID_OPERATION);
3079 }
3080
3081 gl::Context *context = gl::getContext();
3082
3083 if (context)
3084 {
3085 context->readPixels(x, y, width, height, format, type, pixels);
3086 }
3087 }
3088 catch(std::bad_alloc&)
3089 {
3090 return error(GL_OUT_OF_MEMORY);
3091 }
3092}
3093
3094void __stdcall glReleaseShaderCompiler(void)
3095{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003096 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003097
3098 try
3099 {
3100 gl::Shader::releaseCompiler();
3101 }
3102 catch(std::bad_alloc&)
3103 {
3104 return error(GL_OUT_OF_MEMORY);
3105 }
3106}
3107
3108void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3109{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003110 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3111 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003112
3113 try
3114 {
3115 switch (target)
3116 {
3117 case GL_RENDERBUFFER:
3118 break;
3119 default:
3120 return error(GL_INVALID_ENUM);
3121 }
3122
3123 switch (internalformat)
3124 {
3125 case GL_DEPTH_COMPONENT16:
3126 case GL_RGBA4:
3127 case GL_RGB5_A1:
3128 case GL_RGB565:
3129 case GL_STENCIL_INDEX8:
3130 break;
3131 default:
3132 return error(GL_INVALID_ENUM);
3133 }
3134
3135 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3136 {
3137 return error(GL_INVALID_VALUE);
3138 }
3139
3140 gl::Context *context = gl::getContext();
3141
3142 if (context)
3143 {
3144 if (context->framebuffer == 0 || context->renderbuffer == 0)
3145 {
3146 return error(GL_INVALID_OPERATION);
3147 }
3148
3149 switch (internalformat)
3150 {
3151 case GL_DEPTH_COMPONENT16:
3152 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3153 break;
3154 case GL_RGBA4:
3155 case GL_RGB5_A1:
3156 case GL_RGB565:
3157 UNIMPLEMENTED(); // FIXME
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003158 // context->setRenderbuffer(new Colorbuffer(renderTarget));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003159 break;
3160 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003161 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003162 break;
3163 default:
3164 return error(GL_INVALID_ENUM);
3165 }
3166 }
3167 }
3168 catch(std::bad_alloc&)
3169 {
3170 return error(GL_OUT_OF_MEMORY);
3171 }
3172}
3173
3174void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3175{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003176 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003177
3178 try
3179 {
3180 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003181
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003182 if (context)
3183 {
3184 context->sampleCoverageValue = gl::clamp01(value);
3185 context->sampleCoverageInvert = invert;
3186 }
3187 }
3188 catch(std::bad_alloc&)
3189 {
3190 return error(GL_OUT_OF_MEMORY);
3191 }
3192}
3193
3194void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3195{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003196 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 +00003197
3198 try
3199 {
3200 if (width < 0 || height < 0)
3201 {
3202 return error(GL_INVALID_VALUE);
3203 }
3204
3205 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003206
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003207 if (context)
3208 {
3209 context->scissorX = x;
3210 context->scissorY = y;
3211 context->scissorWidth = width;
3212 context->scissorHeight = height;
3213 }
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 glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003222{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003223 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003224 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003225 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003226
3227 try
3228 {
3229 if (n < 0 || length < 0)
3230 {
3231 return error(GL_INVALID_VALUE);
3232 }
3233
3234 UNIMPLEMENTED(); // FIXME
3235 }
3236 catch(std::bad_alloc&)
3237 {
3238 return error(GL_OUT_OF_MEMORY);
3239 }
3240}
3241
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003242void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003243{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003244 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 +00003245 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003246
3247 try
3248 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003249 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003250 {
3251 return error(GL_INVALID_VALUE);
3252 }
3253
3254 gl::Context *context = gl::getContext();
3255
3256 if (context)
3257 {
3258 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003259
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003260 if (!shaderObject)
3261 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003262 if (context->getProgram(shader))
3263 {
3264 return error(GL_INVALID_OPERATION);
3265 }
3266 else
3267 {
3268 return error(GL_INVALID_VALUE);
3269 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003270 }
3271
3272 shaderObject->setSource(count, string, length);
3273 }
3274 }
3275 catch(std::bad_alloc&)
3276 {
3277 return error(GL_OUT_OF_MEMORY);
3278 }
3279}
3280
3281void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3282{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003283 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003284}
3285
3286void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3287{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003288 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 +00003289
3290 try
3291 {
3292 switch (face)
3293 {
3294 case GL_FRONT:
3295 case GL_BACK:
3296 case GL_FRONT_AND_BACK:
3297 break;
3298 default:
3299 return error(GL_INVALID_ENUM);
3300 }
3301
3302 switch (func)
3303 {
3304 case GL_NEVER:
3305 case GL_ALWAYS:
3306 case GL_LESS:
3307 case GL_LEQUAL:
3308 case GL_EQUAL:
3309 case GL_GEQUAL:
3310 case GL_GREATER:
3311 case GL_NOTEQUAL:
3312 break;
3313 default:
3314 return error(GL_INVALID_ENUM);
3315 }
3316
3317 gl::Context *context = gl::getContext();
3318
3319 if (context)
3320 {
3321 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3322 {
3323 context->stencilFunc = func;
3324 context->stencilRef = ref;
3325 context->stencilMask = mask;
3326 }
3327
3328 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3329 {
3330 context->stencilBackFunc = func;
3331 context->stencilBackRef = ref;
3332 context->stencilBackMask = mask;
3333 }
3334 }
3335 }
3336 catch(std::bad_alloc&)
3337 {
3338 return error(GL_OUT_OF_MEMORY);
3339 }
3340}
3341
3342void __stdcall glStencilMask(GLuint mask)
3343{
3344 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3345}
3346
3347void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3348{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003349 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003350
3351 try
3352 {
3353 switch (face)
3354 {
3355 case GL_FRONT:
3356 case GL_BACK:
3357 case GL_FRONT_AND_BACK:
3358 break;
3359 default:
3360 return error(GL_INVALID_ENUM);
3361 }
3362
3363 gl::Context *context = gl::getContext();
3364
3365 if (context)
3366 {
3367 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3368 {
3369 context->stencilWritemask = mask;
3370 }
3371
3372 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3373 {
3374 context->stencilBackWritemask = mask;
3375 }
3376 }
3377 }
3378 catch(std::bad_alloc&)
3379 {
3380 return error(GL_OUT_OF_MEMORY);
3381 }
3382}
3383
3384void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3385{
3386 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3387}
3388
3389void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3390{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003391 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3392 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003393
3394 try
3395 {
3396 switch (face)
3397 {
3398 case GL_FRONT:
3399 case GL_BACK:
3400 case GL_FRONT_AND_BACK:
3401 break;
3402 default:
3403 return error(GL_INVALID_ENUM);
3404 }
3405
3406 switch (fail)
3407 {
3408 case GL_ZERO:
3409 case GL_KEEP:
3410 case GL_REPLACE:
3411 case GL_INCR:
3412 case GL_DECR:
3413 case GL_INVERT:
3414 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003415 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003416 break;
3417 default:
3418 return error(GL_INVALID_ENUM);
3419 }
3420
3421 switch (zfail)
3422 {
3423 case GL_ZERO:
3424 case GL_KEEP:
3425 case GL_REPLACE:
3426 case GL_INCR:
3427 case GL_DECR:
3428 case GL_INVERT:
3429 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003430 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003431 break;
3432 default:
3433 return error(GL_INVALID_ENUM);
3434 }
3435
3436 switch (zpass)
3437 {
3438 case GL_ZERO:
3439 case GL_KEEP:
3440 case GL_REPLACE:
3441 case GL_INCR:
3442 case GL_DECR:
3443 case GL_INVERT:
3444 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003445 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003446 break;
3447 default:
3448 return error(GL_INVALID_ENUM);
3449 }
3450
3451 gl::Context *context = gl::getContext();
3452
3453 if (context)
3454 {
3455 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3456 {
3457 context->stencilFail = fail;
3458 context->stencilPassDepthFail = zfail;
3459 context->stencilPassDepthPass = zpass;
3460 }
3461
3462 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3463 {
3464 context->stencilBackFail = fail;
3465 context->stencilBackPassDepthFail = zfail;
3466 context->stencilBackPassDepthPass = zpass;
3467 }
3468 }
3469 }
3470 catch(std::bad_alloc&)
3471 {
3472 return error(GL_OUT_OF_MEMORY);
3473 }
3474}
3475
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003476void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3477 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003478{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003479 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 +00003480 "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 +00003481 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003482
3483 try
3484 {
3485 if (level < 0 || width < 0 || height < 0)
3486 {
3487 return error(GL_INVALID_VALUE);
3488 }
3489
3490 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3491 {
3492 return error(GL_INVALID_VALUE);
3493 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003494
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003495 switch (target)
3496 {
3497 case GL_TEXTURE_2D:
3498 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3499 {
3500 return error(GL_INVALID_VALUE);
3501 }
3502 break;
3503 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3504 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3505 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3506 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3507 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3508 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3509 if (!gl::isPow2(width) || !gl::isPow2(height))
3510 {
3511 return error(GL_INVALID_VALUE);
3512 }
3513
3514 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3515 {
3516 return error(GL_INVALID_VALUE);
3517 }
3518 break;
3519 default:
3520 return error(GL_INVALID_ENUM);
3521 }
3522
3523 if (internalformat != format)
3524 {
3525 return error(GL_INVALID_OPERATION);
3526 }
3527
3528 switch (internalformat)
3529 {
3530 case GL_ALPHA:
3531 case GL_LUMINANCE:
3532 case GL_LUMINANCE_ALPHA:
3533 switch (type)
3534 {
3535 case GL_UNSIGNED_BYTE:
3536 break;
3537 default:
3538 return error(GL_INVALID_ENUM);
3539 }
3540 break;
3541 case GL_RGB:
3542 switch (type)
3543 {
3544 case GL_UNSIGNED_BYTE:
3545 case GL_UNSIGNED_SHORT_5_6_5:
3546 break;
3547 default:
3548 return error(GL_INVALID_ENUM);
3549 }
3550 break;
3551 case GL_RGBA:
3552 switch (type)
3553 {
3554 case GL_UNSIGNED_BYTE:
3555 case GL_UNSIGNED_SHORT_4_4_4_4:
3556 case GL_UNSIGNED_SHORT_5_5_5_1:
3557 break;
3558 default:
3559 return error(GL_INVALID_ENUM);
3560 }
3561 break;
3562 default:
3563 return error(GL_INVALID_VALUE);
3564 }
3565
3566 if (border != 0)
3567 {
3568 return error(GL_INVALID_VALUE);
3569 }
3570
3571 gl::Context *context = gl::getContext();
3572
3573 if (context)
3574 {
3575 if (target == GL_TEXTURE_2D)
3576 {
3577 gl::Texture2D *texture = context->getTexture2D();
3578
3579 if (!texture)
3580 {
3581 return error(GL_INVALID_OPERATION);
3582 }
3583
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003584 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003585 }
3586 else
3587 {
3588 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3589
3590 if (!texture)
3591 {
3592 return error(GL_INVALID_OPERATION);
3593 }
3594
3595 switch (target)
3596 {
3597 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003598 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003599 break;
3600 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003601 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003602 break;
3603 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003604 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003605 break;
3606 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003607 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003608 break;
3609 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003610 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003611 break;
3612 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003613 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003614 break;
3615 default: UNREACHABLE();
3616 }
3617 }
3618 }
3619 }
3620 catch(std::bad_alloc&)
3621 {
3622 return error(GL_OUT_OF_MEMORY);
3623 }
3624}
3625
3626void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3627{
3628 glTexParameteri(target, pname, (GLint)param);
3629}
3630
3631void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3632{
3633 glTexParameteri(target, pname, (GLint)*params);
3634}
3635
3636void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3637{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003638 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003639
3640 try
3641 {
3642 gl::Context *context = gl::getContext();
3643
3644 if (context)
3645 {
3646 gl::Texture *texture;
3647
3648 switch (target)
3649 {
3650 case GL_TEXTURE_2D:
3651 texture = context->getTexture2D();
3652 break;
3653 case GL_TEXTURE_CUBE_MAP:
3654 texture = context->getTextureCubeMap();
3655 break;
3656 default:
3657 return error(GL_INVALID_ENUM);
3658 }
3659
3660 switch (pname)
3661 {
3662 case GL_TEXTURE_WRAP_S:
3663 if (!texture->setWrapS((GLenum)param))
3664 {
3665 return error(GL_INVALID_ENUM);
3666 }
3667 break;
3668 case GL_TEXTURE_WRAP_T:
3669 if (!texture->setWrapT((GLenum)param))
3670 {
3671 return error(GL_INVALID_ENUM);
3672 }
3673 break;
3674 case GL_TEXTURE_MIN_FILTER:
3675 if (!texture->setMinFilter((GLenum)param))
3676 {
3677 return error(GL_INVALID_ENUM);
3678 }
3679 break;
3680 case GL_TEXTURE_MAG_FILTER:
3681 if (!texture->setMagFilter((GLenum)param))
3682 {
3683 return error(GL_INVALID_ENUM);
3684 }
3685 break;
3686 default:
3687 return error(GL_INVALID_ENUM);
3688 }
3689 }
3690 }
3691 catch(std::bad_alloc&)
3692 {
3693 return error(GL_OUT_OF_MEMORY);
3694 }
3695}
3696
3697void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3698{
3699 glTexParameteri(target, pname, *params);
3700}
3701
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003702void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3703 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003704{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003705 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3706 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003707 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003708 target, level, xoffset, yoffset, width, height, format, type, pixels);
3709
3710 try
3711 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003712 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
3713 {
3714 return error(GL_INVALID_ENUM);
3715 }
3716
3717 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003718 {
3719 return error(GL_INVALID_VALUE);
3720 }
3721
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003722 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
3723 {
3724 return error(GL_INVALID_VALUE);
3725 }
3726
3727 if (!es2dx::CheckTextureFormatType(format, type))
3728 {
3729 return error(GL_INVALID_ENUM);
3730 }
3731
3732 if (width == 0 || height == 0 || pixels == NULL)
3733 {
3734 return;
3735 }
3736
3737 gl::Context *context = gl::getContext();
3738
3739 if (context)
3740 {
3741 if (target == GL_TEXTURE_2D)
3742 {
3743 gl::Texture2D *texture = context->getTexture2D();
3744
3745 if (!texture)
3746 {
3747 return error(GL_INVALID_OPERATION);
3748 }
3749
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003750 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003751 }
3752 else if (es2dx::IsCubemapTextureTarget(target))
3753 {
3754 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3755
3756 if (!texture)
3757 {
3758 return error(GL_INVALID_OPERATION);
3759 }
3760
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003761 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003762 }
3763 else
3764 {
3765 UNREACHABLE();
3766 }
3767 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003768 }
3769 catch(std::bad_alloc&)
3770 {
3771 return error(GL_OUT_OF_MEMORY);
3772 }
3773}
3774
3775void __stdcall glUniform1f(GLint location, GLfloat x)
3776{
3777 glUniform1fv(location, 1, &x);
3778}
3779
3780void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
3781{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003782 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003783
3784 try
3785 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003786 if (count < 0)
3787 {
3788 return error(GL_INVALID_VALUE);
3789 }
3790
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003791 if (location == -1)
3792 {
3793 return;
3794 }
3795
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003796 gl::Context *context = gl::getContext();
3797
3798 if (context)
3799 {
3800 gl::Program *program = context->getCurrentProgram();
3801
3802 if (!program)
3803 {
3804 return error(GL_INVALID_OPERATION);
3805 }
3806
3807 if (!program->setUniform1fv(location, count, v))
3808 {
3809 return error(GL_INVALID_OPERATION);
3810 }
3811 }
3812 }
3813 catch(std::bad_alloc&)
3814 {
3815 return error(GL_OUT_OF_MEMORY);
3816 }
3817}
3818
3819void __stdcall glUniform1i(GLint location, GLint x)
3820{
3821 glUniform1iv(location, 1, &x);
3822}
3823
3824void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
3825{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003826 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003827
3828 try
3829 {
3830 if (count < 0)
3831 {
3832 return error(GL_INVALID_VALUE);
3833 }
3834
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003835 if (location == -1)
3836 {
3837 return;
3838 }
3839
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003840 gl::Context *context = gl::getContext();
3841
3842 if (context)
3843 {
3844 gl::Program *program = context->getCurrentProgram();
3845
3846 if (!program)
3847 {
3848 return error(GL_INVALID_OPERATION);
3849 }
3850
3851 if (!program->setUniform1iv(location, count, v))
3852 {
3853 return error(GL_INVALID_OPERATION);
3854 }
3855 }
3856 }
3857 catch(std::bad_alloc&)
3858 {
3859 return error(GL_OUT_OF_MEMORY);
3860 }
3861}
3862
3863void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
3864{
3865 GLfloat xy[2] = {x, y};
3866
3867 glUniform2fv(location, 1, (GLfloat*)&xy);
3868}
3869
3870void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
3871{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003872 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003873
3874 try
3875 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003876 if (count < 0)
3877 {
3878 return error(GL_INVALID_VALUE);
3879 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003880
3881 if (location == -1)
3882 {
3883 return;
3884 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003885
3886 gl::Context *context = gl::getContext();
3887
3888 if (context)
3889 {
3890 gl::Program *program = context->getCurrentProgram();
3891
3892 if (!program)
3893 {
3894 return error(GL_INVALID_OPERATION);
3895 }
3896
3897 if (!program->setUniform2fv(location, count, v))
3898 {
3899 return error(GL_INVALID_OPERATION);
3900 }
3901 }
3902 }
3903 catch(std::bad_alloc&)
3904 {
3905 return error(GL_OUT_OF_MEMORY);
3906 }
3907}
3908
3909void __stdcall glUniform2i(GLint location, GLint x, GLint y)
3910{
3911 GLint xy[4] = {x, y};
3912
3913 glUniform2iv(location, 1, (GLint*)&xy);
3914}
3915
3916void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
3917{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003918 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003919
3920 try
3921 {
3922 if (count < 0)
3923 {
3924 return error(GL_INVALID_VALUE);
3925 }
3926
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003927 if (location == -1)
3928 {
3929 return;
3930 }
3931
3932 gl::Context *context = gl::getContext();
3933
3934 if (context)
3935 {
3936 gl::Program *program = context->getCurrentProgram();
3937
3938 if (!program)
3939 {
3940 return error(GL_INVALID_OPERATION);
3941 }
3942
3943 if (!program->setUniform2iv(location, count, v))
3944 {
3945 return error(GL_INVALID_OPERATION);
3946 }
3947 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003948 }
3949 catch(std::bad_alloc&)
3950 {
3951 return error(GL_OUT_OF_MEMORY);
3952 }
3953}
3954
3955void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
3956{
3957 GLfloat xyz[3] = {x, y, z};
3958
3959 glUniform3fv(location, 1, (GLfloat*)&xyz);
3960}
3961
3962void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
3963{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003964 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003965
3966 try
3967 {
3968 if (count < 0)
3969 {
3970 return error(GL_INVALID_VALUE);
3971 }
3972
3973 if (location == -1)
3974 {
3975 return;
3976 }
3977
3978 gl::Context *context = gl::getContext();
3979
3980 if (context)
3981 {
3982 gl::Program *program = context->getCurrentProgram();
3983
3984 if (!program)
3985 {
3986 return error(GL_INVALID_OPERATION);
3987 }
3988
3989 if (!program->setUniform3fv(location, count, v))
3990 {
3991 return error(GL_INVALID_OPERATION);
3992 }
3993 }
3994 }
3995 catch(std::bad_alloc&)
3996 {
3997 return error(GL_OUT_OF_MEMORY);
3998 }
3999}
4000
4001void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4002{
4003 GLint xyz[3] = {x, y, z};
4004
4005 glUniform3iv(location, 1, (GLint*)&xyz);
4006}
4007
4008void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4009{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004010 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004011
4012 try
4013 {
4014 if (count < 0)
4015 {
4016 return error(GL_INVALID_VALUE);
4017 }
4018
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004019 if (location == -1)
4020 {
4021 return;
4022 }
4023
4024 gl::Context *context = gl::getContext();
4025
4026 if (context)
4027 {
4028 gl::Program *program = context->getCurrentProgram();
4029
4030 if (!program)
4031 {
4032 return error(GL_INVALID_OPERATION);
4033 }
4034
4035 if (!program->setUniform3iv(location, count, v))
4036 {
4037 return error(GL_INVALID_OPERATION);
4038 }
4039 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004040 }
4041 catch(std::bad_alloc&)
4042 {
4043 return error(GL_OUT_OF_MEMORY);
4044 }
4045}
4046
4047void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4048{
4049 GLfloat xyzw[4] = {x, y, z, w};
4050
4051 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4052}
4053
4054void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4055{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004056 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004057
4058 try
4059 {
4060 if (count < 0)
4061 {
4062 return error(GL_INVALID_VALUE);
4063 }
4064
4065 if (location == -1)
4066 {
4067 return;
4068 }
4069
4070 gl::Context *context = gl::getContext();
4071
4072 if (context)
4073 {
4074 gl::Program *program = context->getCurrentProgram();
4075
4076 if (!program)
4077 {
4078 return error(GL_INVALID_OPERATION);
4079 }
4080
4081 if (!program->setUniform4fv(location, count, v))
4082 {
4083 return error(GL_INVALID_OPERATION);
4084 }
4085 }
4086 }
4087 catch(std::bad_alloc&)
4088 {
4089 return error(GL_OUT_OF_MEMORY);
4090 }
4091}
4092
4093void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4094{
4095 GLint xyzw[4] = {x, y, z, w};
4096
4097 glUniform4iv(location, 1, (GLint*)&xyzw);
4098}
4099
4100void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4101{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004102 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004103
4104 try
4105 {
4106 if (count < 0)
4107 {
4108 return error(GL_INVALID_VALUE);
4109 }
4110
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004111 if (location == -1)
4112 {
4113 return;
4114 }
4115
4116 gl::Context *context = gl::getContext();
4117
4118 if (context)
4119 {
4120 gl::Program *program = context->getCurrentProgram();
4121
4122 if (!program)
4123 {
4124 return error(GL_INVALID_OPERATION);
4125 }
4126
4127 if (!program->setUniform4iv(location, count, v))
4128 {
4129 return error(GL_INVALID_OPERATION);
4130 }
4131 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004132 }
4133 catch(std::bad_alloc&)
4134 {
4135 return error(GL_OUT_OF_MEMORY);
4136 }
4137}
4138
4139void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4140{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004141 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4142 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004143
4144 try
4145 {
4146 if (count < 0 || transpose != GL_FALSE)
4147 {
4148 return error(GL_INVALID_VALUE);
4149 }
4150
4151 if (location == -1)
4152 {
4153 return;
4154 }
4155
4156 gl::Context *context = gl::getContext();
4157
4158 if (context)
4159 {
4160 gl::Program *program = context->getCurrentProgram();
4161
4162 if (!program)
4163 {
4164 return error(GL_INVALID_OPERATION);
4165 }
4166
4167 if (!program->setUniformMatrix2fv(location, count, value))
4168 {
4169 return error(GL_INVALID_OPERATION);
4170 }
4171 }
4172 }
4173 catch(std::bad_alloc&)
4174 {
4175 return error(GL_OUT_OF_MEMORY);
4176 }
4177}
4178
4179void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4180{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004181 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4182 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004183
4184 try
4185 {
4186 if (count < 0 || transpose != GL_FALSE)
4187 {
4188 return error(GL_INVALID_VALUE);
4189 }
4190
4191 if (location == -1)
4192 {
4193 return;
4194 }
4195
4196 gl::Context *context = gl::getContext();
4197
4198 if (context)
4199 {
4200 gl::Program *program = context->getCurrentProgram();
4201
4202 if (!program)
4203 {
4204 return error(GL_INVALID_OPERATION);
4205 }
4206
4207 if (!program->setUniformMatrix3fv(location, count, value))
4208 {
4209 return error(GL_INVALID_OPERATION);
4210 }
4211 }
4212 }
4213 catch(std::bad_alloc&)
4214 {
4215 return error(GL_OUT_OF_MEMORY);
4216 }
4217}
4218
4219void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4220{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004221 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4222 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004223
4224 try
4225 {
4226 if (count < 0 || transpose != GL_FALSE)
4227 {
4228 return error(GL_INVALID_VALUE);
4229 }
4230
4231 if (location == -1)
4232 {
4233 return;
4234 }
4235
4236 gl::Context *context = gl::getContext();
4237
4238 if (context)
4239 {
4240 gl::Program *program = context->getCurrentProgram();
4241
4242 if (!program)
4243 {
4244 return error(GL_INVALID_OPERATION);
4245 }
4246
4247 if (!program->setUniformMatrix4fv(location, count, value))
4248 {
4249 return error(GL_INVALID_OPERATION);
4250 }
4251 }
4252 }
4253 catch(std::bad_alloc&)
4254 {
4255 return error(GL_OUT_OF_MEMORY);
4256 }
4257}
4258
4259void __stdcall glUseProgram(GLuint program)
4260{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004261 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004262
4263 try
4264 {
4265 gl::Context *context = gl::getContext();
4266
4267 if (context)
4268 {
4269 gl::Program *programObject = context->getProgram(program);
4270
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004271 if (!programObject && program != 0)
4272 {
4273 if (context->getShader(program))
4274 {
4275 return error(GL_INVALID_OPERATION);
4276 }
4277 else
4278 {
4279 return error(GL_INVALID_VALUE);
4280 }
4281 }
4282
4283 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004284 {
4285 return error(GL_INVALID_OPERATION);
4286 }
4287
4288 context->useProgram(program);
4289 }
4290 }
4291 catch(std::bad_alloc&)
4292 {
4293 return error(GL_OUT_OF_MEMORY);
4294 }
4295}
4296
4297void __stdcall glValidateProgram(GLuint program)
4298{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004299 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004300
4301 try
4302 {
4303 UNIMPLEMENTED(); // FIXME
4304 }
4305 catch(std::bad_alloc&)
4306 {
4307 return error(GL_OUT_OF_MEMORY);
4308 }
4309}
4310
4311void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4312{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004313 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004314
4315 try
4316 {
4317 if (index >= gl::MAX_VERTEX_ATTRIBS)
4318 {
4319 return error(GL_INVALID_VALUE);
4320 }
4321
4322 UNIMPLEMENTED(); // FIXME
4323 }
4324 catch(std::bad_alloc&)
4325 {
4326 return error(GL_OUT_OF_MEMORY);
4327 }
4328}
4329
4330void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4331{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004332 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004333
4334 try
4335 {
4336 if (index >= gl::MAX_VERTEX_ATTRIBS)
4337 {
4338 return error(GL_INVALID_VALUE);
4339 }
4340
4341 UNIMPLEMENTED(); // FIXME
4342 }
4343 catch(std::bad_alloc&)
4344 {
4345 return error(GL_OUT_OF_MEMORY);
4346 }
4347}
4348
4349void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4350{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004351 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004352
4353 try
4354 {
4355 if (index >= gl::MAX_VERTEX_ATTRIBS)
4356 {
4357 return error(GL_INVALID_VALUE);
4358 }
4359
4360 UNIMPLEMENTED(); // FIXME
4361 }
4362 catch(std::bad_alloc&)
4363 {
4364 return error(GL_OUT_OF_MEMORY);
4365 }
4366}
4367
4368void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4369{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004370 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004371
4372 try
4373 {
4374 if (index >= gl::MAX_VERTEX_ATTRIBS)
4375 {
4376 return error(GL_INVALID_VALUE);
4377 }
4378
4379 UNIMPLEMENTED(); // FIXME
4380 }
4381 catch(std::bad_alloc&)
4382 {
4383 return error(GL_OUT_OF_MEMORY);
4384 }
4385}
4386
4387void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4388{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004389 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 +00004390
4391 try
4392 {
4393 if (index >= gl::MAX_VERTEX_ATTRIBS)
4394 {
4395 return error(GL_INVALID_VALUE);
4396 }
4397
4398 UNIMPLEMENTED(); // FIXME
4399 }
4400 catch(std::bad_alloc&)
4401 {
4402 return error(GL_OUT_OF_MEMORY);
4403 }
4404}
4405
4406void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4407{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004408 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004409
4410 try
4411 {
4412 if (index >= gl::MAX_VERTEX_ATTRIBS)
4413 {
4414 return error(GL_INVALID_VALUE);
4415 }
4416
4417 UNIMPLEMENTED(); // FIXME
4418 }
4419 catch(std::bad_alloc&)
4420 {
4421 return error(GL_OUT_OF_MEMORY);
4422 }
4423}
4424
4425void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4426{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004427 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 +00004428
4429 try
4430 {
4431 if (index >= gl::MAX_VERTEX_ATTRIBS)
4432 {
4433 return error(GL_INVALID_VALUE);
4434 }
4435
4436 UNIMPLEMENTED(); // FIXME
4437 }
4438 catch(std::bad_alloc&)
4439 {
4440 return error(GL_OUT_OF_MEMORY);
4441 }
4442}
4443
4444void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4445{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004446 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004447
4448 try
4449 {
4450 if (index >= gl::MAX_VERTEX_ATTRIBS)
4451 {
4452 return error(GL_INVALID_VALUE);
4453 }
4454
4455 UNIMPLEMENTED(); // FIXME
4456 }
4457 catch(std::bad_alloc&)
4458 {
4459 return error(GL_OUT_OF_MEMORY);
4460 }
4461}
4462
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004463void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004464{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004465 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004466 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004467 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004468
4469 try
4470 {
4471 if (index >= gl::MAX_VERTEX_ATTRIBS)
4472 {
4473 return error(GL_INVALID_VALUE);
4474 }
4475
4476 if (size < 1 || size > 4)
4477 {
4478 return error(GL_INVALID_VALUE);
4479 }
4480
4481 switch (type)
4482 {
4483 case GL_BYTE:
4484 case GL_UNSIGNED_BYTE:
4485 case GL_SHORT:
4486 case GL_UNSIGNED_SHORT:
4487 case GL_FIXED:
4488 case GL_FLOAT:
4489 break;
4490 default:
4491 return error(GL_INVALID_ENUM);
4492 }
4493
4494 if (stride < 0)
4495 {
4496 return error(GL_INVALID_VALUE);
4497 }
4498
4499 gl::Context *context = gl::getContext();
4500
4501 if (context)
4502 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004503 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4504 context->vertexAttribute[index].mSize = size;
4505 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004506 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004507 context->vertexAttribute[index].mStride = stride;
4508 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004509 }
4510 }
4511 catch(std::bad_alloc&)
4512 {
4513 return error(GL_OUT_OF_MEMORY);
4514 }
4515}
4516
4517void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4518{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004519 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 +00004520
4521 try
4522 {
4523 if (width < 0 || height < 0)
4524 {
4525 return error(GL_INVALID_VALUE);
4526 }
4527
4528 gl::Context *context = gl::getContext();
4529
4530 if (context)
4531 {
4532 context->viewportX = x;
4533 context->viewportY = y;
4534 context->viewportWidth = width;
4535 context->viewportHeight = height;
4536 }
4537 }
4538 catch(std::bad_alloc&)
4539 {
4540 return error(GL_OUT_OF_MEMORY);
4541 }
4542}
4543
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004544void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4545 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004546{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004547 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4548 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004549 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004550 target, level, internalformat, width, height, depth, border, format, type, pixels);
4551
4552 try
4553 {
4554 UNIMPLEMENTED(); // FIXME
4555 }
4556 catch(std::bad_alloc&)
4557 {
4558 return error(GL_OUT_OF_MEMORY);
4559 }
4560}
4561}