blob: 06b42f32336d9e79bc5cb44640c7a3939d38acce [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016#include "Context.h"
17#include "main.h"
18#include "Program.h"
19#include "Shader.h"
20#include "Buffer.h"
21#include "Texture.h"
22#include "Renderbuffer.h"
23#include "Framebuffer.h"
24#include "mathutil.h"
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000025#include "common/debug.h"
daniel@transgaming.com00c75962010-03-11 20:36:15 +000026#include "utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027
28extern "C"
29{
30
31void __stdcall glActiveTexture(GLenum texture)
32{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000033 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034
35 try
36 {
37 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
38 {
39 return error(GL_INVALID_ENUM);
40 }
41
42 gl::Context *context = gl::getContext();
43
44 if (context)
45 {
46 context->activeSampler = texture - GL_TEXTURE0;
47 }
48 }
49 catch(std::bad_alloc&)
50 {
51 return error(GL_OUT_OF_MEMORY);
52 }
53}
54
55void __stdcall glAttachShader(GLuint program, GLuint shader)
56{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000057 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000058
59 try
60 {
61 gl::Context *context = gl::getContext();
62
63 if (context)
64 {
65 gl::Program *programObject = context->getProgram(program);
66 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000067
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000068 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000069 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000070 if (context->getShader(program))
71 {
72 return error(GL_INVALID_OPERATION);
73 }
74 else
75 {
76 return error(GL_INVALID_VALUE);
77 }
78 }
79
80 if (!shaderObject)
81 {
82 if (context->getProgram(shader))
83 {
84 return error(GL_INVALID_OPERATION);
85 }
86 else
87 {
88 return error(GL_INVALID_VALUE);
89 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090 }
91
92 if (!programObject->attachShader(shaderObject))
93 {
94 return error(GL_INVALID_OPERATION);
95 }
96 }
97 }
98 catch(std::bad_alloc&)
99 {
100 return error(GL_OUT_OF_MEMORY);
101 }
102}
103
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000104void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000105{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000106 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107
108 try
109 {
110 if (index >= gl::MAX_VERTEX_ATTRIBS)
111 {
112 return error(GL_INVALID_VALUE);
113 }
114
115 gl::Context *context = gl::getContext();
116
117 if (context)
118 {
119 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000120
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000121 if (!programObject)
122 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000123 if (context->getShader(program))
124 {
125 return error(GL_INVALID_OPERATION);
126 }
127 else
128 {
129 return error(GL_INVALID_VALUE);
130 }
131 }
132
133 if (strncmp(name, "gl_", 3) == 0)
134 {
135 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000136 }
137
138 programObject->bindAttributeLocation(index, name);
139 }
140 }
141 catch(std::bad_alloc&)
142 {
143 return error(GL_OUT_OF_MEMORY);
144 }
145}
146
147void __stdcall glBindBuffer(GLenum target, GLuint buffer)
148{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000149 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150
151 try
152 {
153 gl::Context *context = gl::getContext();
154
155 if (context)
156 {
157 switch (target)
158 {
159 case GL_ARRAY_BUFFER:
160 context->bindArrayBuffer(buffer);
161 return;
162 case GL_ELEMENT_ARRAY_BUFFER:
163 context->bindElementArrayBuffer(buffer);
164 return;
165 default:
166 return error(GL_INVALID_ENUM);
167 }
168 }
169 }
170 catch(std::bad_alloc&)
171 {
172 return error(GL_OUT_OF_MEMORY);
173 }
174}
175
176void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
177{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000178 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000179
180 try
181 {
182 if (target != GL_FRAMEBUFFER)
183 {
184 return error(GL_INVALID_ENUM);
185 }
186
187 gl::Context *context = gl::getContext();
188
189 if (context)
190 {
191 context->bindFramebuffer(framebuffer);
192 }
193 }
194 catch(std::bad_alloc&)
195 {
196 return error(GL_OUT_OF_MEMORY);
197 }
198}
199
200void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
201{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000202 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203
204 try
205 {
206 if (target != GL_RENDERBUFFER)
207 {
208 return error(GL_INVALID_ENUM);
209 }
210
211 gl::Context *context = gl::getContext();
212
213 if (context)
214 {
215 context->bindRenderbuffer(renderbuffer);
216 }
217 }
218 catch(std::bad_alloc&)
219 {
220 return error(GL_OUT_OF_MEMORY);
221 }
222}
223
224void __stdcall glBindTexture(GLenum target, GLuint texture)
225{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000226 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227
228 try
229 {
230 gl::Context *context = gl::getContext();
231
232 if (context)
233 {
234 gl::Texture *textureObject = context->getTexture(texture);
235
236 if (textureObject && textureObject->getTarget() != target && texture != 0)
237 {
238 return error(GL_INVALID_OPERATION);
239 }
240
241 switch (target)
242 {
243 case GL_TEXTURE_2D:
244 context->bindTexture2D(texture);
245 return;
246 case GL_TEXTURE_CUBE_MAP:
247 context->bindTextureCubeMap(texture);
248 return;
249 default:
250 return error(GL_INVALID_ENUM);
251 }
252 }
253 }
254 catch(std::bad_alloc&)
255 {
256 return error(GL_OUT_OF_MEMORY);
257 }
258}
259
260void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
261{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000262 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
263 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264
265 try
266 {
267 gl::Context* context = gl::getContext();
268
269 if (context)
270 {
271 context->blendColor.red = gl::clamp01(red);
272 context->blendColor.blue = gl::clamp01(blue);
273 context->blendColor.green = gl::clamp01(green);
274 context->blendColor.alpha = gl::clamp01(alpha);
275 }
276 }
277 catch(std::bad_alloc&)
278 {
279 return error(GL_OUT_OF_MEMORY);
280 }
281}
282
283void __stdcall glBlendEquation(GLenum mode)
284{
285 glBlendEquationSeparate(mode, mode);
286}
287
288void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
289{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000290 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000291
292 try
293 {
294 switch (modeRGB)
295 {
296 case GL_FUNC_ADD:
297 case GL_FUNC_SUBTRACT:
298 case GL_FUNC_REVERSE_SUBTRACT:
299 break;
300 default:
301 return error(GL_INVALID_ENUM);
302 }
303
304 switch (modeAlpha)
305 {
306 case GL_FUNC_ADD:
307 case GL_FUNC_SUBTRACT:
308 case GL_FUNC_REVERSE_SUBTRACT:
309 break;
310 default:
311 return error(GL_INVALID_ENUM);
312 }
313
314 gl::Context *context = gl::getContext();
315
316 if (context)
317 {
318 context->blendEquationRGB = modeRGB;
319 context->blendEquationAlpha = modeAlpha;
320 }
321 }
322 catch(std::bad_alloc&)
323 {
324 return error(GL_OUT_OF_MEMORY);
325 }
326}
327
328void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
329{
330 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
331}
332
333void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
334{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000335 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
336 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000337
338 try
339 {
340 switch (srcRGB)
341 {
342 case GL_ZERO:
343 case GL_ONE:
344 case GL_SRC_COLOR:
345 case GL_ONE_MINUS_SRC_COLOR:
346 case GL_DST_COLOR:
347 case GL_ONE_MINUS_DST_COLOR:
348 case GL_SRC_ALPHA:
349 case GL_ONE_MINUS_SRC_ALPHA:
350 case GL_DST_ALPHA:
351 case GL_ONE_MINUS_DST_ALPHA:
352 case GL_CONSTANT_COLOR:
353 case GL_ONE_MINUS_CONSTANT_COLOR:
354 case GL_CONSTANT_ALPHA:
355 case GL_ONE_MINUS_CONSTANT_ALPHA:
356 case GL_SRC_ALPHA_SATURATE:
357 break;
358 default:
359 return error(GL_INVALID_ENUM);
360 }
361
362 switch (dstRGB)
363 {
364 case GL_ZERO:
365 case GL_ONE:
366 case GL_SRC_COLOR:
367 case GL_ONE_MINUS_SRC_COLOR:
368 case GL_DST_COLOR:
369 case GL_ONE_MINUS_DST_COLOR:
370 case GL_SRC_ALPHA:
371 case GL_ONE_MINUS_SRC_ALPHA:
372 case GL_DST_ALPHA:
373 case GL_ONE_MINUS_DST_ALPHA:
374 case GL_CONSTANT_COLOR:
375 case GL_ONE_MINUS_CONSTANT_COLOR:
376 case GL_CONSTANT_ALPHA:
377 case GL_ONE_MINUS_CONSTANT_ALPHA:
378 break;
379 default:
380 return error(GL_INVALID_ENUM);
381 }
382
383 switch (srcAlpha)
384 {
385 case GL_ZERO:
386 case GL_ONE:
387 case GL_SRC_COLOR:
388 case GL_ONE_MINUS_SRC_COLOR:
389 case GL_DST_COLOR:
390 case GL_ONE_MINUS_DST_COLOR:
391 case GL_SRC_ALPHA:
392 case GL_ONE_MINUS_SRC_ALPHA:
393 case GL_DST_ALPHA:
394 case GL_ONE_MINUS_DST_ALPHA:
395 case GL_CONSTANT_COLOR:
396 case GL_ONE_MINUS_CONSTANT_COLOR:
397 case GL_CONSTANT_ALPHA:
398 case GL_ONE_MINUS_CONSTANT_ALPHA:
399 case GL_SRC_ALPHA_SATURATE:
400 break;
401 default:
402 return error(GL_INVALID_ENUM);
403 }
404
405 switch (dstAlpha)
406 {
407 case GL_ZERO:
408 case GL_ONE:
409 case GL_SRC_COLOR:
410 case GL_ONE_MINUS_SRC_COLOR:
411 case GL_DST_COLOR:
412 case GL_ONE_MINUS_DST_COLOR:
413 case GL_SRC_ALPHA:
414 case GL_ONE_MINUS_SRC_ALPHA:
415 case GL_DST_ALPHA:
416 case GL_ONE_MINUS_DST_ALPHA:
417 case GL_CONSTANT_COLOR:
418 case GL_ONE_MINUS_CONSTANT_COLOR:
419 case GL_CONSTANT_ALPHA:
420 case GL_ONE_MINUS_CONSTANT_ALPHA:
421 break;
422 default:
423 return error(GL_INVALID_ENUM);
424 }
425
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000426 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
427 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
428
429 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
430 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
431
432 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000433 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000434 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
435 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000436 }
437
438 gl::Context *context = gl::getContext();
439
440 if (context)
441 {
442 context->sourceBlendRGB = srcRGB;
443 context->sourceBlendAlpha = srcAlpha;
444 context->destBlendRGB = dstRGB;
445 context->destBlendAlpha = dstAlpha;
446 }
447 }
448 catch(std::bad_alloc&)
449 {
450 return error(GL_OUT_OF_MEMORY);
451 }
452}
453
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000454void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000455{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000456 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000457 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000458
459 try
460 {
461 if (size < 0)
462 {
463 return error(GL_INVALID_VALUE);
464 }
465
466 switch (usage)
467 {
468 case GL_STREAM_DRAW:
469 case GL_STATIC_DRAW:
470 case GL_DYNAMIC_DRAW:
471 break;
472 default:
473 return error(GL_INVALID_ENUM);
474 }
475
476 gl::Context *context = gl::getContext();
477
478 if (context)
479 {
480 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000481
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000482 switch (target)
483 {
484 case GL_ARRAY_BUFFER:
485 buffer = context->getArrayBuffer();
486 break;
487 case GL_ELEMENT_ARRAY_BUFFER:
488 buffer = context->getElementArrayBuffer();
489 break;
490 default:
491 return error(GL_INVALID_ENUM);
492 }
493
494 if (!buffer)
495 {
496 return error(GL_INVALID_OPERATION);
497 }
498
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000499 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000500 }
501 }
502 catch(std::bad_alloc&)
503 {
504 return error(GL_OUT_OF_MEMORY);
505 }
506}
507
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000508void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000509{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000510 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000511 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512
513 try
514 {
515 if (size < 0)
516 {
517 return error(GL_INVALID_VALUE);
518 }
519
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000520 if (data == NULL)
521 {
522 return;
523 }
524
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000525 gl::Context *context = gl::getContext();
526
527 if (context)
528 {
529 gl::Buffer *buffer;
530
531 switch (target)
532 {
533 case GL_ARRAY_BUFFER:
534 buffer = context->getArrayBuffer();
535 break;
536 case GL_ELEMENT_ARRAY_BUFFER:
537 buffer = context->getElementArrayBuffer();
538 break;
539 default:
540 return error(GL_INVALID_ENUM);
541 }
542
543 if (!buffer)
544 {
545 return error(GL_INVALID_OPERATION);
546 }
547
548 GLenum err = buffer->bufferSubData(data, size, offset);
549
550 if (err != GL_NO_ERROR)
551 {
552 return error(err);
553 }
554 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000555 }
556 catch(std::bad_alloc&)
557 {
558 return error(GL_OUT_OF_MEMORY);
559 }
560}
561
562GLenum __stdcall glCheckFramebufferStatus(GLenum target)
563{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000564 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000565
566 try
567 {
568 if (target != GL_FRAMEBUFFER)
569 {
570 return error(GL_INVALID_ENUM, 0);
571 }
572
573 gl::Context *context = gl::getContext();
574
575 if (context)
576 {
577 gl::Framebuffer *framebuffer = context->getFramebuffer();
578
579 return framebuffer->completeness();
580 }
581 }
582 catch(std::bad_alloc&)
583 {
584 return error(GL_OUT_OF_MEMORY, 0);
585 }
586
587 return 0;
588}
589
590void __stdcall glClear(GLbitfield mask)
591{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000592 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000593
594 try
595 {
596 gl::Context *context = gl::getContext();
597
598 if (context)
599 {
600 context->clear(mask);
601 }
602 }
603 catch(std::bad_alloc&)
604 {
605 return error(GL_OUT_OF_MEMORY);
606 }
607}
608
609void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
610{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000611 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
612 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000613
614 try
615 {
616 gl::Context *context = gl::getContext();
617
618 if (context)
619 {
620 context->setClearColor(red, green, blue, alpha);
621 }
622 }
623 catch(std::bad_alloc&)
624 {
625 return error(GL_OUT_OF_MEMORY);
626 }
627}
628
629void __stdcall glClearDepthf(GLclampf depth)
630{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000631 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000632
633 try
634 {
635 gl::Context *context = gl::getContext();
636
637 if (context)
638 {
639 context->setClearDepth(depth);
640 }
641 }
642 catch(std::bad_alloc&)
643 {
644 return error(GL_OUT_OF_MEMORY);
645 }
646}
647
648void __stdcall glClearStencil(GLint s)
649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000650 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000651
652 try
653 {
654 gl::Context *context = gl::getContext();
655
656 if (context)
657 {
658 context->setClearStencil(s);
659 }
660 }
661 catch(std::bad_alloc&)
662 {
663 return error(GL_OUT_OF_MEMORY);
664 }
665}
666
667void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
668{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000669 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
670 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000671
672 try
673 {
674 gl::Context *context = gl::getContext();
675
676 if (context)
677 {
678 context->colorMaskRed = red != GL_FALSE;
679 context->colorMaskGreen = green != GL_FALSE;
680 context->colorMaskBlue = blue != GL_FALSE;
681 context->colorMaskAlpha = alpha != GL_FALSE;
682 }
683 }
684 catch(std::bad_alloc&)
685 {
686 return error(GL_OUT_OF_MEMORY);
687 }
688}
689
690void __stdcall glCompileShader(GLuint shader)
691{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000692 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000693
694 try
695 {
696 gl::Context *context = gl::getContext();
697
698 if (context)
699 {
700 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000701
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000702 if (!shaderObject)
703 {
704 return error(GL_INVALID_VALUE);
705 }
706
707 shaderObject->compile();
708 }
709 }
710 catch(std::bad_alloc&)
711 {
712 return error(GL_OUT_OF_MEMORY);
713 }
714}
715
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000716void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
717 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000718{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000719 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000720 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000721 target, level, internalformat, width, height, border, imageSize, data);
722
723 try
724 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000725 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
726 {
727 return error(GL_INVALID_ENUM);
728 }
729
730 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000731 {
732 return error(GL_INVALID_VALUE);
733 }
734
daniel@transgaming.com41430492010-03-11 20:36:18 +0000735 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
736 {
737 return error(GL_INVALID_VALUE);
738 }
739
740 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000741 }
742 catch(std::bad_alloc&)
743 {
744 return error(GL_OUT_OF_MEMORY);
745 }
746}
747
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000748void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
749 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000750{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000751 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
752 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000753 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000754 target, level, xoffset, yoffset, width, height, format, imageSize, data);
755
756 try
757 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000758 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
759 {
760 return error(GL_INVALID_ENUM);
761 }
762
763 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000764 {
765 return error(GL_INVALID_VALUE);
766 }
767
daniel@transgaming.com41430492010-03-11 20:36:18 +0000768 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
769 {
770 return error(GL_INVALID_VALUE);
771 }
772
773 if (xoffset != 0 || yoffset != 0)
774 {
775 return error(GL_INVALID_OPERATION);
776 }
777
778 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000779 }
780 catch(std::bad_alloc&)
781 {
782 return error(GL_OUT_OF_MEMORY);
783 }
784}
785
786void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
787{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000788 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
789 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000790 target, level, internalformat, x, y, width, height, border);
791
792 try
793 {
794 if (width < 0 || height < 0)
795 {
796 return error(GL_INVALID_VALUE);
797 }
798
799 UNIMPLEMENTED(); // FIXME
800 }
801 catch(std::bad_alloc&)
802 {
803 return error(GL_OUT_OF_MEMORY);
804 }
805}
806
807void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
808{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000809 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
810 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000811 target, level, xoffset, yoffset, x, y, width, height);
812
813 try
814 {
815 if (width < 0 || height < 0)
816 {
817 return error(GL_INVALID_VALUE);
818 }
819
820 UNIMPLEMENTED(); // FIXME
821 }
822 catch(std::bad_alloc&)
823 {
824 return error(GL_OUT_OF_MEMORY);
825 }
826}
827
828GLuint __stdcall glCreateProgram(void)
829{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000830 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000831
832 try
833 {
834 gl::Context *context = gl::getContext();
835
836 if (context)
837 {
838 return context->createProgram();
839 }
840 }
841 catch(std::bad_alloc&)
842 {
843 return error(GL_OUT_OF_MEMORY, 0);
844 }
845
846 return 0;
847}
848
849GLuint __stdcall glCreateShader(GLenum type)
850{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000851 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000852
853 try
854 {
855 gl::Context *context = gl::getContext();
856
857 if (context)
858 {
859 switch (type)
860 {
861 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000862 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000863 return context->createShader(type);
864 default:
865 return error(GL_INVALID_ENUM, 0);
866 }
867 }
868 }
869 catch(std::bad_alloc&)
870 {
871 return error(GL_OUT_OF_MEMORY, 0);
872 }
873
874 return 0;
875}
876
877void __stdcall glCullFace(GLenum mode)
878{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000879 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000880
881 try
882 {
883 switch (mode)
884 {
885 case GL_FRONT:
886 case GL_BACK:
887 case GL_FRONT_AND_BACK:
888 {
889 gl::Context *context = gl::getContext();
890
891 if (context)
892 {
893 context->cullMode = mode;
894 }
895 }
896 break;
897 default:
898 return error(GL_INVALID_ENUM);
899 }
900 }
901 catch(std::bad_alloc&)
902 {
903 return error(GL_OUT_OF_MEMORY);
904 }
905}
906
907void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
908{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000909 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000910
911 try
912 {
913 if (n < 0)
914 {
915 return error(GL_INVALID_VALUE);
916 }
917
918 gl::Context *context = gl::getContext();
919
920 if (context)
921 {
922 for (int i = 0; i < n; i++)
923 {
924 context->deleteBuffer(buffers[i]);
925 }
926 }
927 }
928 catch(std::bad_alloc&)
929 {
930 return error(GL_OUT_OF_MEMORY);
931 }
932}
933
934void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
935{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000936 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000937
938 try
939 {
940 if (n < 0)
941 {
942 return error(GL_INVALID_VALUE);
943 }
944
945 gl::Context *context = gl::getContext();
946
947 if (context)
948 {
949 for (int i = 0; i < n; i++)
950 {
951 if (framebuffers[i] != 0)
952 {
953 context->deleteFramebuffer(framebuffers[i]);
954 }
955 }
956 }
957 }
958 catch(std::bad_alloc&)
959 {
960 return error(GL_OUT_OF_MEMORY);
961 }
962}
963
964void __stdcall glDeleteProgram(GLuint program)
965{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000966 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000967
968 try
969 {
970 gl::Context *context = gl::getContext();
971
972 if (context)
973 {
974 context->deleteProgram(program);
975 }
976 }
977 catch(std::bad_alloc&)
978 {
979 return error(GL_OUT_OF_MEMORY);
980 }
981}
982
983void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
984{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000985 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000986
987 try
988 {
989 if (n < 0)
990 {
991 return error(GL_INVALID_VALUE);
992 }
993
994 gl::Context *context = gl::getContext();
995
996 if (context)
997 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +0000998 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000999 {
1000 context->deleteRenderbuffer(renderbuffers[i]);
1001 }
1002 }
1003 }
1004 catch(std::bad_alloc&)
1005 {
1006 return error(GL_OUT_OF_MEMORY);
1007 }
1008}
1009
1010void __stdcall glDeleteShader(GLuint shader)
1011{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001012 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001013
1014 try
1015 {
1016 gl::Context *context = gl::getContext();
1017
1018 if (context)
1019 {
1020 context->deleteShader(shader);
1021 }
1022 }
1023 catch(std::bad_alloc&)
1024 {
1025 return error(GL_OUT_OF_MEMORY);
1026 }
1027}
1028
1029void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1030{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001031 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001032
1033 try
1034 {
1035 if (n < 0)
1036 {
1037 return error(GL_INVALID_VALUE);
1038 }
1039
1040 gl::Context *context = gl::getContext();
1041
1042 if (context)
1043 {
1044 for (int i = 0; i < n; i++)
1045 {
1046 if (textures[i] != 0)
1047 {
1048 context->deleteTexture(textures[i]);
1049 }
1050 }
1051 }
1052 }
1053 catch(std::bad_alloc&)
1054 {
1055 return error(GL_OUT_OF_MEMORY);
1056 }
1057}
1058
1059void __stdcall glDepthFunc(GLenum func)
1060{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001061 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001062
1063 try
1064 {
1065 switch (func)
1066 {
1067 case GL_NEVER:
1068 case GL_ALWAYS:
1069 case GL_LESS:
1070 case GL_LEQUAL:
1071 case GL_EQUAL:
1072 case GL_GREATER:
1073 case GL_GEQUAL:
1074 case GL_NOTEQUAL:
1075 break;
1076 default:
1077 return error(GL_INVALID_ENUM);
1078 }
1079
1080 gl::Context *context = gl::getContext();
1081
1082 if (context)
1083 {
1084 context->depthFunc = func;
1085 }
1086 }
1087 catch(std::bad_alloc&)
1088 {
1089 return error(GL_OUT_OF_MEMORY);
1090 }
1091}
1092
1093void __stdcall glDepthMask(GLboolean flag)
1094{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001095 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001096
1097 try
1098 {
1099 gl::Context *context = gl::getContext();
1100
1101 if (context)
1102 {
1103 context->depthMask = flag != GL_FALSE;
1104 }
1105 }
1106 catch(std::bad_alloc&)
1107 {
1108 return error(GL_OUT_OF_MEMORY);
1109 }
1110}
1111
1112void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1113{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001114 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001115
1116 try
1117 {
1118 gl::Context *context = gl::getContext();
1119
1120 if (context)
1121 {
1122 context->zNear = zNear;
1123 context->zFar = zFar;
1124 }
1125 }
1126 catch(std::bad_alloc&)
1127 {
1128 return error(GL_OUT_OF_MEMORY);
1129 }
1130}
1131
1132void __stdcall glDetachShader(GLuint program, GLuint shader)
1133{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001134 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001135
1136 try
1137 {
1138 gl::Context *context = gl::getContext();
1139
1140 if (context)
1141 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001142
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001143 gl::Program *programObject = context->getProgram(program);
1144 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001145
1146 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001147 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001148 gl::Shader *shaderByProgramHandle;
1149 shaderByProgramHandle = context->getShader(program);
1150 if (!shaderByProgramHandle)
1151 {
1152 return error(GL_INVALID_VALUE);
1153 }
1154 else
1155 {
1156 return error(GL_INVALID_OPERATION);
1157 }
1158 }
1159
1160 if (!shaderObject)
1161 {
1162 gl::Program *programByShaderHandle = context->getProgram(shader);
1163 if (!programByShaderHandle)
1164 {
1165 return error(GL_INVALID_VALUE);
1166 }
1167 else
1168 {
1169 return error(GL_INVALID_OPERATION);
1170 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001171 }
1172
1173 if (!programObject->detachShader(shaderObject))
1174 {
1175 return error(GL_INVALID_OPERATION);
1176 }
1177
1178 if (shaderObject->isDeletable())
1179 {
1180 context->deleteShader(shader);
1181 }
1182 }
1183 }
1184 catch(std::bad_alloc&)
1185 {
1186 return error(GL_OUT_OF_MEMORY);
1187 }
1188}
1189
1190void __stdcall glDisable(GLenum cap)
1191{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001192 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001193
1194 try
1195 {
1196 gl::Context *context = gl::getContext();
1197
1198 if (context)
1199 {
1200 switch (cap)
1201 {
1202 case GL_CULL_FACE: context->cullFace = false; break;
1203 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1204 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1205 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1206 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1207 case GL_STENCIL_TEST: context->stencilTest = false; break;
1208 case GL_DEPTH_TEST: context->depthTest = false; break;
1209 case GL_BLEND: context->blend = false; break;
1210 case GL_DITHER: context->dither = false; break;
1211 default:
1212 return error(GL_INVALID_ENUM);
1213 }
1214 }
1215 }
1216 catch(std::bad_alloc&)
1217 {
1218 return error(GL_OUT_OF_MEMORY);
1219 }
1220}
1221
1222void __stdcall glDisableVertexAttribArray(GLuint index)
1223{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001224 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001225
1226 try
1227 {
1228 if (index >= gl::MAX_VERTEX_ATTRIBS)
1229 {
1230 return error(GL_INVALID_VALUE);
1231 }
1232
1233 gl::Context *context = gl::getContext();
1234
1235 if (context)
1236 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001237 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001238 }
1239 }
1240 catch(std::bad_alloc&)
1241 {
1242 return error(GL_OUT_OF_MEMORY);
1243 }
1244}
1245
1246void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1247{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001248 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001249
1250 try
1251 {
1252 if (count < 0 || first < 0)
1253 {
1254 return error(GL_INVALID_VALUE);
1255 }
1256
1257 gl::Context *context = gl::getContext();
1258
1259 if (context)
1260 {
1261 context->drawArrays(mode, first, count);
1262 }
1263 }
1264 catch(std::bad_alloc&)
1265 {
1266 return error(GL_OUT_OF_MEMORY);
1267 }
1268}
1269
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001270void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001271{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001272 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 +00001273 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001274
1275 try
1276 {
1277 if (count < 0)
1278 {
1279 return error(GL_INVALID_VALUE);
1280 }
1281
1282 switch (type)
1283 {
1284 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001285 case GL_UNSIGNED_SHORT:
1286 break;
1287 default:
1288 return error(GL_INVALID_ENUM);
1289 }
1290
1291 gl::Context *context = gl::getContext();
1292
1293 if (context)
1294 {
1295 context->drawElements(mode, count, type, indices);
1296 }
1297 }
1298 catch(std::bad_alloc&)
1299 {
1300 return error(GL_OUT_OF_MEMORY);
1301 }
1302}
1303
1304void __stdcall glEnable(GLenum cap)
1305{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001306 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001307
1308 try
1309 {
1310 gl::Context *context = gl::getContext();
1311
1312 if (context)
1313 {
1314 switch (cap)
1315 {
1316 case GL_CULL_FACE: context->cullFace = true; break;
1317 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1318 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1319 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1320 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1321 case GL_STENCIL_TEST: context->stencilTest = true; break;
1322 case GL_DEPTH_TEST: context->depthTest = true; break;
1323 case GL_BLEND: context->blend = true; break;
1324 case GL_DITHER: context->dither = true; break;
1325 default:
1326 return error(GL_INVALID_ENUM);
1327 }
1328 }
1329 }
1330 catch(std::bad_alloc&)
1331 {
1332 return error(GL_OUT_OF_MEMORY);
1333 }
1334}
1335
1336void __stdcall glEnableVertexAttribArray(GLuint index)
1337{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001338 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001339
1340 try
1341 {
1342 if (index >= gl::MAX_VERTEX_ATTRIBS)
1343 {
1344 return error(GL_INVALID_VALUE);
1345 }
1346
1347 gl::Context *context = gl::getContext();
1348
1349 if (context)
1350 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001351 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001352 }
1353 }
1354 catch(std::bad_alloc&)
1355 {
1356 return error(GL_OUT_OF_MEMORY);
1357 }
1358}
1359
1360void __stdcall glFinish(void)
1361{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001362 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001363
1364 try
1365 {
1366 gl::Context *context = gl::getContext();
1367
1368 if (context)
1369 {
1370 context->finish();
1371 }
1372 }
1373 catch(std::bad_alloc&)
1374 {
1375 return error(GL_OUT_OF_MEMORY);
1376 }
1377}
1378
1379void __stdcall glFlush(void)
1380{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001381 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001382
1383 try
1384 {
1385 gl::Context *context = gl::getContext();
1386
1387 if (context)
1388 {
1389 context->flush();
1390 }
1391 }
1392 catch(std::bad_alloc&)
1393 {
1394 return error(GL_OUT_OF_MEMORY);
1395 }
1396}
1397
1398void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1399{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001400 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1401 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001402
1403 try
1404 {
1405 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1406 {
1407 return error(GL_INVALID_ENUM);
1408 }
1409
1410 gl::Context *context = gl::getContext();
1411
1412 if (context)
1413 {
1414 gl::Framebuffer *framebuffer = context->getFramebuffer();
1415
1416 if (context->framebuffer == 0 || !framebuffer)
1417 {
1418 return error(GL_INVALID_OPERATION);
1419 }
1420
1421 switch (attachment)
1422 {
1423 case GL_COLOR_ATTACHMENT0:
1424 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1425 break;
1426 case GL_DEPTH_ATTACHMENT:
1427 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1428 break;
1429 case GL_STENCIL_ATTACHMENT:
1430 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1431 break;
1432 default:
1433 return error(GL_INVALID_ENUM);
1434 }
1435 }
1436 }
1437 catch(std::bad_alloc&)
1438 {
1439 return error(GL_OUT_OF_MEMORY);
1440 }
1441}
1442
1443void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1444{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001445 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1446 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001447
1448 try
1449 {
1450 if (target != GL_FRAMEBUFFER)
1451 {
1452 return error(GL_INVALID_ENUM);
1453 }
1454
1455 switch (attachment)
1456 {
1457 case GL_COLOR_ATTACHMENT0:
1458 break;
1459 default:
1460 return error(GL_INVALID_ENUM);
1461 }
1462
1463 gl::Context *context = gl::getContext();
1464
1465 if (context)
1466 {
1467 if (texture)
1468 {
1469 switch (textarget)
1470 {
1471 case GL_TEXTURE_2D:
1472 if (!context->getTexture2D())
1473 {
1474 return error(GL_INVALID_OPERATION);
1475 }
1476 break;
1477 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1478 UNIMPLEMENTED(); // FIXME
1479 break;
1480 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1481 UNIMPLEMENTED(); // FIXME
1482 break;
1483 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1484 UNIMPLEMENTED(); // FIXME
1485 break;
1486 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1487 UNIMPLEMENTED(); // FIXME
1488 break;
1489 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1490 UNIMPLEMENTED(); // FIXME
1491 break;
1492 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1493 UNIMPLEMENTED(); // FIXME
1494 break;
1495 default:
1496 return error(GL_INVALID_ENUM);
1497 }
1498
1499 if (level != 0)
1500 {
1501 return error(GL_INVALID_VALUE);
1502 }
1503 }
1504
1505 gl::Framebuffer *framebuffer = context->getFramebuffer();
1506
1507 if (context->framebuffer == 0 || !framebuffer)
1508 {
1509 return error(GL_INVALID_OPERATION);
1510 }
1511
1512 framebuffer->setColorbuffer(GL_TEXTURE, texture);
1513 }
1514 }
1515 catch(std::bad_alloc&)
1516 {
1517 return error(GL_OUT_OF_MEMORY);
1518 }
1519}
1520
1521void __stdcall glFrontFace(GLenum mode)
1522{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001523 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001524
1525 try
1526 {
1527 switch (mode)
1528 {
1529 case GL_CW:
1530 case GL_CCW:
1531 {
1532 gl::Context *context = gl::getContext();
1533
1534 if (context)
1535 {
1536 context->frontFace = mode;
1537 }
1538 }
1539 break;
1540 default:
1541 return error(GL_INVALID_ENUM);
1542 }
1543 }
1544 catch(std::bad_alloc&)
1545 {
1546 return error(GL_OUT_OF_MEMORY);
1547 }
1548}
1549
1550void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1551{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001552 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001553
1554 try
1555 {
1556 if (n < 0)
1557 {
1558 return error(GL_INVALID_VALUE);
1559 }
1560
1561 gl::Context *context = gl::getContext();
1562
1563 if (context)
1564 {
1565 for (int i = 0; i < n; i++)
1566 {
1567 buffers[i] = context->createBuffer();
1568 }
1569 }
1570 }
1571 catch(std::bad_alloc&)
1572 {
1573 return error(GL_OUT_OF_MEMORY);
1574 }
1575}
1576
1577void __stdcall glGenerateMipmap(GLenum target)
1578{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001579 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001580
1581 try
1582 {
1583 UNIMPLEMENTED(); // FIXME
1584 }
1585 catch(std::bad_alloc&)
1586 {
1587 return error(GL_OUT_OF_MEMORY);
1588 }
1589}
1590
1591void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1592{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001593 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001594
1595 try
1596 {
1597 if (n < 0)
1598 {
1599 return error(GL_INVALID_VALUE);
1600 }
1601
1602 gl::Context *context = gl::getContext();
1603
1604 if (context)
1605 {
1606 for (int i = 0; i < n; i++)
1607 {
1608 framebuffers[i] = context->createFramebuffer();
1609 }
1610 }
1611 }
1612 catch(std::bad_alloc&)
1613 {
1614 return error(GL_OUT_OF_MEMORY);
1615 }
1616}
1617
1618void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1619{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001620 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001621
1622 try
1623 {
1624 if (n < 0)
1625 {
1626 return error(GL_INVALID_VALUE);
1627 }
1628
1629 gl::Context *context = gl::getContext();
1630
1631 if (context)
1632 {
1633 for (int i = 0; i < n; i++)
1634 {
1635 renderbuffers[i] = context->createRenderbuffer();
1636 }
1637 }
1638 }
1639 catch(std::bad_alloc&)
1640 {
1641 return error(GL_OUT_OF_MEMORY);
1642 }
1643}
1644
1645void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1646{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001647 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001648
1649 try
1650 {
1651 if (n < 0)
1652 {
1653 return error(GL_INVALID_VALUE);
1654 }
1655
1656 gl::Context *context = gl::getContext();
1657
1658 if (context)
1659 {
1660 for (int i = 0; i < n; i++)
1661 {
1662 textures[i] = context->createTexture();
1663 }
1664 }
1665 }
1666 catch(std::bad_alloc&)
1667 {
1668 return error(GL_OUT_OF_MEMORY);
1669 }
1670}
1671
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001672void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001673{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001674 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001675 "GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001676 program, index, bufsize, length, size, type, name);
1677
1678 try
1679 {
1680 if (bufsize < 0)
1681 {
1682 return error(GL_INVALID_VALUE);
1683 }
1684
1685 UNIMPLEMENTED(); // FIXME
1686 }
1687 catch(std::bad_alloc&)
1688 {
1689 return error(GL_OUT_OF_MEMORY);
1690 }
1691}
1692
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001693void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001694{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001695 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001696 "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 +00001697 program, index, bufsize, length, size, type, name);
1698
1699 try
1700 {
1701 if (bufsize < 0)
1702 {
1703 return error(GL_INVALID_VALUE);
1704 }
1705
1706 UNIMPLEMENTED(); // FIXME
1707 }
1708 catch(std::bad_alloc&)
1709 {
1710 return error(GL_OUT_OF_MEMORY);
1711 }
1712}
1713
1714void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1715{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001716 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1717 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001718
1719 try
1720 {
1721 if (maxcount < 0)
1722 {
1723 return error(GL_INVALID_VALUE);
1724 }
1725
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001726 gl::Context *context = gl::getContext();
1727
1728 if (context)
1729 {
1730 gl::Program *programObject = context->getProgram(program);
1731
1732 if (!programObject)
1733 {
1734 return error(GL_INVALID_VALUE);
1735 }
1736
1737 return programObject->getAttachedShaders(maxcount, count, shaders);
1738 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001739 }
1740 catch(std::bad_alloc&)
1741 {
1742 return error(GL_OUT_OF_MEMORY);
1743 }
1744}
1745
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001746int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001747{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001748 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001749
1750 try
1751 {
1752 gl::Context *context = gl::getContext();
1753
1754 if (context)
1755 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001756
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001757 gl::Program *programObject = context->getProgram(program);
1758
1759 if (!programObject)
1760 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001761 if (context->getShader(program))
1762 {
1763 return error(GL_INVALID_OPERATION, -1);
1764 }
1765 else
1766 {
1767 return error(GL_INVALID_VALUE, -1);
1768 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001769 }
1770
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00001771 if (!programObject->isLinked())
1772 {
1773 return error(GL_INVALID_OPERATION, -1);
1774 }
1775
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001776 return programObject->getAttributeLocation(name);
1777 }
1778 }
1779 catch(std::bad_alloc&)
1780 {
1781 return error(GL_OUT_OF_MEMORY, -1);
1782 }
1783
1784 return -1;
1785}
1786
1787void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1788{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001789 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001790
1791 try
1792 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001793 gl::Context *context = gl::getContext();
1794
1795 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001796 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001797 if (!(context->getBooleanv(pname, params)))
1798 {
1799 GLenum nativeType;
1800 unsigned int numParams = 0;
1801 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1802 return error(GL_INVALID_ENUM);
1803
1804 if (numParams == 0)
1805 return; // it is known that the pname is valid, but there are no parameters to return
1806
1807 if (nativeType == GL_FLOAT)
1808 {
1809 GLfloat *floatParams = NULL;
1810 floatParams = new GLfloat[numParams];
1811
1812 context->getFloatv(pname, floatParams);
1813
1814 for (unsigned int i = 0; i < numParams; ++i)
1815 {
1816 if (floatParams[i] == 0.0f)
1817 params[i] = GL_FALSE;
1818 else
1819 params[i] = GL_TRUE;
1820 }
1821
1822 delete [] floatParams;
1823 }
1824 else if (nativeType == GL_INT)
1825 {
1826 GLint *intParams = NULL;
1827 intParams = new GLint[numParams];
1828
1829 context->getIntegerv(pname, intParams);
1830
1831 for (unsigned int i = 0; i < numParams; ++i)
1832 {
1833 if (intParams[i] == 0)
1834 params[i] = GL_FALSE;
1835 else
1836 params[i] = GL_TRUE;
1837 }
1838
1839 delete [] intParams;
1840 }
1841 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001842 }
1843 }
1844 catch(std::bad_alloc&)
1845 {
1846 return error(GL_OUT_OF_MEMORY);
1847 }
1848}
1849
1850void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1851{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001852 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 +00001853
1854 try
1855 {
1856 UNIMPLEMENTED(); // FIXME
1857 }
1858 catch(std::bad_alloc&)
1859 {
1860 return error(GL_OUT_OF_MEMORY);
1861 }
1862}
1863
1864GLenum __stdcall glGetError(void)
1865{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001866 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001867
1868 gl::Context *context = gl::getContext();
1869
1870 if (context)
1871 {
1872 return context->getError();
1873 }
1874
1875 return GL_NO_ERROR;
1876}
1877
1878void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
1879{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001880 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001881
1882 try
1883 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001884 gl::Context *context = gl::getContext();
1885
1886 if (context)
1887 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001888 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001889 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001890 GLenum nativeType;
1891 unsigned int numParams = 0;
1892 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1893 return error(GL_INVALID_ENUM);
1894
1895 if (numParams == 0)
1896 return; // it is known that the pname is valid, but that there are no parameters to return.
1897
1898 if (nativeType == GL_BOOL)
1899 {
1900 GLboolean *boolParams = NULL;
1901 boolParams = new GLboolean[numParams];
1902
1903 context->getBooleanv(pname, boolParams);
1904
1905 for (unsigned int i = 0; i < numParams; ++i)
1906 {
1907 if (boolParams[i] == GL_FALSE)
1908 params[i] = 0.0f;
1909 else
1910 params[i] = 1.0f;
1911 }
1912
1913 delete [] boolParams;
1914 }
1915 else if (nativeType == GL_INT)
1916 {
1917 GLint *intParams = NULL;
1918 intParams = new GLint[numParams];
1919
1920 context->getIntegerv(pname, intParams);
1921
1922 for (unsigned int i = 0; i < numParams; ++i)
1923 {
1924 params[i] = (GLfloat)intParams[i];
1925 }
1926
1927 delete [] intParams;
1928 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001929 }
1930 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001931 }
1932 catch(std::bad_alloc&)
1933 {
1934 return error(GL_OUT_OF_MEMORY);
1935 }
1936}
1937
1938void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
1939{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001940 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
1941 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001942
1943 try
1944 {
1945 gl::Context *context = gl::getContext();
1946
1947 if (context)
1948 {
1949 if (context->framebuffer == 0)
1950 {
1951 return error(GL_INVALID_OPERATION);
1952 }
1953
1954 UNIMPLEMENTED(); // FIXME
1955 }
1956 }
1957 catch(std::bad_alloc&)
1958 {
1959 return error(GL_OUT_OF_MEMORY);
1960 }
1961}
1962
1963void __stdcall glGetIntegerv(GLenum pname, GLint* params)
1964{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001965 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001966
1967 try
1968 {
1969 gl::Context *context = gl::getContext();
1970
1971 if (context)
1972 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001973 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001974 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001975 GLenum nativeType;
1976 unsigned int numParams = 0;
1977 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1978 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001979
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001980 if (numParams == 0)
1981 return; // it is known that pname is valid, but there are no parameters to return
1982
1983 if (nativeType == GL_BOOL)
1984 {
1985 GLboolean *boolParams = NULL;
1986 boolParams = new GLboolean[numParams];
1987
1988 context->getBooleanv(pname, boolParams);
1989
1990 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001991 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001992 if (boolParams[i] == GL_FALSE)
1993 params[i] = 0;
1994 else
1995 params[i] = 1;
1996 }
1997
1998 delete [] boolParams;
1999 }
2000 else if (nativeType == GL_FLOAT)
2001 {
2002 GLfloat *floatParams = NULL;
2003 floatParams = new GLfloat[numParams];
2004
2005 context->getFloatv(pname, floatParams);
2006
2007 for (unsigned int i = 0; i < numParams; ++i)
2008 {
2009 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002010 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002011 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002012 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002013 else
2014 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 +00002015 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002016
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002017 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002018 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002019 }
2020 }
2021 }
2022 catch(std::bad_alloc&)
2023 {
2024 return error(GL_OUT_OF_MEMORY);
2025 }
2026}
2027
2028void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2029{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002030 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002031
2032 try
2033 {
2034 gl::Context *context = gl::getContext();
2035
2036 if (context)
2037 {
2038 gl::Program *programObject = context->getProgram(program);
2039
2040 if (!programObject)
2041 {
2042 return error(GL_INVALID_VALUE);
2043 }
2044
2045 switch (pname)
2046 {
2047 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002048 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002049 return;
2050 case GL_LINK_STATUS:
2051 *params = programObject->isLinked();
2052 return;
2053 case GL_VALIDATE_STATUS:
2054 UNIMPLEMENTED(); // FIXME
2055 *params = GL_TRUE;
2056 return;
2057 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002058 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002059 return;
2060 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002061 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002062 return;
2063 case GL_ACTIVE_ATTRIBUTES:
2064 UNIMPLEMENTED(); // FIXME
2065 *params = 0;
2066 return;
2067 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2068 UNIMPLEMENTED(); // FIXME
2069 *params = 0;
2070 return;
2071 case GL_ACTIVE_UNIFORMS:
2072 UNIMPLEMENTED(); // FIXME
2073 *params = 0;
2074 return;
2075 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2076 UNIMPLEMENTED(); // FIXME
2077 *params = 0;
2078 return;
2079 default:
2080 return error(GL_INVALID_ENUM);
2081 }
2082 }
2083 }
2084 catch(std::bad_alloc&)
2085 {
2086 return error(GL_OUT_OF_MEMORY);
2087 }
2088}
2089
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002090void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002091{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002092 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 +00002093 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002094
2095 try
2096 {
2097 if (bufsize < 0)
2098 {
2099 return error(GL_INVALID_VALUE);
2100 }
2101
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002102 gl::Context *context = gl::getContext();
2103
2104 if (context)
2105 {
2106 gl::Program *programObject = context->getProgram(program);
2107
2108 if (!programObject)
2109 {
2110 return error(GL_INVALID_VALUE);
2111 }
2112
2113 programObject->getInfoLog(bufsize, length, infolog);
2114 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002115 }
2116 catch(std::bad_alloc&)
2117 {
2118 return error(GL_OUT_OF_MEMORY);
2119 }
2120}
2121
2122void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2123{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002124 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 +00002125
2126 try
2127 {
2128 UNIMPLEMENTED(); // FIXME
2129 }
2130 catch(std::bad_alloc&)
2131 {
2132 return error(GL_OUT_OF_MEMORY);
2133 }
2134}
2135
2136void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2137{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002138 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002139
2140 try
2141 {
2142 gl::Context *context = gl::getContext();
2143
2144 if (context)
2145 {
2146 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002147
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002148 if (!shaderObject)
2149 {
2150 return error(GL_INVALID_VALUE);
2151 }
2152
2153 switch (pname)
2154 {
2155 case GL_SHADER_TYPE:
2156 *params = shaderObject->getType();
2157 return;
2158 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002159 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002160 return;
2161 case GL_COMPILE_STATUS:
2162 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2163 return;
2164 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002165 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002166 return;
2167 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002168 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002169 return;
2170 default:
2171 return error(GL_INVALID_ENUM);
2172 }
2173 }
2174 }
2175 catch(std::bad_alloc&)
2176 {
2177 return error(GL_OUT_OF_MEMORY);
2178 }
2179}
2180
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002181void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002182{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002183 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 +00002184 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002185
2186 try
2187 {
2188 if (bufsize < 0)
2189 {
2190 return error(GL_INVALID_VALUE);
2191 }
2192
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002193 gl::Context *context = gl::getContext();
2194
2195 if (context)
2196 {
2197 gl::Shader *shaderObject = context->getShader(shader);
2198
2199 if (!shaderObject)
2200 {
2201 return error(GL_INVALID_VALUE);
2202 }
2203
2204 shaderObject->getInfoLog(bufsize, length, infolog);
2205 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002206 }
2207 catch(std::bad_alloc&)
2208 {
2209 return error(GL_OUT_OF_MEMORY);
2210 }
2211}
2212
2213void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2214{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002215 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2216 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002217
2218 try
2219 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002220 switch (shadertype)
2221 {
2222 case GL_VERTEX_SHADER:
2223 case GL_FRAGMENT_SHADER:
2224 break;
2225 default:
2226 return error(GL_INVALID_ENUM);
2227 }
2228
2229 switch (precisiontype)
2230 {
2231 case GL_LOW_FLOAT:
2232 case GL_MEDIUM_FLOAT:
2233 case GL_HIGH_FLOAT:
2234 // Assume IEEE 754 precision
2235 range[0] = 127;
2236 range[1] = 127;
2237 precision[0] = 23;
2238 precision[1] = 23;
2239 break;
2240 case GL_LOW_INT:
2241 case GL_MEDIUM_INT:
2242 case GL_HIGH_INT:
2243 // Some (most) hardware only supports single-precision floating-point numbers,
2244 // which can accurately represent integers up to +/-16777216
2245 range[0] = 24;
2246 range[1] = 24;
2247 precision[0] = 0;
2248 precision[1] = 0;
2249 break;
2250 default:
2251 return error(GL_INVALID_ENUM);
2252 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002253 }
2254 catch(std::bad_alloc&)
2255 {
2256 return error(GL_OUT_OF_MEMORY);
2257 }
2258}
2259
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002260void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002261{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002262 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 +00002263 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002264
2265 try
2266 {
2267 if (bufsize < 0)
2268 {
2269 return error(GL_INVALID_VALUE);
2270 }
2271
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002272 gl::Context *context = gl::getContext();
2273
2274 if (context)
2275 {
2276 gl::Shader *shaderObject = context->getShader(shader);
2277
2278 if (!shaderObject)
2279 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002280 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002281 }
2282
2283 shaderObject->getSource(bufsize, length, source);
2284 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002285 }
2286 catch(std::bad_alloc&)
2287 {
2288 return error(GL_OUT_OF_MEMORY);
2289 }
2290}
2291
2292const GLubyte* __stdcall glGetString(GLenum name)
2293{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002294 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002295
2296 try
2297 {
2298 switch (name)
2299 {
2300 case GL_VENDOR:
2301 return (GLubyte*)"TransGaming Inc.";
2302 case GL_RENDERER:
2303 return (GLubyte*)"ANGLE";
2304 case GL_VERSION:
2305 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2306 case GL_SHADING_LANGUAGE_VERSION:
2307 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2308 case GL_EXTENSIONS:
2309 return (GLubyte*)"";
2310 default:
2311 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2312 }
2313 }
2314 catch(std::bad_alloc&)
2315 {
2316 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2317 }
2318
2319 return NULL;
2320}
2321
2322void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2323{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002324 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 +00002325
2326 try
2327 {
2328 UNIMPLEMENTED(); // FIXME
2329 }
2330 catch(std::bad_alloc&)
2331 {
2332 return error(GL_OUT_OF_MEMORY);
2333 }
2334}
2335
2336void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2337{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002338 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 +00002339
2340 try
2341 {
2342 UNIMPLEMENTED(); // FIXME
2343 }
2344 catch(std::bad_alloc&)
2345 {
2346 return error(GL_OUT_OF_MEMORY);
2347 }
2348}
2349
2350void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2351{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002352 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002353
2354 try
2355 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002356 gl::Context *context = gl::getContext();
2357
2358 if (context)
2359 {
2360 if (program == 0)
2361 {
2362 return error(GL_INVALID_VALUE);
2363 }
2364
2365 gl::Program *programObject = context->getProgram(program);
2366
2367 if (!programObject || !programObject->isLinked())
2368 {
2369 return error(GL_INVALID_OPERATION);
2370 }
2371
2372 if (!programObject->getUniformfv(location, params))
2373 {
2374 return error(GL_INVALID_OPERATION);
2375 }
2376 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002377 }
2378 catch(std::bad_alloc&)
2379 {
2380 return error(GL_OUT_OF_MEMORY);
2381 }
2382}
2383
2384void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2385{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002386 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002387
2388 try
2389 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002390 gl::Context *context = gl::getContext();
2391
2392 if (context)
2393 {
2394 if (program == 0)
2395 {
2396 return error(GL_INVALID_VALUE);
2397 }
2398
2399 gl::Program *programObject = context->getProgram(program);
2400
2401 if (!programObject || !programObject->isLinked())
2402 {
2403 return error(GL_INVALID_OPERATION);
2404 }
2405
2406 if (!programObject)
2407 {
2408 return error(GL_INVALID_OPERATION);
2409 }
2410
2411 if (!programObject->getUniformiv(location, params))
2412 {
2413 return error(GL_INVALID_OPERATION);
2414 }
2415 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002416 }
2417 catch(std::bad_alloc&)
2418 {
2419 return error(GL_OUT_OF_MEMORY);
2420 }
2421}
2422
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002423int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002424{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002425 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002426
2427 try
2428 {
2429 gl::Context *context = gl::getContext();
2430
2431 if (strstr(name, "gl_") == name)
2432 {
2433 return -1;
2434 }
2435
2436 if (context)
2437 {
2438 gl::Program *programObject = context->getProgram(program);
2439
2440 if (!programObject)
2441 {
2442 return error(GL_INVALID_VALUE, -1);
2443 }
2444
2445 if (!programObject->isLinked())
2446 {
2447 return error(GL_INVALID_OPERATION, -1);
2448 }
2449
2450 return programObject->getUniformLocation(name);
2451 }
2452 }
2453 catch(std::bad_alloc&)
2454 {
2455 return error(GL_OUT_OF_MEMORY, -1);
2456 }
2457
2458 return -1;
2459}
2460
2461void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2462{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002463 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002464
2465 try
2466 {
2467 if (index >= gl::MAX_VERTEX_ATTRIBS)
2468 {
2469 return error(GL_INVALID_VALUE);
2470 }
2471
2472 UNIMPLEMENTED(); // FIXME
2473 }
2474 catch(std::bad_alloc&)
2475 {
2476 return error(GL_OUT_OF_MEMORY);
2477 }
2478}
2479
2480void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2481{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002482 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002483
2484 try
2485 {
2486 if (index >= gl::MAX_VERTEX_ATTRIBS)
2487 {
2488 return error(GL_INVALID_VALUE);
2489 }
2490
2491 UNIMPLEMENTED(); // FIXME
2492 }
2493 catch(std::bad_alloc&)
2494 {
2495 return error(GL_OUT_OF_MEMORY);
2496 }
2497}
2498
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002499void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002500{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002501 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002502
2503 try
2504 {
2505 if (index >= gl::MAX_VERTEX_ATTRIBS)
2506 {
2507 return error(GL_INVALID_VALUE);
2508 }
2509
2510 UNIMPLEMENTED(); // FIXME
2511 }
2512 catch(std::bad_alloc&)
2513 {
2514 return error(GL_OUT_OF_MEMORY);
2515 }
2516}
2517
2518void __stdcall glHint(GLenum target, GLenum mode)
2519{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002520 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002521
2522 try
2523 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002524 switch (target)
2525 {
2526 case GL_GENERATE_MIPMAP_HINT:
2527 switch (mode)
2528 {
2529 case GL_FASTEST:
2530 case GL_NICEST:
2531 case GL_DONT_CARE:
2532 break;
2533 default:
2534 return error(GL_INVALID_ENUM);
2535 }
2536 break;
2537 default:
2538 return error(GL_INVALID_ENUM);
2539 }
2540
2541 gl::Context *context = gl::getContext();
2542 if (context)
2543 {
2544 if (target == GL_GENERATE_MIPMAP_HINT)
2545 context->generateMipmapHint = mode;
2546 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002547 }
2548 catch(std::bad_alloc&)
2549 {
2550 return error(GL_OUT_OF_MEMORY);
2551 }
2552}
2553
2554GLboolean __stdcall glIsBuffer(GLuint buffer)
2555{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002556 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002557
2558 try
2559 {
2560 gl::Context *context = gl::getContext();
2561
2562 if (context && buffer)
2563 {
2564 gl::Buffer *bufferObject = context->getBuffer(buffer);
2565
2566 if (bufferObject)
2567 {
2568 return GL_TRUE;
2569 }
2570 }
2571 }
2572 catch(std::bad_alloc&)
2573 {
2574 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2575 }
2576
2577 return GL_FALSE;
2578}
2579
2580GLboolean __stdcall glIsEnabled(GLenum cap)
2581{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002582 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002583
2584 try
2585 {
2586 gl::Context *context = gl::getContext();
2587
2588 if (context)
2589 {
2590 switch (cap)
2591 {
2592 case GL_CULL_FACE: return context->cullFace;
2593 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
2594 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
2595 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
2596 case GL_SCISSOR_TEST: return context->scissorTest;
2597 case GL_STENCIL_TEST: return context->stencilTest;
2598 case GL_DEPTH_TEST: return context->depthTest;
2599 case GL_BLEND: return context->blend;
2600 case GL_DITHER: return context->dither;
2601 default:
2602 return error(GL_INVALID_ENUM, false);
2603 }
2604 }
2605 }
2606 catch(std::bad_alloc&)
2607 {
2608 return error(GL_OUT_OF_MEMORY, false);
2609 }
2610
2611 return false;
2612}
2613
2614GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
2615{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002616 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002617
2618 try
2619 {
2620 gl::Context *context = gl::getContext();
2621
2622 if (context && framebuffer)
2623 {
2624 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2625
2626 if (framebufferObject)
2627 {
2628 return GL_TRUE;
2629 }
2630 }
2631 }
2632 catch(std::bad_alloc&)
2633 {
2634 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2635 }
2636
2637 return GL_FALSE;
2638}
2639
2640GLboolean __stdcall glIsProgram(GLuint program)
2641{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002642 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002643
2644 try
2645 {
2646 gl::Context *context = gl::getContext();
2647
2648 if (context && program)
2649 {
2650 gl::Program *programObject = context->getProgram(program);
2651
2652 if (programObject)
2653 {
2654 return GL_TRUE;
2655 }
2656 }
2657 }
2658 catch(std::bad_alloc&)
2659 {
2660 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2661 }
2662
2663 return GL_FALSE;
2664}
2665
2666GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
2667{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002668 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002669
2670 try
2671 {
2672 gl::Context *context = gl::getContext();
2673
2674 if (context && renderbuffer)
2675 {
2676 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2677
2678 if (renderbufferObject)
2679 {
2680 return GL_TRUE;
2681 }
2682 }
2683 }
2684 catch(std::bad_alloc&)
2685 {
2686 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2687 }
2688
2689 return GL_FALSE;
2690}
2691
2692GLboolean __stdcall glIsShader(GLuint shader)
2693{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002694 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002695
2696 try
2697 {
2698 gl::Context *context = gl::getContext();
2699
2700 if (context && shader)
2701 {
2702 gl::Shader *shaderObject = context->getShader(shader);
2703
2704 if (shaderObject)
2705 {
2706 return GL_TRUE;
2707 }
2708 }
2709 }
2710 catch(std::bad_alloc&)
2711 {
2712 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2713 }
2714
2715 return GL_FALSE;
2716}
2717
2718GLboolean __stdcall glIsTexture(GLuint texture)
2719{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002720 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002721
2722 try
2723 {
2724 gl::Context *context = gl::getContext();
2725
2726 if (context && texture)
2727 {
2728 gl::Texture *textureObject = context->getTexture(texture);
2729
2730 if (textureObject)
2731 {
2732 return GL_TRUE;
2733 }
2734 }
2735 }
2736 catch(std::bad_alloc&)
2737 {
2738 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2739 }
2740
2741 return GL_FALSE;
2742}
2743
2744void __stdcall glLineWidth(GLfloat width)
2745{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002746 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002747
2748 try
2749 {
2750 if (width <= 0.0f)
2751 {
2752 return error(GL_INVALID_VALUE);
2753 }
2754
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002755 gl::Context *context = gl::getContext();
2756
2757 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002758 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002759 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002760 }
2761 }
2762 catch(std::bad_alloc&)
2763 {
2764 return error(GL_OUT_OF_MEMORY);
2765 }
2766}
2767
2768void __stdcall glLinkProgram(GLuint program)
2769{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002770 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002771
2772 try
2773 {
2774 gl::Context *context = gl::getContext();
2775
2776 if (context)
2777 {
2778 gl::Program *programObject = context->getProgram(program);
2779
2780 if (!programObject)
2781 {
2782 return error(GL_INVALID_VALUE);
2783 }
2784
2785 programObject->link();
2786 }
2787 }
2788 catch(std::bad_alloc&)
2789 {
2790 return error(GL_OUT_OF_MEMORY);
2791 }
2792}
2793
2794void __stdcall glPixelStorei(GLenum pname, GLint param)
2795{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002796 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002797
2798 try
2799 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002800 gl::Context *context = gl::getContext();
2801
2802 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002803 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002804 switch (pname)
2805 {
2806 case GL_UNPACK_ALIGNMENT:
2807 if (param != 1 && param != 2 && param != 4 && param != 8)
2808 {
2809 return error(GL_INVALID_VALUE);
2810 }
2811
2812 context->unpackAlignment = param;
2813 break;
2814
2815 case GL_PACK_ALIGNMENT:
2816 if (param != 1 && param != 2 && param != 4 && param != 8)
2817 {
2818 return error(GL_INVALID_VALUE);
2819 }
2820
2821 context->packAlignment = param;
2822 break;
2823
2824 default:
2825 return error(GL_INVALID_ENUM);
2826 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002827 }
2828 }
2829 catch(std::bad_alloc&)
2830 {
2831 return error(GL_OUT_OF_MEMORY);
2832 }
2833}
2834
2835void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
2836{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002837 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002838
2839 try
2840 {
2841 if (factor != 0.0f || units != 0.0f)
2842 {
2843 UNIMPLEMENTED(); // FIXME
2844 }
2845 }
2846 catch(std::bad_alloc&)
2847 {
2848 return error(GL_OUT_OF_MEMORY);
2849 }
2850}
2851
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002852void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002853{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002854 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002855 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002856 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002857
2858 try
2859 {
2860 if (width < 0 || height < 0)
2861 {
2862 return error(GL_INVALID_VALUE);
2863 }
2864
2865 switch (format)
2866 {
2867 case GL_RGBA:
2868 switch (type)
2869 {
2870 case GL_UNSIGNED_BYTE:
2871 break;
2872 default:
2873 return error(GL_INVALID_OPERATION);
2874 }
2875 break;
2876 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
2877 switch (type)
2878 {
2879 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
2880 break;
2881 default:
2882 return error(GL_INVALID_OPERATION);
2883 }
2884 break;
2885 default:
2886 return error(GL_INVALID_OPERATION);
2887 }
2888
2889 gl::Context *context = gl::getContext();
2890
2891 if (context)
2892 {
2893 context->readPixels(x, y, width, height, format, type, pixels);
2894 }
2895 }
2896 catch(std::bad_alloc&)
2897 {
2898 return error(GL_OUT_OF_MEMORY);
2899 }
2900}
2901
2902void __stdcall glReleaseShaderCompiler(void)
2903{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002904 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002905
2906 try
2907 {
2908 gl::Shader::releaseCompiler();
2909 }
2910 catch(std::bad_alloc&)
2911 {
2912 return error(GL_OUT_OF_MEMORY);
2913 }
2914}
2915
2916void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
2917{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002918 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
2919 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002920
2921 try
2922 {
2923 switch (target)
2924 {
2925 case GL_RENDERBUFFER:
2926 break;
2927 default:
2928 return error(GL_INVALID_ENUM);
2929 }
2930
2931 switch (internalformat)
2932 {
2933 case GL_DEPTH_COMPONENT16:
2934 case GL_RGBA4:
2935 case GL_RGB5_A1:
2936 case GL_RGB565:
2937 case GL_STENCIL_INDEX8:
2938 break;
2939 default:
2940 return error(GL_INVALID_ENUM);
2941 }
2942
2943 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
2944 {
2945 return error(GL_INVALID_VALUE);
2946 }
2947
2948 gl::Context *context = gl::getContext();
2949
2950 if (context)
2951 {
2952 if (context->framebuffer == 0 || context->renderbuffer == 0)
2953 {
2954 return error(GL_INVALID_OPERATION);
2955 }
2956
2957 switch (internalformat)
2958 {
2959 case GL_DEPTH_COMPONENT16:
2960 context->setRenderbuffer(new gl::Depthbuffer(width, height));
2961 break;
2962 case GL_RGBA4:
2963 case GL_RGB5_A1:
2964 case GL_RGB565:
2965 UNIMPLEMENTED(); // FIXME
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00002966 // context->setRenderbuffer(new Colorbuffer(renderTarget));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002967 break;
2968 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00002969 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002970 break;
2971 default:
2972 return error(GL_INVALID_ENUM);
2973 }
2974 }
2975 }
2976 catch(std::bad_alloc&)
2977 {
2978 return error(GL_OUT_OF_MEMORY);
2979 }
2980}
2981
2982void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
2983{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002984 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002985
2986 try
2987 {
2988 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002989
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002990 if (context)
2991 {
2992 context->sampleCoverageValue = gl::clamp01(value);
2993 context->sampleCoverageInvert = invert;
2994 }
2995 }
2996 catch(std::bad_alloc&)
2997 {
2998 return error(GL_OUT_OF_MEMORY);
2999 }
3000}
3001
3002void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3003{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003004 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 +00003005
3006 try
3007 {
3008 if (width < 0 || height < 0)
3009 {
3010 return error(GL_INVALID_VALUE);
3011 }
3012
3013 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003014
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003015 if (context)
3016 {
3017 context->scissorX = x;
3018 context->scissorY = y;
3019 context->scissorWidth = width;
3020 context->scissorHeight = height;
3021 }
3022 }
3023 catch(std::bad_alloc&)
3024 {
3025 return error(GL_OUT_OF_MEMORY);
3026 }
3027}
3028
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003029void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003030{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003031 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003032 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003033 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003034
3035 try
3036 {
3037 if (n < 0 || length < 0)
3038 {
3039 return error(GL_INVALID_VALUE);
3040 }
3041
3042 UNIMPLEMENTED(); // FIXME
3043 }
3044 catch(std::bad_alloc&)
3045 {
3046 return error(GL_OUT_OF_MEMORY);
3047 }
3048}
3049
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003050void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003051{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003052 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 +00003053 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003054
3055 try
3056 {
daniel@transgaming.com57a0bab2010-04-03 20:56:10 +00003057 if (shader == 0 || count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003058 {
3059 return error(GL_INVALID_VALUE);
3060 }
3061
3062 gl::Context *context = gl::getContext();
3063
3064 if (context)
3065 {
3066 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003067
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003068 if (!shaderObject)
3069 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003070 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003071 }
3072
3073 shaderObject->setSource(count, string, length);
3074 }
3075 }
3076 catch(std::bad_alloc&)
3077 {
3078 return error(GL_OUT_OF_MEMORY);
3079 }
3080}
3081
3082void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3083{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003084 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003085}
3086
3087void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3088{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003089 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 +00003090
3091 try
3092 {
3093 switch (face)
3094 {
3095 case GL_FRONT:
3096 case GL_BACK:
3097 case GL_FRONT_AND_BACK:
3098 break;
3099 default:
3100 return error(GL_INVALID_ENUM);
3101 }
3102
3103 switch (func)
3104 {
3105 case GL_NEVER:
3106 case GL_ALWAYS:
3107 case GL_LESS:
3108 case GL_LEQUAL:
3109 case GL_EQUAL:
3110 case GL_GEQUAL:
3111 case GL_GREATER:
3112 case GL_NOTEQUAL:
3113 break;
3114 default:
3115 return error(GL_INVALID_ENUM);
3116 }
3117
3118 gl::Context *context = gl::getContext();
3119
3120 if (context)
3121 {
3122 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3123 {
3124 context->stencilFunc = func;
3125 context->stencilRef = ref;
3126 context->stencilMask = mask;
3127 }
3128
3129 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3130 {
3131 context->stencilBackFunc = func;
3132 context->stencilBackRef = ref;
3133 context->stencilBackMask = mask;
3134 }
3135 }
3136 }
3137 catch(std::bad_alloc&)
3138 {
3139 return error(GL_OUT_OF_MEMORY);
3140 }
3141}
3142
3143void __stdcall glStencilMask(GLuint mask)
3144{
3145 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3146}
3147
3148void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3149{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003150 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003151
3152 try
3153 {
3154 switch (face)
3155 {
3156 case GL_FRONT:
3157 case GL_BACK:
3158 case GL_FRONT_AND_BACK:
3159 break;
3160 default:
3161 return error(GL_INVALID_ENUM);
3162 }
3163
3164 gl::Context *context = gl::getContext();
3165
3166 if (context)
3167 {
3168 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3169 {
3170 context->stencilWritemask = mask;
3171 }
3172
3173 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3174 {
3175 context->stencilBackWritemask = mask;
3176 }
3177 }
3178 }
3179 catch(std::bad_alloc&)
3180 {
3181 return error(GL_OUT_OF_MEMORY);
3182 }
3183}
3184
3185void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3186{
3187 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3188}
3189
3190void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3191{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003192 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3193 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003194
3195 try
3196 {
3197 switch (face)
3198 {
3199 case GL_FRONT:
3200 case GL_BACK:
3201 case GL_FRONT_AND_BACK:
3202 break;
3203 default:
3204 return error(GL_INVALID_ENUM);
3205 }
3206
3207 switch (fail)
3208 {
3209 case GL_ZERO:
3210 case GL_KEEP:
3211 case GL_REPLACE:
3212 case GL_INCR:
3213 case GL_DECR:
3214 case GL_INVERT:
3215 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003216 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003217 break;
3218 default:
3219 return error(GL_INVALID_ENUM);
3220 }
3221
3222 switch (zfail)
3223 {
3224 case GL_ZERO:
3225 case GL_KEEP:
3226 case GL_REPLACE:
3227 case GL_INCR:
3228 case GL_DECR:
3229 case GL_INVERT:
3230 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003231 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003232 break;
3233 default:
3234 return error(GL_INVALID_ENUM);
3235 }
3236
3237 switch (zpass)
3238 {
3239 case GL_ZERO:
3240 case GL_KEEP:
3241 case GL_REPLACE:
3242 case GL_INCR:
3243 case GL_DECR:
3244 case GL_INVERT:
3245 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003246 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003247 break;
3248 default:
3249 return error(GL_INVALID_ENUM);
3250 }
3251
3252 gl::Context *context = gl::getContext();
3253
3254 if (context)
3255 {
3256 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3257 {
3258 context->stencilFail = fail;
3259 context->stencilPassDepthFail = zfail;
3260 context->stencilPassDepthPass = zpass;
3261 }
3262
3263 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3264 {
3265 context->stencilBackFail = fail;
3266 context->stencilBackPassDepthFail = zfail;
3267 context->stencilBackPassDepthPass = zpass;
3268 }
3269 }
3270 }
3271 catch(std::bad_alloc&)
3272 {
3273 return error(GL_OUT_OF_MEMORY);
3274 }
3275}
3276
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003277void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3278 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003279{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003280 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 +00003281 "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 +00003282 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003283
3284 try
3285 {
3286 if (level < 0 || width < 0 || height < 0)
3287 {
3288 return error(GL_INVALID_VALUE);
3289 }
3290
3291 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3292 {
3293 return error(GL_INVALID_VALUE);
3294 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003295
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003296 switch (target)
3297 {
3298 case GL_TEXTURE_2D:
3299 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3300 {
3301 return error(GL_INVALID_VALUE);
3302 }
3303 break;
3304 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3305 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3306 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3307 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3308 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3309 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3310 if (!gl::isPow2(width) || !gl::isPow2(height))
3311 {
3312 return error(GL_INVALID_VALUE);
3313 }
3314
3315 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3316 {
3317 return error(GL_INVALID_VALUE);
3318 }
3319 break;
3320 default:
3321 return error(GL_INVALID_ENUM);
3322 }
3323
3324 if (internalformat != format)
3325 {
3326 return error(GL_INVALID_OPERATION);
3327 }
3328
3329 switch (internalformat)
3330 {
3331 case GL_ALPHA:
3332 case GL_LUMINANCE:
3333 case GL_LUMINANCE_ALPHA:
3334 switch (type)
3335 {
3336 case GL_UNSIGNED_BYTE:
3337 break;
3338 default:
3339 return error(GL_INVALID_ENUM);
3340 }
3341 break;
3342 case GL_RGB:
3343 switch (type)
3344 {
3345 case GL_UNSIGNED_BYTE:
3346 case GL_UNSIGNED_SHORT_5_6_5:
3347 break;
3348 default:
3349 return error(GL_INVALID_ENUM);
3350 }
3351 break;
3352 case GL_RGBA:
3353 switch (type)
3354 {
3355 case GL_UNSIGNED_BYTE:
3356 case GL_UNSIGNED_SHORT_4_4_4_4:
3357 case GL_UNSIGNED_SHORT_5_5_5_1:
3358 break;
3359 default:
3360 return error(GL_INVALID_ENUM);
3361 }
3362 break;
3363 default:
3364 return error(GL_INVALID_VALUE);
3365 }
3366
3367 if (border != 0)
3368 {
3369 return error(GL_INVALID_VALUE);
3370 }
3371
3372 gl::Context *context = gl::getContext();
3373
3374 if (context)
3375 {
3376 if (target == GL_TEXTURE_2D)
3377 {
3378 gl::Texture2D *texture = context->getTexture2D();
3379
3380 if (!texture)
3381 {
3382 return error(GL_INVALID_OPERATION);
3383 }
3384
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003385 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003386 }
3387 else
3388 {
3389 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3390
3391 if (!texture)
3392 {
3393 return error(GL_INVALID_OPERATION);
3394 }
3395
3396 switch (target)
3397 {
3398 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003399 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003400 break;
3401 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003402 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003403 break;
3404 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003405 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003406 break;
3407 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003408 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003409 break;
3410 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003411 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003412 break;
3413 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003414 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003415 break;
3416 default: UNREACHABLE();
3417 }
3418 }
3419 }
3420 }
3421 catch(std::bad_alloc&)
3422 {
3423 return error(GL_OUT_OF_MEMORY);
3424 }
3425}
3426
3427void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3428{
3429 glTexParameteri(target, pname, (GLint)param);
3430}
3431
3432void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3433{
3434 glTexParameteri(target, pname, (GLint)*params);
3435}
3436
3437void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3438{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003439 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003440
3441 try
3442 {
3443 gl::Context *context = gl::getContext();
3444
3445 if (context)
3446 {
3447 gl::Texture *texture;
3448
3449 switch (target)
3450 {
3451 case GL_TEXTURE_2D:
3452 texture = context->getTexture2D();
3453 break;
3454 case GL_TEXTURE_CUBE_MAP:
3455 texture = context->getTextureCubeMap();
3456 break;
3457 default:
3458 return error(GL_INVALID_ENUM);
3459 }
3460
3461 switch (pname)
3462 {
3463 case GL_TEXTURE_WRAP_S:
3464 if (!texture->setWrapS((GLenum)param))
3465 {
3466 return error(GL_INVALID_ENUM);
3467 }
3468 break;
3469 case GL_TEXTURE_WRAP_T:
3470 if (!texture->setWrapT((GLenum)param))
3471 {
3472 return error(GL_INVALID_ENUM);
3473 }
3474 break;
3475 case GL_TEXTURE_MIN_FILTER:
3476 if (!texture->setMinFilter((GLenum)param))
3477 {
3478 return error(GL_INVALID_ENUM);
3479 }
3480 break;
3481 case GL_TEXTURE_MAG_FILTER:
3482 if (!texture->setMagFilter((GLenum)param))
3483 {
3484 return error(GL_INVALID_ENUM);
3485 }
3486 break;
3487 default:
3488 return error(GL_INVALID_ENUM);
3489 }
3490 }
3491 }
3492 catch(std::bad_alloc&)
3493 {
3494 return error(GL_OUT_OF_MEMORY);
3495 }
3496}
3497
3498void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3499{
3500 glTexParameteri(target, pname, *params);
3501}
3502
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003503void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3504 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003505{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003506 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3507 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003508 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003509 target, level, xoffset, yoffset, width, height, format, type, pixels);
3510
3511 try
3512 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003513 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
3514 {
3515 return error(GL_INVALID_ENUM);
3516 }
3517
3518 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003519 {
3520 return error(GL_INVALID_VALUE);
3521 }
3522
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003523 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
3524 {
3525 return error(GL_INVALID_VALUE);
3526 }
3527
3528 if (!es2dx::CheckTextureFormatType(format, type))
3529 {
3530 return error(GL_INVALID_ENUM);
3531 }
3532
3533 if (width == 0 || height == 0 || pixels == NULL)
3534 {
3535 return;
3536 }
3537
3538 gl::Context *context = gl::getContext();
3539
3540 if (context)
3541 {
3542 if (target == GL_TEXTURE_2D)
3543 {
3544 gl::Texture2D *texture = context->getTexture2D();
3545
3546 if (!texture)
3547 {
3548 return error(GL_INVALID_OPERATION);
3549 }
3550
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003551 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003552 }
3553 else if (es2dx::IsCubemapTextureTarget(target))
3554 {
3555 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3556
3557 if (!texture)
3558 {
3559 return error(GL_INVALID_OPERATION);
3560 }
3561
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003562 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003563 }
3564 else
3565 {
3566 UNREACHABLE();
3567 }
3568 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003569 }
3570 catch(std::bad_alloc&)
3571 {
3572 return error(GL_OUT_OF_MEMORY);
3573 }
3574}
3575
3576void __stdcall glUniform1f(GLint location, GLfloat x)
3577{
3578 glUniform1fv(location, 1, &x);
3579}
3580
3581void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
3582{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003583 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003584
3585 try
3586 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003587 if (count < 0)
3588 {
3589 return error(GL_INVALID_VALUE);
3590 }
3591
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003592 if (location == -1)
3593 {
3594 return;
3595 }
3596
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003597 gl::Context *context = gl::getContext();
3598
3599 if (context)
3600 {
3601 gl::Program *program = context->getCurrentProgram();
3602
3603 if (!program)
3604 {
3605 return error(GL_INVALID_OPERATION);
3606 }
3607
3608 if (!program->setUniform1fv(location, count, v))
3609 {
3610 return error(GL_INVALID_OPERATION);
3611 }
3612 }
3613 }
3614 catch(std::bad_alloc&)
3615 {
3616 return error(GL_OUT_OF_MEMORY);
3617 }
3618}
3619
3620void __stdcall glUniform1i(GLint location, GLint x)
3621{
3622 glUniform1iv(location, 1, &x);
3623}
3624
3625void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
3626{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003627 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003628
3629 try
3630 {
3631 if (count < 0)
3632 {
3633 return error(GL_INVALID_VALUE);
3634 }
3635
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003636 if (location == -1)
3637 {
3638 return;
3639 }
3640
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003641 gl::Context *context = gl::getContext();
3642
3643 if (context)
3644 {
3645 gl::Program *program = context->getCurrentProgram();
3646
3647 if (!program)
3648 {
3649 return error(GL_INVALID_OPERATION);
3650 }
3651
3652 if (!program->setUniform1iv(location, count, v))
3653 {
3654 return error(GL_INVALID_OPERATION);
3655 }
3656 }
3657 }
3658 catch(std::bad_alloc&)
3659 {
3660 return error(GL_OUT_OF_MEMORY);
3661 }
3662}
3663
3664void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
3665{
3666 GLfloat xy[2] = {x, y};
3667
3668 glUniform2fv(location, 1, (GLfloat*)&xy);
3669}
3670
3671void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
3672{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003673 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003674
3675 try
3676 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003677 if (count < 0)
3678 {
3679 return error(GL_INVALID_VALUE);
3680 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003681
3682 if (location == -1)
3683 {
3684 return;
3685 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003686
3687 gl::Context *context = gl::getContext();
3688
3689 if (context)
3690 {
3691 gl::Program *program = context->getCurrentProgram();
3692
3693 if (!program)
3694 {
3695 return error(GL_INVALID_OPERATION);
3696 }
3697
3698 if (!program->setUniform2fv(location, count, v))
3699 {
3700 return error(GL_INVALID_OPERATION);
3701 }
3702 }
3703 }
3704 catch(std::bad_alloc&)
3705 {
3706 return error(GL_OUT_OF_MEMORY);
3707 }
3708}
3709
3710void __stdcall glUniform2i(GLint location, GLint x, GLint y)
3711{
3712 GLint xy[4] = {x, y};
3713
3714 glUniform2iv(location, 1, (GLint*)&xy);
3715}
3716
3717void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
3718{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003719 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003720
3721 try
3722 {
3723 if (count < 0)
3724 {
3725 return error(GL_INVALID_VALUE);
3726 }
3727
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003728 if (location == -1)
3729 {
3730 return;
3731 }
3732
3733 gl::Context *context = gl::getContext();
3734
3735 if (context)
3736 {
3737 gl::Program *program = context->getCurrentProgram();
3738
3739 if (!program)
3740 {
3741 return error(GL_INVALID_OPERATION);
3742 }
3743
3744 if (!program->setUniform2iv(location, count, v))
3745 {
3746 return error(GL_INVALID_OPERATION);
3747 }
3748 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003749 }
3750 catch(std::bad_alloc&)
3751 {
3752 return error(GL_OUT_OF_MEMORY);
3753 }
3754}
3755
3756void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
3757{
3758 GLfloat xyz[3] = {x, y, z};
3759
3760 glUniform3fv(location, 1, (GLfloat*)&xyz);
3761}
3762
3763void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
3764{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003765 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003766
3767 try
3768 {
3769 if (count < 0)
3770 {
3771 return error(GL_INVALID_VALUE);
3772 }
3773
3774 if (location == -1)
3775 {
3776 return;
3777 }
3778
3779 gl::Context *context = gl::getContext();
3780
3781 if (context)
3782 {
3783 gl::Program *program = context->getCurrentProgram();
3784
3785 if (!program)
3786 {
3787 return error(GL_INVALID_OPERATION);
3788 }
3789
3790 if (!program->setUniform3fv(location, count, v))
3791 {
3792 return error(GL_INVALID_OPERATION);
3793 }
3794 }
3795 }
3796 catch(std::bad_alloc&)
3797 {
3798 return error(GL_OUT_OF_MEMORY);
3799 }
3800}
3801
3802void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
3803{
3804 GLint xyz[3] = {x, y, z};
3805
3806 glUniform3iv(location, 1, (GLint*)&xyz);
3807}
3808
3809void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
3810{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003811 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003812
3813 try
3814 {
3815 if (count < 0)
3816 {
3817 return error(GL_INVALID_VALUE);
3818 }
3819
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003820 if (location == -1)
3821 {
3822 return;
3823 }
3824
3825 gl::Context *context = gl::getContext();
3826
3827 if (context)
3828 {
3829 gl::Program *program = context->getCurrentProgram();
3830
3831 if (!program)
3832 {
3833 return error(GL_INVALID_OPERATION);
3834 }
3835
3836 if (!program->setUniform3iv(location, count, v))
3837 {
3838 return error(GL_INVALID_OPERATION);
3839 }
3840 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003841 }
3842 catch(std::bad_alloc&)
3843 {
3844 return error(GL_OUT_OF_MEMORY);
3845 }
3846}
3847
3848void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3849{
3850 GLfloat xyzw[4] = {x, y, z, w};
3851
3852 glUniform4fv(location, 1, (GLfloat*)&xyzw);
3853}
3854
3855void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
3856{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003857 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003858
3859 try
3860 {
3861 if (count < 0)
3862 {
3863 return error(GL_INVALID_VALUE);
3864 }
3865
3866 if (location == -1)
3867 {
3868 return;
3869 }
3870
3871 gl::Context *context = gl::getContext();
3872
3873 if (context)
3874 {
3875 gl::Program *program = context->getCurrentProgram();
3876
3877 if (!program)
3878 {
3879 return error(GL_INVALID_OPERATION);
3880 }
3881
3882 if (!program->setUniform4fv(location, count, v))
3883 {
3884 return error(GL_INVALID_OPERATION);
3885 }
3886 }
3887 }
3888 catch(std::bad_alloc&)
3889 {
3890 return error(GL_OUT_OF_MEMORY);
3891 }
3892}
3893
3894void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
3895{
3896 GLint xyzw[4] = {x, y, z, w};
3897
3898 glUniform4iv(location, 1, (GLint*)&xyzw);
3899}
3900
3901void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
3902{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003903 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003904
3905 try
3906 {
3907 if (count < 0)
3908 {
3909 return error(GL_INVALID_VALUE);
3910 }
3911
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003912 if (location == -1)
3913 {
3914 return;
3915 }
3916
3917 gl::Context *context = gl::getContext();
3918
3919 if (context)
3920 {
3921 gl::Program *program = context->getCurrentProgram();
3922
3923 if (!program)
3924 {
3925 return error(GL_INVALID_OPERATION);
3926 }
3927
3928 if (!program->setUniform4iv(location, count, v))
3929 {
3930 return error(GL_INVALID_OPERATION);
3931 }
3932 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003933 }
3934 catch(std::bad_alloc&)
3935 {
3936 return error(GL_OUT_OF_MEMORY);
3937 }
3938}
3939
3940void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
3941{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003942 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
3943 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003944
3945 try
3946 {
3947 if (count < 0 || transpose != GL_FALSE)
3948 {
3949 return error(GL_INVALID_VALUE);
3950 }
3951
3952 if (location == -1)
3953 {
3954 return;
3955 }
3956
3957 gl::Context *context = gl::getContext();
3958
3959 if (context)
3960 {
3961 gl::Program *program = context->getCurrentProgram();
3962
3963 if (!program)
3964 {
3965 return error(GL_INVALID_OPERATION);
3966 }
3967
3968 if (!program->setUniformMatrix2fv(location, count, value))
3969 {
3970 return error(GL_INVALID_OPERATION);
3971 }
3972 }
3973 }
3974 catch(std::bad_alloc&)
3975 {
3976 return error(GL_OUT_OF_MEMORY);
3977 }
3978}
3979
3980void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
3981{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003982 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
3983 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003984
3985 try
3986 {
3987 if (count < 0 || transpose != GL_FALSE)
3988 {
3989 return error(GL_INVALID_VALUE);
3990 }
3991
3992 if (location == -1)
3993 {
3994 return;
3995 }
3996
3997 gl::Context *context = gl::getContext();
3998
3999 if (context)
4000 {
4001 gl::Program *program = context->getCurrentProgram();
4002
4003 if (!program)
4004 {
4005 return error(GL_INVALID_OPERATION);
4006 }
4007
4008 if (!program->setUniformMatrix3fv(location, count, value))
4009 {
4010 return error(GL_INVALID_OPERATION);
4011 }
4012 }
4013 }
4014 catch(std::bad_alloc&)
4015 {
4016 return error(GL_OUT_OF_MEMORY);
4017 }
4018}
4019
4020void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4021{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004022 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4023 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004024
4025 try
4026 {
4027 if (count < 0 || transpose != GL_FALSE)
4028 {
4029 return error(GL_INVALID_VALUE);
4030 }
4031
4032 if (location == -1)
4033 {
4034 return;
4035 }
4036
4037 gl::Context *context = gl::getContext();
4038
4039 if (context)
4040 {
4041 gl::Program *program = context->getCurrentProgram();
4042
4043 if (!program)
4044 {
4045 return error(GL_INVALID_OPERATION);
4046 }
4047
4048 if (!program->setUniformMatrix4fv(location, count, value))
4049 {
4050 return error(GL_INVALID_OPERATION);
4051 }
4052 }
4053 }
4054 catch(std::bad_alloc&)
4055 {
4056 return error(GL_OUT_OF_MEMORY);
4057 }
4058}
4059
4060void __stdcall glUseProgram(GLuint program)
4061{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004062 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004063
4064 try
4065 {
4066 gl::Context *context = gl::getContext();
4067
4068 if (context)
4069 {
4070 gl::Program *programObject = context->getProgram(program);
4071
4072 if (programObject && !programObject->isLinked())
4073 {
4074 return error(GL_INVALID_OPERATION);
4075 }
4076
4077 context->useProgram(program);
4078 }
4079 }
4080 catch(std::bad_alloc&)
4081 {
4082 return error(GL_OUT_OF_MEMORY);
4083 }
4084}
4085
4086void __stdcall glValidateProgram(GLuint program)
4087{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004088 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004089
4090 try
4091 {
4092 UNIMPLEMENTED(); // FIXME
4093 }
4094 catch(std::bad_alloc&)
4095 {
4096 return error(GL_OUT_OF_MEMORY);
4097 }
4098}
4099
4100void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4101{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004102 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004103
4104 try
4105 {
4106 if (index >= gl::MAX_VERTEX_ATTRIBS)
4107 {
4108 return error(GL_INVALID_VALUE);
4109 }
4110
4111 UNIMPLEMENTED(); // FIXME
4112 }
4113 catch(std::bad_alloc&)
4114 {
4115 return error(GL_OUT_OF_MEMORY);
4116 }
4117}
4118
4119void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4120{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004121 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004122
4123 try
4124 {
4125 if (index >= gl::MAX_VERTEX_ATTRIBS)
4126 {
4127 return error(GL_INVALID_VALUE);
4128 }
4129
4130 UNIMPLEMENTED(); // FIXME
4131 }
4132 catch(std::bad_alloc&)
4133 {
4134 return error(GL_OUT_OF_MEMORY);
4135 }
4136}
4137
4138void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4139{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004140 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004141
4142 try
4143 {
4144 if (index >= gl::MAX_VERTEX_ATTRIBS)
4145 {
4146 return error(GL_INVALID_VALUE);
4147 }
4148
4149 UNIMPLEMENTED(); // FIXME
4150 }
4151 catch(std::bad_alloc&)
4152 {
4153 return error(GL_OUT_OF_MEMORY);
4154 }
4155}
4156
4157void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4158{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004159 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004160
4161 try
4162 {
4163 if (index >= gl::MAX_VERTEX_ATTRIBS)
4164 {
4165 return error(GL_INVALID_VALUE);
4166 }
4167
4168 UNIMPLEMENTED(); // FIXME
4169 }
4170 catch(std::bad_alloc&)
4171 {
4172 return error(GL_OUT_OF_MEMORY);
4173 }
4174}
4175
4176void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4177{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004178 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 +00004179
4180 try
4181 {
4182 if (index >= gl::MAX_VERTEX_ATTRIBS)
4183 {
4184 return error(GL_INVALID_VALUE);
4185 }
4186
4187 UNIMPLEMENTED(); // FIXME
4188 }
4189 catch(std::bad_alloc&)
4190 {
4191 return error(GL_OUT_OF_MEMORY);
4192 }
4193}
4194
4195void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4196{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004197 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004198
4199 try
4200 {
4201 if (index >= gl::MAX_VERTEX_ATTRIBS)
4202 {
4203 return error(GL_INVALID_VALUE);
4204 }
4205
4206 UNIMPLEMENTED(); // FIXME
4207 }
4208 catch(std::bad_alloc&)
4209 {
4210 return error(GL_OUT_OF_MEMORY);
4211 }
4212}
4213
4214void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4215{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004216 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 +00004217
4218 try
4219 {
4220 if (index >= gl::MAX_VERTEX_ATTRIBS)
4221 {
4222 return error(GL_INVALID_VALUE);
4223 }
4224
4225 UNIMPLEMENTED(); // FIXME
4226 }
4227 catch(std::bad_alloc&)
4228 {
4229 return error(GL_OUT_OF_MEMORY);
4230 }
4231}
4232
4233void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4234{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004235 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004236
4237 try
4238 {
4239 if (index >= gl::MAX_VERTEX_ATTRIBS)
4240 {
4241 return error(GL_INVALID_VALUE);
4242 }
4243
4244 UNIMPLEMENTED(); // FIXME
4245 }
4246 catch(std::bad_alloc&)
4247 {
4248 return error(GL_OUT_OF_MEMORY);
4249 }
4250}
4251
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004252void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004253{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004254 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004255 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004256 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004257
4258 try
4259 {
4260 if (index >= gl::MAX_VERTEX_ATTRIBS)
4261 {
4262 return error(GL_INVALID_VALUE);
4263 }
4264
4265 if (size < 1 || size > 4)
4266 {
4267 return error(GL_INVALID_VALUE);
4268 }
4269
4270 switch (type)
4271 {
4272 case GL_BYTE:
4273 case GL_UNSIGNED_BYTE:
4274 case GL_SHORT:
4275 case GL_UNSIGNED_SHORT:
4276 case GL_FIXED:
4277 case GL_FLOAT:
4278 break;
4279 default:
4280 return error(GL_INVALID_ENUM);
4281 }
4282
4283 if (stride < 0)
4284 {
4285 return error(GL_INVALID_VALUE);
4286 }
4287
4288 gl::Context *context = gl::getContext();
4289
4290 if (context)
4291 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004292 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4293 context->vertexAttribute[index].mSize = size;
4294 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004295 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004296 context->vertexAttribute[index].mStride = stride;
4297 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004298 }
4299 }
4300 catch(std::bad_alloc&)
4301 {
4302 return error(GL_OUT_OF_MEMORY);
4303 }
4304}
4305
4306void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4307{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004308 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 +00004309
4310 try
4311 {
4312 if (width < 0 || height < 0)
4313 {
4314 return error(GL_INVALID_VALUE);
4315 }
4316
4317 gl::Context *context = gl::getContext();
4318
4319 if (context)
4320 {
4321 context->viewportX = x;
4322 context->viewportY = y;
4323 context->viewportWidth = width;
4324 context->viewportHeight = height;
4325 }
4326 }
4327 catch(std::bad_alloc&)
4328 {
4329 return error(GL_OUT_OF_MEMORY);
4330 }
4331}
4332
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004333void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4334 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004335{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004336 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4337 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004338 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004339 target, level, internalformat, width, height, depth, border, format, type, pixels);
4340
4341 try
4342 {
4343 UNIMPLEMENTED(); // FIXME
4344 }
4345 catch(std::bad_alloc&)
4346 {
4347 return error(GL_OUT_OF_MEMORY);
4348 }
4349}
4350}