blob: ecd8bef00e0f0f43d75c82b0ed6bbf3f0567b379 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016#include "Context.h"
17#include "main.h"
18#include "Program.h"
19#include "Shader.h"
20#include "Buffer.h"
21#include "Texture.h"
22#include "Renderbuffer.h"
23#include "Framebuffer.h"
24#include "mathutil.h"
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000025#include "common/debug.h"
daniel@transgaming.com00c75962010-03-11 20:36:15 +000026#include "utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027
28extern "C"
29{
30
31void __stdcall glActiveTexture(GLenum texture)
32{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000033 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034
35 try
36 {
37 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
38 {
39 return error(GL_INVALID_ENUM);
40 }
41
42 gl::Context *context = gl::getContext();
43
44 if (context)
45 {
46 context->activeSampler = texture - GL_TEXTURE0;
47 }
48 }
49 catch(std::bad_alloc&)
50 {
51 return error(GL_OUT_OF_MEMORY);
52 }
53}
54
55void __stdcall glAttachShader(GLuint program, GLuint shader)
56{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000057 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000058
59 try
60 {
61 gl::Context *context = gl::getContext();
62
63 if (context)
64 {
65 gl::Program *programObject = context->getProgram(program);
66 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000067
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000068 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000069 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000070 if (context->getShader(program))
71 {
72 return error(GL_INVALID_OPERATION);
73 }
74 else
75 {
76 return error(GL_INVALID_VALUE);
77 }
78 }
79
80 if (!shaderObject)
81 {
82 if (context->getProgram(shader))
83 {
84 return error(GL_INVALID_OPERATION);
85 }
86 else
87 {
88 return error(GL_INVALID_VALUE);
89 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090 }
91
92 if (!programObject->attachShader(shaderObject))
93 {
94 return error(GL_INVALID_OPERATION);
95 }
96 }
97 }
98 catch(std::bad_alloc&)
99 {
100 return error(GL_OUT_OF_MEMORY);
101 }
102}
103
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000104void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000105{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000106 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107
108 try
109 {
110 if (index >= gl::MAX_VERTEX_ATTRIBS)
111 {
112 return error(GL_INVALID_VALUE);
113 }
114
115 gl::Context *context = gl::getContext();
116
117 if (context)
118 {
119 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000120
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000121 if (!programObject)
122 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000123 if (context->getShader(program))
124 {
125 return error(GL_INVALID_OPERATION);
126 }
127 else
128 {
129 return error(GL_INVALID_VALUE);
130 }
131 }
132
133 if (strncmp(name, "gl_", 3) == 0)
134 {
135 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000136 }
137
138 programObject->bindAttributeLocation(index, name);
139 }
140 }
141 catch(std::bad_alloc&)
142 {
143 return error(GL_OUT_OF_MEMORY);
144 }
145}
146
147void __stdcall glBindBuffer(GLenum target, GLuint buffer)
148{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000149 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150
151 try
152 {
153 gl::Context *context = gl::getContext();
154
155 if (context)
156 {
157 switch (target)
158 {
159 case GL_ARRAY_BUFFER:
160 context->bindArrayBuffer(buffer);
161 return;
162 case GL_ELEMENT_ARRAY_BUFFER:
163 context->bindElementArrayBuffer(buffer);
164 return;
165 default:
166 return error(GL_INVALID_ENUM);
167 }
168 }
169 }
170 catch(std::bad_alloc&)
171 {
172 return error(GL_OUT_OF_MEMORY);
173 }
174}
175
176void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
177{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000178 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000179
180 try
181 {
182 if (target != GL_FRAMEBUFFER)
183 {
184 return error(GL_INVALID_ENUM);
185 }
186
187 gl::Context *context = gl::getContext();
188
189 if (context)
190 {
191 context->bindFramebuffer(framebuffer);
192 }
193 }
194 catch(std::bad_alloc&)
195 {
196 return error(GL_OUT_OF_MEMORY);
197 }
198}
199
200void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
201{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000202 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203
204 try
205 {
206 if (target != GL_RENDERBUFFER)
207 {
208 return error(GL_INVALID_ENUM);
209 }
210
211 gl::Context *context = gl::getContext();
212
213 if (context)
214 {
215 context->bindRenderbuffer(renderbuffer);
216 }
217 }
218 catch(std::bad_alloc&)
219 {
220 return error(GL_OUT_OF_MEMORY);
221 }
222}
223
224void __stdcall glBindTexture(GLenum target, GLuint texture)
225{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000226 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227
228 try
229 {
230 gl::Context *context = gl::getContext();
231
232 if (context)
233 {
234 gl::Texture *textureObject = context->getTexture(texture);
235
236 if (textureObject && textureObject->getTarget() != target && texture != 0)
237 {
238 return error(GL_INVALID_OPERATION);
239 }
240
241 switch (target)
242 {
243 case GL_TEXTURE_2D:
244 context->bindTexture2D(texture);
245 return;
246 case GL_TEXTURE_CUBE_MAP:
247 context->bindTextureCubeMap(texture);
248 return;
249 default:
250 return error(GL_INVALID_ENUM);
251 }
252 }
253 }
254 catch(std::bad_alloc&)
255 {
256 return error(GL_OUT_OF_MEMORY);
257 }
258}
259
260void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
261{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000262 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
263 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264
265 try
266 {
267 gl::Context* context = gl::getContext();
268
269 if (context)
270 {
271 context->blendColor.red = gl::clamp01(red);
272 context->blendColor.blue = gl::clamp01(blue);
273 context->blendColor.green = gl::clamp01(green);
274 context->blendColor.alpha = gl::clamp01(alpha);
275 }
276 }
277 catch(std::bad_alloc&)
278 {
279 return error(GL_OUT_OF_MEMORY);
280 }
281}
282
283void __stdcall glBlendEquation(GLenum mode)
284{
285 glBlendEquationSeparate(mode, mode);
286}
287
288void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
289{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000290 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000291
292 try
293 {
294 switch (modeRGB)
295 {
296 case GL_FUNC_ADD:
297 case GL_FUNC_SUBTRACT:
298 case GL_FUNC_REVERSE_SUBTRACT:
299 break;
300 default:
301 return error(GL_INVALID_ENUM);
302 }
303
304 switch (modeAlpha)
305 {
306 case GL_FUNC_ADD:
307 case GL_FUNC_SUBTRACT:
308 case GL_FUNC_REVERSE_SUBTRACT:
309 break;
310 default:
311 return error(GL_INVALID_ENUM);
312 }
313
314 gl::Context *context = gl::getContext();
315
316 if (context)
317 {
318 context->blendEquationRGB = modeRGB;
319 context->blendEquationAlpha = modeAlpha;
320 }
321 }
322 catch(std::bad_alloc&)
323 {
324 return error(GL_OUT_OF_MEMORY);
325 }
326}
327
328void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
329{
330 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
331}
332
333void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
334{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000335 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
336 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000337
338 try
339 {
340 switch (srcRGB)
341 {
342 case GL_ZERO:
343 case GL_ONE:
344 case GL_SRC_COLOR:
345 case GL_ONE_MINUS_SRC_COLOR:
346 case GL_DST_COLOR:
347 case GL_ONE_MINUS_DST_COLOR:
348 case GL_SRC_ALPHA:
349 case GL_ONE_MINUS_SRC_ALPHA:
350 case GL_DST_ALPHA:
351 case GL_ONE_MINUS_DST_ALPHA:
352 case GL_CONSTANT_COLOR:
353 case GL_ONE_MINUS_CONSTANT_COLOR:
354 case GL_CONSTANT_ALPHA:
355 case GL_ONE_MINUS_CONSTANT_ALPHA:
356 case GL_SRC_ALPHA_SATURATE:
357 break;
358 default:
359 return error(GL_INVALID_ENUM);
360 }
361
362 switch (dstRGB)
363 {
364 case GL_ZERO:
365 case GL_ONE:
366 case GL_SRC_COLOR:
367 case GL_ONE_MINUS_SRC_COLOR:
368 case GL_DST_COLOR:
369 case GL_ONE_MINUS_DST_COLOR:
370 case GL_SRC_ALPHA:
371 case GL_ONE_MINUS_SRC_ALPHA:
372 case GL_DST_ALPHA:
373 case GL_ONE_MINUS_DST_ALPHA:
374 case GL_CONSTANT_COLOR:
375 case GL_ONE_MINUS_CONSTANT_COLOR:
376 case GL_CONSTANT_ALPHA:
377 case GL_ONE_MINUS_CONSTANT_ALPHA:
378 break;
379 default:
380 return error(GL_INVALID_ENUM);
381 }
382
383 switch (srcAlpha)
384 {
385 case GL_ZERO:
386 case GL_ONE:
387 case GL_SRC_COLOR:
388 case GL_ONE_MINUS_SRC_COLOR:
389 case GL_DST_COLOR:
390 case GL_ONE_MINUS_DST_COLOR:
391 case GL_SRC_ALPHA:
392 case GL_ONE_MINUS_SRC_ALPHA:
393 case GL_DST_ALPHA:
394 case GL_ONE_MINUS_DST_ALPHA:
395 case GL_CONSTANT_COLOR:
396 case GL_ONE_MINUS_CONSTANT_COLOR:
397 case GL_CONSTANT_ALPHA:
398 case GL_ONE_MINUS_CONSTANT_ALPHA:
399 case GL_SRC_ALPHA_SATURATE:
400 break;
401 default:
402 return error(GL_INVALID_ENUM);
403 }
404
405 switch (dstAlpha)
406 {
407 case GL_ZERO:
408 case GL_ONE:
409 case GL_SRC_COLOR:
410 case GL_ONE_MINUS_SRC_COLOR:
411 case GL_DST_COLOR:
412 case GL_ONE_MINUS_DST_COLOR:
413 case GL_SRC_ALPHA:
414 case GL_ONE_MINUS_SRC_ALPHA:
415 case GL_DST_ALPHA:
416 case GL_ONE_MINUS_DST_ALPHA:
417 case GL_CONSTANT_COLOR:
418 case GL_ONE_MINUS_CONSTANT_COLOR:
419 case GL_CONSTANT_ALPHA:
420 case GL_ONE_MINUS_CONSTANT_ALPHA:
421 break;
422 default:
423 return error(GL_INVALID_ENUM);
424 }
425
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000426 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
427 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
428
429 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
430 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
431
432 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000433 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000434 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
435 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000436 }
437
438 gl::Context *context = gl::getContext();
439
440 if (context)
441 {
442 context->sourceBlendRGB = srcRGB;
443 context->sourceBlendAlpha = srcAlpha;
444 context->destBlendRGB = dstRGB;
445 context->destBlendAlpha = dstAlpha;
446 }
447 }
448 catch(std::bad_alloc&)
449 {
450 return error(GL_OUT_OF_MEMORY);
451 }
452}
453
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000454void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000455{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000456 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000457 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000458
459 try
460 {
461 if (size < 0)
462 {
463 return error(GL_INVALID_VALUE);
464 }
465
466 switch (usage)
467 {
468 case GL_STREAM_DRAW:
469 case GL_STATIC_DRAW:
470 case GL_DYNAMIC_DRAW:
471 break;
472 default:
473 return error(GL_INVALID_ENUM);
474 }
475
476 gl::Context *context = gl::getContext();
477
478 if (context)
479 {
480 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000481
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000482 switch (target)
483 {
484 case GL_ARRAY_BUFFER:
485 buffer = context->getArrayBuffer();
486 break;
487 case GL_ELEMENT_ARRAY_BUFFER:
488 buffer = context->getElementArrayBuffer();
489 break;
490 default:
491 return error(GL_INVALID_ENUM);
492 }
493
494 if (!buffer)
495 {
496 return error(GL_INVALID_OPERATION);
497 }
498
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000499 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000500 }
501 }
502 catch(std::bad_alloc&)
503 {
504 return error(GL_OUT_OF_MEMORY);
505 }
506}
507
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000508void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000509{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000510 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000511 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512
513 try
514 {
515 if (size < 0)
516 {
517 return error(GL_INVALID_VALUE);
518 }
519
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000520 if (data == NULL)
521 {
522 return;
523 }
524
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000525 gl::Context *context = gl::getContext();
526
527 if (context)
528 {
529 gl::Buffer *buffer;
530
531 switch (target)
532 {
533 case GL_ARRAY_BUFFER:
534 buffer = context->getArrayBuffer();
535 break;
536 case GL_ELEMENT_ARRAY_BUFFER:
537 buffer = context->getElementArrayBuffer();
538 break;
539 default:
540 return error(GL_INVALID_ENUM);
541 }
542
543 if (!buffer)
544 {
545 return error(GL_INVALID_OPERATION);
546 }
547
548 GLenum err = buffer->bufferSubData(data, size, offset);
549
550 if (err != GL_NO_ERROR)
551 {
552 return error(err);
553 }
554 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000555 }
556 catch(std::bad_alloc&)
557 {
558 return error(GL_OUT_OF_MEMORY);
559 }
560}
561
562GLenum __stdcall glCheckFramebufferStatus(GLenum target)
563{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000564 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000565
566 try
567 {
568 if (target != GL_FRAMEBUFFER)
569 {
570 return error(GL_INVALID_ENUM, 0);
571 }
572
573 gl::Context *context = gl::getContext();
574
575 if (context)
576 {
577 gl::Framebuffer *framebuffer = context->getFramebuffer();
578
579 return framebuffer->completeness();
580 }
581 }
582 catch(std::bad_alloc&)
583 {
584 return error(GL_OUT_OF_MEMORY, 0);
585 }
586
587 return 0;
588}
589
590void __stdcall glClear(GLbitfield mask)
591{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000592 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000593
594 try
595 {
596 gl::Context *context = gl::getContext();
597
598 if (context)
599 {
600 context->clear(mask);
601 }
602 }
603 catch(std::bad_alloc&)
604 {
605 return error(GL_OUT_OF_MEMORY);
606 }
607}
608
609void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
610{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000611 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
612 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000613
614 try
615 {
616 gl::Context *context = gl::getContext();
617
618 if (context)
619 {
620 context->setClearColor(red, green, blue, alpha);
621 }
622 }
623 catch(std::bad_alloc&)
624 {
625 return error(GL_OUT_OF_MEMORY);
626 }
627}
628
629void __stdcall glClearDepthf(GLclampf depth)
630{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000631 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000632
633 try
634 {
635 gl::Context *context = gl::getContext();
636
637 if (context)
638 {
639 context->setClearDepth(depth);
640 }
641 }
642 catch(std::bad_alloc&)
643 {
644 return error(GL_OUT_OF_MEMORY);
645 }
646}
647
648void __stdcall glClearStencil(GLint s)
649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000650 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000651
652 try
653 {
654 gl::Context *context = gl::getContext();
655
656 if (context)
657 {
658 context->setClearStencil(s);
659 }
660 }
661 catch(std::bad_alloc&)
662 {
663 return error(GL_OUT_OF_MEMORY);
664 }
665}
666
667void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
668{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000669 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
670 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000671
672 try
673 {
674 gl::Context *context = gl::getContext();
675
676 if (context)
677 {
678 context->colorMaskRed = red != GL_FALSE;
679 context->colorMaskGreen = green != GL_FALSE;
680 context->colorMaskBlue = blue != GL_FALSE;
681 context->colorMaskAlpha = alpha != GL_FALSE;
682 }
683 }
684 catch(std::bad_alloc&)
685 {
686 return error(GL_OUT_OF_MEMORY);
687 }
688}
689
690void __stdcall glCompileShader(GLuint shader)
691{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000692 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000693
694 try
695 {
696 gl::Context *context = gl::getContext();
697
698 if (context)
699 {
700 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000701
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000702 if (!shaderObject)
703 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000704 if (context->getProgram(shader))
705 {
706 return error(GL_INVALID_OPERATION);
707 }
708 else
709 {
710 return error(GL_INVALID_VALUE);
711 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000712 }
713
714 shaderObject->compile();
715 }
716 }
717 catch(std::bad_alloc&)
718 {
719 return error(GL_OUT_OF_MEMORY);
720 }
721}
722
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000723void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
724 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000725{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000726 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000727 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000728 target, level, internalformat, width, height, border, imageSize, data);
729
730 try
731 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000732 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
733 {
734 return error(GL_INVALID_ENUM);
735 }
736
737 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000738 {
739 return error(GL_INVALID_VALUE);
740 }
741
daniel@transgaming.com41430492010-03-11 20:36:18 +0000742 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
743 {
744 return error(GL_INVALID_VALUE);
745 }
746
747 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748 }
749 catch(std::bad_alloc&)
750 {
751 return error(GL_OUT_OF_MEMORY);
752 }
753}
754
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000755void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
756 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000757{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000758 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
759 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000760 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000761 target, level, xoffset, yoffset, width, height, format, imageSize, data);
762
763 try
764 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000765 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
766 {
767 return error(GL_INVALID_ENUM);
768 }
769
770 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000771 {
772 return error(GL_INVALID_VALUE);
773 }
774
daniel@transgaming.com41430492010-03-11 20:36:18 +0000775 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
776 {
777 return error(GL_INVALID_VALUE);
778 }
779
780 if (xoffset != 0 || yoffset != 0)
781 {
782 return error(GL_INVALID_OPERATION);
783 }
784
785 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000786 }
787 catch(std::bad_alloc&)
788 {
789 return error(GL_OUT_OF_MEMORY);
790 }
791}
792
793void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
794{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000795 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
796 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000797 target, level, internalformat, x, y, width, height, border);
798
799 try
800 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000801 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000802 {
803 return error(GL_INVALID_VALUE);
804 }
805
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000806 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
807 {
808 return error(GL_INVALID_VALUE);
809 }
810
811 switch (target)
812 {
813 case GL_TEXTURE_2D:
814 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
815 {
816 return error(GL_INVALID_VALUE);
817 }
818 break;
819 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
820 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
821 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
822 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
823 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
824 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
825 if (!gl::isPow2(width) || !gl::isPow2(height))
826 {
827 return error(GL_INVALID_VALUE);
828 }
829
830 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
831 {
832 return error(GL_INVALID_VALUE);
833 }
834 break;
835 default:
836 return error(GL_INVALID_ENUM);
837 }
838
839 switch (internalformat)
840 {
841 case GL_ALPHA:
842 case GL_LUMINANCE:
843 case GL_LUMINANCE_ALPHA:
844 case GL_RGB:
845 case GL_RGBA:
846 break;
847 default:
848 return error(GL_INVALID_VALUE);
849 }
850
851 if (border != 0)
852 {
853 return error(GL_INVALID_VALUE);
854 }
855
856 gl::Context *context = gl::getContext();
857
858 if (context)
859 {
860 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
861
862 if (target == GL_TEXTURE_2D)
863 {
864 gl::Texture2D *texture = context->getTexture2D();
865
866 if (!texture)
867 {
868 return error(GL_INVALID_OPERATION);
869 }
870
871 texture->copyImage(level, internalformat, x, y, width, height, source);
872 }
873 else if (es2dx::IsCubemapTextureTarget(target))
874 {
875 gl::TextureCubeMap *texture = context->getTextureCubeMap();
876
877 if (!texture)
878 {
879 return error(GL_INVALID_OPERATION);
880 }
881
882 texture->copyImage(target, level, internalformat, x, y, width, height, source);
883 }
884 else
885 {
886 UNREACHABLE();
887 }
888 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000889 }
890 catch(std::bad_alloc&)
891 {
892 return error(GL_OUT_OF_MEMORY);
893 }
894}
895
896void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
897{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000898 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
899 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000900 target, level, xoffset, yoffset, x, y, width, height);
901
902 try
903 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000904 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
905 {
906 return error(GL_INVALID_ENUM);
907 }
908
909 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000910 {
911 return error(GL_INVALID_VALUE);
912 }
913
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000914 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
915 {
916 return error(GL_INVALID_VALUE);
917 }
918
919 if (width == 0 || height == 0)
920 {
921 return;
922 }
923
924 gl::Context *context = gl::getContext();
925
926 if (context)
927 {
928 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
929
930 if (target == GL_TEXTURE_2D)
931 {
932 gl::Texture2D *texture = context->getTexture2D();
933
934 if (!texture)
935 {
936 return error(GL_INVALID_OPERATION);
937 }
938
939 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
940 }
941 else if (es2dx::IsCubemapTextureTarget(target))
942 {
943 gl::TextureCubeMap *texture = context->getTextureCubeMap();
944
945 if (!texture)
946 {
947 return error(GL_INVALID_OPERATION);
948 }
949
950 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
951 }
952 else
953 {
954 UNREACHABLE();
955 }
956 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000957 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000958
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000959 catch(std::bad_alloc&)
960 {
961 return error(GL_OUT_OF_MEMORY);
962 }
963}
964
965GLuint __stdcall glCreateProgram(void)
966{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000967 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000968
969 try
970 {
971 gl::Context *context = gl::getContext();
972
973 if (context)
974 {
975 return context->createProgram();
976 }
977 }
978 catch(std::bad_alloc&)
979 {
980 return error(GL_OUT_OF_MEMORY, 0);
981 }
982
983 return 0;
984}
985
986GLuint __stdcall glCreateShader(GLenum type)
987{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000988 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000989
990 try
991 {
992 gl::Context *context = gl::getContext();
993
994 if (context)
995 {
996 switch (type)
997 {
998 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000999 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001000 return context->createShader(type);
1001 default:
1002 return error(GL_INVALID_ENUM, 0);
1003 }
1004 }
1005 }
1006 catch(std::bad_alloc&)
1007 {
1008 return error(GL_OUT_OF_MEMORY, 0);
1009 }
1010
1011 return 0;
1012}
1013
1014void __stdcall glCullFace(GLenum mode)
1015{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001016 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001017
1018 try
1019 {
1020 switch (mode)
1021 {
1022 case GL_FRONT:
1023 case GL_BACK:
1024 case GL_FRONT_AND_BACK:
1025 {
1026 gl::Context *context = gl::getContext();
1027
1028 if (context)
1029 {
1030 context->cullMode = mode;
1031 }
1032 }
1033 break;
1034 default:
1035 return error(GL_INVALID_ENUM);
1036 }
1037 }
1038 catch(std::bad_alloc&)
1039 {
1040 return error(GL_OUT_OF_MEMORY);
1041 }
1042}
1043
1044void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1045{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001046 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001047
1048 try
1049 {
1050 if (n < 0)
1051 {
1052 return error(GL_INVALID_VALUE);
1053 }
1054
1055 gl::Context *context = gl::getContext();
1056
1057 if (context)
1058 {
1059 for (int i = 0; i < n; i++)
1060 {
1061 context->deleteBuffer(buffers[i]);
1062 }
1063 }
1064 }
1065 catch(std::bad_alloc&)
1066 {
1067 return error(GL_OUT_OF_MEMORY);
1068 }
1069}
1070
1071void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1072{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001073 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001074
1075 try
1076 {
1077 if (n < 0)
1078 {
1079 return error(GL_INVALID_VALUE);
1080 }
1081
1082 gl::Context *context = gl::getContext();
1083
1084 if (context)
1085 {
1086 for (int i = 0; i < n; i++)
1087 {
1088 if (framebuffers[i] != 0)
1089 {
1090 context->deleteFramebuffer(framebuffers[i]);
1091 }
1092 }
1093 }
1094 }
1095 catch(std::bad_alloc&)
1096 {
1097 return error(GL_OUT_OF_MEMORY);
1098 }
1099}
1100
1101void __stdcall glDeleteProgram(GLuint program)
1102{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001103 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001104
1105 try
1106 {
1107 gl::Context *context = gl::getContext();
1108
1109 if (context)
1110 {
1111 context->deleteProgram(program);
1112 }
1113 }
1114 catch(std::bad_alloc&)
1115 {
1116 return error(GL_OUT_OF_MEMORY);
1117 }
1118}
1119
1120void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1121{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001122 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001123
1124 try
1125 {
1126 if (n < 0)
1127 {
1128 return error(GL_INVALID_VALUE);
1129 }
1130
1131 gl::Context *context = gl::getContext();
1132
1133 if (context)
1134 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001135 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001136 {
1137 context->deleteRenderbuffer(renderbuffers[i]);
1138 }
1139 }
1140 }
1141 catch(std::bad_alloc&)
1142 {
1143 return error(GL_OUT_OF_MEMORY);
1144 }
1145}
1146
1147void __stdcall glDeleteShader(GLuint shader)
1148{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001149 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001150
1151 try
1152 {
1153 gl::Context *context = gl::getContext();
1154
1155 if (context)
1156 {
1157 context->deleteShader(shader);
1158 }
1159 }
1160 catch(std::bad_alloc&)
1161 {
1162 return error(GL_OUT_OF_MEMORY);
1163 }
1164}
1165
1166void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1167{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001168 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001169
1170 try
1171 {
1172 if (n < 0)
1173 {
1174 return error(GL_INVALID_VALUE);
1175 }
1176
1177 gl::Context *context = gl::getContext();
1178
1179 if (context)
1180 {
1181 for (int i = 0; i < n; i++)
1182 {
1183 if (textures[i] != 0)
1184 {
1185 context->deleteTexture(textures[i]);
1186 }
1187 }
1188 }
1189 }
1190 catch(std::bad_alloc&)
1191 {
1192 return error(GL_OUT_OF_MEMORY);
1193 }
1194}
1195
1196void __stdcall glDepthFunc(GLenum func)
1197{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001198 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001199
1200 try
1201 {
1202 switch (func)
1203 {
1204 case GL_NEVER:
1205 case GL_ALWAYS:
1206 case GL_LESS:
1207 case GL_LEQUAL:
1208 case GL_EQUAL:
1209 case GL_GREATER:
1210 case GL_GEQUAL:
1211 case GL_NOTEQUAL:
1212 break;
1213 default:
1214 return error(GL_INVALID_ENUM);
1215 }
1216
1217 gl::Context *context = gl::getContext();
1218
1219 if (context)
1220 {
1221 context->depthFunc = func;
1222 }
1223 }
1224 catch(std::bad_alloc&)
1225 {
1226 return error(GL_OUT_OF_MEMORY);
1227 }
1228}
1229
1230void __stdcall glDepthMask(GLboolean flag)
1231{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001232 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001233
1234 try
1235 {
1236 gl::Context *context = gl::getContext();
1237
1238 if (context)
1239 {
1240 context->depthMask = flag != GL_FALSE;
1241 }
1242 }
1243 catch(std::bad_alloc&)
1244 {
1245 return error(GL_OUT_OF_MEMORY);
1246 }
1247}
1248
1249void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1250{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001251 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001252
1253 try
1254 {
1255 gl::Context *context = gl::getContext();
1256
1257 if (context)
1258 {
1259 context->zNear = zNear;
1260 context->zFar = zFar;
1261 }
1262 }
1263 catch(std::bad_alloc&)
1264 {
1265 return error(GL_OUT_OF_MEMORY);
1266 }
1267}
1268
1269void __stdcall glDetachShader(GLuint program, GLuint shader)
1270{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001271 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001272
1273 try
1274 {
1275 gl::Context *context = gl::getContext();
1276
1277 if (context)
1278 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001279
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001280 gl::Program *programObject = context->getProgram(program);
1281 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001282
1283 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001284 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001285 gl::Shader *shaderByProgramHandle;
1286 shaderByProgramHandle = context->getShader(program);
1287 if (!shaderByProgramHandle)
1288 {
1289 return error(GL_INVALID_VALUE);
1290 }
1291 else
1292 {
1293 return error(GL_INVALID_OPERATION);
1294 }
1295 }
1296
1297 if (!shaderObject)
1298 {
1299 gl::Program *programByShaderHandle = context->getProgram(shader);
1300 if (!programByShaderHandle)
1301 {
1302 return error(GL_INVALID_VALUE);
1303 }
1304 else
1305 {
1306 return error(GL_INVALID_OPERATION);
1307 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001308 }
1309
1310 if (!programObject->detachShader(shaderObject))
1311 {
1312 return error(GL_INVALID_OPERATION);
1313 }
1314
1315 if (shaderObject->isDeletable())
1316 {
1317 context->deleteShader(shader);
1318 }
1319 }
1320 }
1321 catch(std::bad_alloc&)
1322 {
1323 return error(GL_OUT_OF_MEMORY);
1324 }
1325}
1326
1327void __stdcall glDisable(GLenum cap)
1328{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001329 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001330
1331 try
1332 {
1333 gl::Context *context = gl::getContext();
1334
1335 if (context)
1336 {
1337 switch (cap)
1338 {
1339 case GL_CULL_FACE: context->cullFace = false; break;
1340 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1341 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1342 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1343 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1344 case GL_STENCIL_TEST: context->stencilTest = false; break;
1345 case GL_DEPTH_TEST: context->depthTest = false; break;
1346 case GL_BLEND: context->blend = false; break;
1347 case GL_DITHER: context->dither = false; break;
1348 default:
1349 return error(GL_INVALID_ENUM);
1350 }
1351 }
1352 }
1353 catch(std::bad_alloc&)
1354 {
1355 return error(GL_OUT_OF_MEMORY);
1356 }
1357}
1358
1359void __stdcall glDisableVertexAttribArray(GLuint index)
1360{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001361 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001362
1363 try
1364 {
1365 if (index >= gl::MAX_VERTEX_ATTRIBS)
1366 {
1367 return error(GL_INVALID_VALUE);
1368 }
1369
1370 gl::Context *context = gl::getContext();
1371
1372 if (context)
1373 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001374 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001375 }
1376 }
1377 catch(std::bad_alloc&)
1378 {
1379 return error(GL_OUT_OF_MEMORY);
1380 }
1381}
1382
1383void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1384{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001385 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001386
1387 try
1388 {
1389 if (count < 0 || first < 0)
1390 {
1391 return error(GL_INVALID_VALUE);
1392 }
1393
1394 gl::Context *context = gl::getContext();
1395
1396 if (context)
1397 {
1398 context->drawArrays(mode, first, count);
1399 }
1400 }
1401 catch(std::bad_alloc&)
1402 {
1403 return error(GL_OUT_OF_MEMORY);
1404 }
1405}
1406
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001407void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001408{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001409 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 +00001410 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001411
1412 try
1413 {
1414 if (count < 0)
1415 {
1416 return error(GL_INVALID_VALUE);
1417 }
1418
1419 switch (type)
1420 {
1421 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001422 case GL_UNSIGNED_SHORT:
1423 break;
1424 default:
1425 return error(GL_INVALID_ENUM);
1426 }
1427
1428 gl::Context *context = gl::getContext();
1429
1430 if (context)
1431 {
1432 context->drawElements(mode, count, type, indices);
1433 }
1434 }
1435 catch(std::bad_alloc&)
1436 {
1437 return error(GL_OUT_OF_MEMORY);
1438 }
1439}
1440
1441void __stdcall glEnable(GLenum cap)
1442{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001443 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001444
1445 try
1446 {
1447 gl::Context *context = gl::getContext();
1448
1449 if (context)
1450 {
1451 switch (cap)
1452 {
1453 case GL_CULL_FACE: context->cullFace = true; break;
1454 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1455 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1456 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1457 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1458 case GL_STENCIL_TEST: context->stencilTest = true; break;
1459 case GL_DEPTH_TEST: context->depthTest = true; break;
1460 case GL_BLEND: context->blend = true; break;
1461 case GL_DITHER: context->dither = true; break;
1462 default:
1463 return error(GL_INVALID_ENUM);
1464 }
1465 }
1466 }
1467 catch(std::bad_alloc&)
1468 {
1469 return error(GL_OUT_OF_MEMORY);
1470 }
1471}
1472
1473void __stdcall glEnableVertexAttribArray(GLuint index)
1474{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001475 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001476
1477 try
1478 {
1479 if (index >= gl::MAX_VERTEX_ATTRIBS)
1480 {
1481 return error(GL_INVALID_VALUE);
1482 }
1483
1484 gl::Context *context = gl::getContext();
1485
1486 if (context)
1487 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001488 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001489 }
1490 }
1491 catch(std::bad_alloc&)
1492 {
1493 return error(GL_OUT_OF_MEMORY);
1494 }
1495}
1496
1497void __stdcall glFinish(void)
1498{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001499 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001500
1501 try
1502 {
1503 gl::Context *context = gl::getContext();
1504
1505 if (context)
1506 {
1507 context->finish();
1508 }
1509 }
1510 catch(std::bad_alloc&)
1511 {
1512 return error(GL_OUT_OF_MEMORY);
1513 }
1514}
1515
1516void __stdcall glFlush(void)
1517{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001518 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001519
1520 try
1521 {
1522 gl::Context *context = gl::getContext();
1523
1524 if (context)
1525 {
1526 context->flush();
1527 }
1528 }
1529 catch(std::bad_alloc&)
1530 {
1531 return error(GL_OUT_OF_MEMORY);
1532 }
1533}
1534
1535void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1536{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001537 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1538 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001539
1540 try
1541 {
1542 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1543 {
1544 return error(GL_INVALID_ENUM);
1545 }
1546
1547 gl::Context *context = gl::getContext();
1548
1549 if (context)
1550 {
1551 gl::Framebuffer *framebuffer = context->getFramebuffer();
1552
1553 if (context->framebuffer == 0 || !framebuffer)
1554 {
1555 return error(GL_INVALID_OPERATION);
1556 }
1557
1558 switch (attachment)
1559 {
1560 case GL_COLOR_ATTACHMENT0:
1561 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1562 break;
1563 case GL_DEPTH_ATTACHMENT:
1564 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1565 break;
1566 case GL_STENCIL_ATTACHMENT:
1567 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1568 break;
1569 default:
1570 return error(GL_INVALID_ENUM);
1571 }
1572 }
1573 }
1574 catch(std::bad_alloc&)
1575 {
1576 return error(GL_OUT_OF_MEMORY);
1577 }
1578}
1579
1580void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1581{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001582 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1583 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001584
1585 try
1586 {
1587 if (target != GL_FRAMEBUFFER)
1588 {
1589 return error(GL_INVALID_ENUM);
1590 }
1591
1592 switch (attachment)
1593 {
1594 case GL_COLOR_ATTACHMENT0:
1595 break;
1596 default:
1597 return error(GL_INVALID_ENUM);
1598 }
1599
1600 gl::Context *context = gl::getContext();
1601
1602 if (context)
1603 {
1604 if (texture)
1605 {
1606 switch (textarget)
1607 {
1608 case GL_TEXTURE_2D:
1609 if (!context->getTexture2D())
1610 {
1611 return error(GL_INVALID_OPERATION);
1612 }
1613 break;
1614 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1615 UNIMPLEMENTED(); // FIXME
1616 break;
1617 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1618 UNIMPLEMENTED(); // FIXME
1619 break;
1620 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1621 UNIMPLEMENTED(); // FIXME
1622 break;
1623 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1624 UNIMPLEMENTED(); // FIXME
1625 break;
1626 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1627 UNIMPLEMENTED(); // FIXME
1628 break;
1629 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1630 UNIMPLEMENTED(); // FIXME
1631 break;
1632 default:
1633 return error(GL_INVALID_ENUM);
1634 }
1635
1636 if (level != 0)
1637 {
1638 return error(GL_INVALID_VALUE);
1639 }
1640 }
1641
1642 gl::Framebuffer *framebuffer = context->getFramebuffer();
1643
1644 if (context->framebuffer == 0 || !framebuffer)
1645 {
1646 return error(GL_INVALID_OPERATION);
1647 }
1648
1649 framebuffer->setColorbuffer(GL_TEXTURE, texture);
1650 }
1651 }
1652 catch(std::bad_alloc&)
1653 {
1654 return error(GL_OUT_OF_MEMORY);
1655 }
1656}
1657
1658void __stdcall glFrontFace(GLenum mode)
1659{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001660 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001661
1662 try
1663 {
1664 switch (mode)
1665 {
1666 case GL_CW:
1667 case GL_CCW:
1668 {
1669 gl::Context *context = gl::getContext();
1670
1671 if (context)
1672 {
1673 context->frontFace = mode;
1674 }
1675 }
1676 break;
1677 default:
1678 return error(GL_INVALID_ENUM);
1679 }
1680 }
1681 catch(std::bad_alloc&)
1682 {
1683 return error(GL_OUT_OF_MEMORY);
1684 }
1685}
1686
1687void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1688{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001689 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001690
1691 try
1692 {
1693 if (n < 0)
1694 {
1695 return error(GL_INVALID_VALUE);
1696 }
1697
1698 gl::Context *context = gl::getContext();
1699
1700 if (context)
1701 {
1702 for (int i = 0; i < n; i++)
1703 {
1704 buffers[i] = context->createBuffer();
1705 }
1706 }
1707 }
1708 catch(std::bad_alloc&)
1709 {
1710 return error(GL_OUT_OF_MEMORY);
1711 }
1712}
1713
1714void __stdcall glGenerateMipmap(GLenum target)
1715{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001716 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001717
1718 try
1719 {
1720 UNIMPLEMENTED(); // FIXME
1721 }
1722 catch(std::bad_alloc&)
1723 {
1724 return error(GL_OUT_OF_MEMORY);
1725 }
1726}
1727
1728void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1729{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001730 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001731
1732 try
1733 {
1734 if (n < 0)
1735 {
1736 return error(GL_INVALID_VALUE);
1737 }
1738
1739 gl::Context *context = gl::getContext();
1740
1741 if (context)
1742 {
1743 for (int i = 0; i < n; i++)
1744 {
1745 framebuffers[i] = context->createFramebuffer();
1746 }
1747 }
1748 }
1749 catch(std::bad_alloc&)
1750 {
1751 return error(GL_OUT_OF_MEMORY);
1752 }
1753}
1754
1755void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1756{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001757 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001758
1759 try
1760 {
1761 if (n < 0)
1762 {
1763 return error(GL_INVALID_VALUE);
1764 }
1765
1766 gl::Context *context = gl::getContext();
1767
1768 if (context)
1769 {
1770 for (int i = 0; i < n; i++)
1771 {
1772 renderbuffers[i] = context->createRenderbuffer();
1773 }
1774 }
1775 }
1776 catch(std::bad_alloc&)
1777 {
1778 return error(GL_OUT_OF_MEMORY);
1779 }
1780}
1781
1782void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1783{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001784 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001785
1786 try
1787 {
1788 if (n < 0)
1789 {
1790 return error(GL_INVALID_VALUE);
1791 }
1792
1793 gl::Context *context = gl::getContext();
1794
1795 if (context)
1796 {
1797 for (int i = 0; i < n; i++)
1798 {
1799 textures[i] = context->createTexture();
1800 }
1801 }
1802 }
1803 catch(std::bad_alloc&)
1804 {
1805 return error(GL_OUT_OF_MEMORY);
1806 }
1807}
1808
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001809void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001810{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001811 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001812 "GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001813 program, index, bufsize, length, size, type, name);
1814
1815 try
1816 {
1817 if (bufsize < 0)
1818 {
1819 return error(GL_INVALID_VALUE);
1820 }
1821
1822 UNIMPLEMENTED(); // FIXME
1823 }
1824 catch(std::bad_alloc&)
1825 {
1826 return error(GL_OUT_OF_MEMORY);
1827 }
1828}
1829
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001830void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001831{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001832 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001833 "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 +00001834 program, index, bufsize, length, size, type, name);
1835
1836 try
1837 {
1838 if (bufsize < 0)
1839 {
1840 return error(GL_INVALID_VALUE);
1841 }
1842
1843 UNIMPLEMENTED(); // FIXME
1844 }
1845 catch(std::bad_alloc&)
1846 {
1847 return error(GL_OUT_OF_MEMORY);
1848 }
1849}
1850
1851void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1852{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001853 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1854 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001855
1856 try
1857 {
1858 if (maxcount < 0)
1859 {
1860 return error(GL_INVALID_VALUE);
1861 }
1862
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001863 gl::Context *context = gl::getContext();
1864
1865 if (context)
1866 {
1867 gl::Program *programObject = context->getProgram(program);
1868
1869 if (!programObject)
1870 {
1871 return error(GL_INVALID_VALUE);
1872 }
1873
1874 return programObject->getAttachedShaders(maxcount, count, shaders);
1875 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001876 }
1877 catch(std::bad_alloc&)
1878 {
1879 return error(GL_OUT_OF_MEMORY);
1880 }
1881}
1882
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001883int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001884{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001885 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001886
1887 try
1888 {
1889 gl::Context *context = gl::getContext();
1890
1891 if (context)
1892 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001893
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001894 gl::Program *programObject = context->getProgram(program);
1895
1896 if (!programObject)
1897 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001898 if (context->getShader(program))
1899 {
1900 return error(GL_INVALID_OPERATION, -1);
1901 }
1902 else
1903 {
1904 return error(GL_INVALID_VALUE, -1);
1905 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001906 }
1907
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00001908 if (!programObject->isLinked())
1909 {
1910 return error(GL_INVALID_OPERATION, -1);
1911 }
1912
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001913 return programObject->getAttributeLocation(name);
1914 }
1915 }
1916 catch(std::bad_alloc&)
1917 {
1918 return error(GL_OUT_OF_MEMORY, -1);
1919 }
1920
1921 return -1;
1922}
1923
1924void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1925{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001926 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001927
1928 try
1929 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001930 gl::Context *context = gl::getContext();
1931
1932 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001933 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001934 if (!(context->getBooleanv(pname, params)))
1935 {
1936 GLenum nativeType;
1937 unsigned int numParams = 0;
1938 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1939 return error(GL_INVALID_ENUM);
1940
1941 if (numParams == 0)
1942 return; // it is known that the pname is valid, but there are no parameters to return
1943
1944 if (nativeType == GL_FLOAT)
1945 {
1946 GLfloat *floatParams = NULL;
1947 floatParams = new GLfloat[numParams];
1948
1949 context->getFloatv(pname, floatParams);
1950
1951 for (unsigned int i = 0; i < numParams; ++i)
1952 {
1953 if (floatParams[i] == 0.0f)
1954 params[i] = GL_FALSE;
1955 else
1956 params[i] = GL_TRUE;
1957 }
1958
1959 delete [] floatParams;
1960 }
1961 else if (nativeType == GL_INT)
1962 {
1963 GLint *intParams = NULL;
1964 intParams = new GLint[numParams];
1965
1966 context->getIntegerv(pname, intParams);
1967
1968 for (unsigned int i = 0; i < numParams; ++i)
1969 {
1970 if (intParams[i] == 0)
1971 params[i] = GL_FALSE;
1972 else
1973 params[i] = GL_TRUE;
1974 }
1975
1976 delete [] intParams;
1977 }
1978 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001979 }
1980 }
1981 catch(std::bad_alloc&)
1982 {
1983 return error(GL_OUT_OF_MEMORY);
1984 }
1985}
1986
1987void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1988{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001989 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 +00001990
1991 try
1992 {
1993 UNIMPLEMENTED(); // FIXME
1994 }
1995 catch(std::bad_alloc&)
1996 {
1997 return error(GL_OUT_OF_MEMORY);
1998 }
1999}
2000
2001GLenum __stdcall glGetError(void)
2002{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002003 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002004
2005 gl::Context *context = gl::getContext();
2006
2007 if (context)
2008 {
2009 return context->getError();
2010 }
2011
2012 return GL_NO_ERROR;
2013}
2014
2015void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2016{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002017 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002018
2019 try
2020 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002021 gl::Context *context = gl::getContext();
2022
2023 if (context)
2024 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002025 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002026 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002027 GLenum nativeType;
2028 unsigned int numParams = 0;
2029 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2030 return error(GL_INVALID_ENUM);
2031
2032 if (numParams == 0)
2033 return; // it is known that the pname is valid, but that there are no parameters to return.
2034
2035 if (nativeType == GL_BOOL)
2036 {
2037 GLboolean *boolParams = NULL;
2038 boolParams = new GLboolean[numParams];
2039
2040 context->getBooleanv(pname, boolParams);
2041
2042 for (unsigned int i = 0; i < numParams; ++i)
2043 {
2044 if (boolParams[i] == GL_FALSE)
2045 params[i] = 0.0f;
2046 else
2047 params[i] = 1.0f;
2048 }
2049
2050 delete [] boolParams;
2051 }
2052 else if (nativeType == GL_INT)
2053 {
2054 GLint *intParams = NULL;
2055 intParams = new GLint[numParams];
2056
2057 context->getIntegerv(pname, intParams);
2058
2059 for (unsigned int i = 0; i < numParams; ++i)
2060 {
2061 params[i] = (GLfloat)intParams[i];
2062 }
2063
2064 delete [] intParams;
2065 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002066 }
2067 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002068 }
2069 catch(std::bad_alloc&)
2070 {
2071 return error(GL_OUT_OF_MEMORY);
2072 }
2073}
2074
2075void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2076{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002077 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2078 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002079
2080 try
2081 {
2082 gl::Context *context = gl::getContext();
2083
2084 if (context)
2085 {
2086 if (context->framebuffer == 0)
2087 {
2088 return error(GL_INVALID_OPERATION);
2089 }
2090
2091 UNIMPLEMENTED(); // FIXME
2092 }
2093 }
2094 catch(std::bad_alloc&)
2095 {
2096 return error(GL_OUT_OF_MEMORY);
2097 }
2098}
2099
2100void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2101{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002102 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002103
2104 try
2105 {
2106 gl::Context *context = gl::getContext();
2107
2108 if (context)
2109 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002110 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002111 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002112 GLenum nativeType;
2113 unsigned int numParams = 0;
2114 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2115 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002116
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002117 if (numParams == 0)
2118 return; // it is known that pname is valid, but there are no parameters to return
2119
2120 if (nativeType == GL_BOOL)
2121 {
2122 GLboolean *boolParams = NULL;
2123 boolParams = new GLboolean[numParams];
2124
2125 context->getBooleanv(pname, boolParams);
2126
2127 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002128 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002129 if (boolParams[i] == GL_FALSE)
2130 params[i] = 0;
2131 else
2132 params[i] = 1;
2133 }
2134
2135 delete [] boolParams;
2136 }
2137 else if (nativeType == GL_FLOAT)
2138 {
2139 GLfloat *floatParams = NULL;
2140 floatParams = new GLfloat[numParams];
2141
2142 context->getFloatv(pname, floatParams);
2143
2144 for (unsigned int i = 0; i < numParams; ++i)
2145 {
2146 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002147 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002148 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002149 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002150 else
2151 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 +00002152 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002153
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002154 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002155 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002156 }
2157 }
2158 }
2159 catch(std::bad_alloc&)
2160 {
2161 return error(GL_OUT_OF_MEMORY);
2162 }
2163}
2164
2165void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2166{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002167 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002168
2169 try
2170 {
2171 gl::Context *context = gl::getContext();
2172
2173 if (context)
2174 {
2175 gl::Program *programObject = context->getProgram(program);
2176
2177 if (!programObject)
2178 {
2179 return error(GL_INVALID_VALUE);
2180 }
2181
2182 switch (pname)
2183 {
2184 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002185 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002186 return;
2187 case GL_LINK_STATUS:
2188 *params = programObject->isLinked();
2189 return;
2190 case GL_VALIDATE_STATUS:
2191 UNIMPLEMENTED(); // FIXME
2192 *params = GL_TRUE;
2193 return;
2194 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002195 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002196 return;
2197 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002198 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002199 return;
2200 case GL_ACTIVE_ATTRIBUTES:
2201 UNIMPLEMENTED(); // FIXME
2202 *params = 0;
2203 return;
2204 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2205 UNIMPLEMENTED(); // FIXME
2206 *params = 0;
2207 return;
2208 case GL_ACTIVE_UNIFORMS:
2209 UNIMPLEMENTED(); // FIXME
2210 *params = 0;
2211 return;
2212 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2213 UNIMPLEMENTED(); // FIXME
2214 *params = 0;
2215 return;
2216 default:
2217 return error(GL_INVALID_ENUM);
2218 }
2219 }
2220 }
2221 catch(std::bad_alloc&)
2222 {
2223 return error(GL_OUT_OF_MEMORY);
2224 }
2225}
2226
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002227void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002228{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002229 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 +00002230 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002231
2232 try
2233 {
2234 if (bufsize < 0)
2235 {
2236 return error(GL_INVALID_VALUE);
2237 }
2238
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002239 gl::Context *context = gl::getContext();
2240
2241 if (context)
2242 {
2243 gl::Program *programObject = context->getProgram(program);
2244
2245 if (!programObject)
2246 {
2247 return error(GL_INVALID_VALUE);
2248 }
2249
2250 programObject->getInfoLog(bufsize, length, infolog);
2251 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002252 }
2253 catch(std::bad_alloc&)
2254 {
2255 return error(GL_OUT_OF_MEMORY);
2256 }
2257}
2258
2259void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2260{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002261 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 +00002262
2263 try
2264 {
2265 UNIMPLEMENTED(); // FIXME
2266 }
2267 catch(std::bad_alloc&)
2268 {
2269 return error(GL_OUT_OF_MEMORY);
2270 }
2271}
2272
2273void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2274{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002275 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002276
2277 try
2278 {
2279 gl::Context *context = gl::getContext();
2280
2281 if (context)
2282 {
2283 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002284
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002285 if (!shaderObject)
2286 {
2287 return error(GL_INVALID_VALUE);
2288 }
2289
2290 switch (pname)
2291 {
2292 case GL_SHADER_TYPE:
2293 *params = shaderObject->getType();
2294 return;
2295 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002296 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002297 return;
2298 case GL_COMPILE_STATUS:
2299 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2300 return;
2301 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002302 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002303 return;
2304 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002305 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002306 return;
2307 default:
2308 return error(GL_INVALID_ENUM);
2309 }
2310 }
2311 }
2312 catch(std::bad_alloc&)
2313 {
2314 return error(GL_OUT_OF_MEMORY);
2315 }
2316}
2317
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002318void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002319{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002320 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 +00002321 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002322
2323 try
2324 {
2325 if (bufsize < 0)
2326 {
2327 return error(GL_INVALID_VALUE);
2328 }
2329
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002330 gl::Context *context = gl::getContext();
2331
2332 if (context)
2333 {
2334 gl::Shader *shaderObject = context->getShader(shader);
2335
2336 if (!shaderObject)
2337 {
2338 return error(GL_INVALID_VALUE);
2339 }
2340
2341 shaderObject->getInfoLog(bufsize, length, infolog);
2342 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002343 }
2344 catch(std::bad_alloc&)
2345 {
2346 return error(GL_OUT_OF_MEMORY);
2347 }
2348}
2349
2350void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2351{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002352 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2353 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002354
2355 try
2356 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002357 switch (shadertype)
2358 {
2359 case GL_VERTEX_SHADER:
2360 case GL_FRAGMENT_SHADER:
2361 break;
2362 default:
2363 return error(GL_INVALID_ENUM);
2364 }
2365
2366 switch (precisiontype)
2367 {
2368 case GL_LOW_FLOAT:
2369 case GL_MEDIUM_FLOAT:
2370 case GL_HIGH_FLOAT:
2371 // Assume IEEE 754 precision
2372 range[0] = 127;
2373 range[1] = 127;
2374 precision[0] = 23;
2375 precision[1] = 23;
2376 break;
2377 case GL_LOW_INT:
2378 case GL_MEDIUM_INT:
2379 case GL_HIGH_INT:
2380 // Some (most) hardware only supports single-precision floating-point numbers,
2381 // which can accurately represent integers up to +/-16777216
2382 range[0] = 24;
2383 range[1] = 24;
2384 precision[0] = 0;
2385 precision[1] = 0;
2386 break;
2387 default:
2388 return error(GL_INVALID_ENUM);
2389 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002390 }
2391 catch(std::bad_alloc&)
2392 {
2393 return error(GL_OUT_OF_MEMORY);
2394 }
2395}
2396
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002397void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002398{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002399 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 +00002400 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002401
2402 try
2403 {
2404 if (bufsize < 0)
2405 {
2406 return error(GL_INVALID_VALUE);
2407 }
2408
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002409 gl::Context *context = gl::getContext();
2410
2411 if (context)
2412 {
2413 gl::Shader *shaderObject = context->getShader(shader);
2414
2415 if (!shaderObject)
2416 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002417 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002418 }
2419
2420 shaderObject->getSource(bufsize, length, source);
2421 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002422 }
2423 catch(std::bad_alloc&)
2424 {
2425 return error(GL_OUT_OF_MEMORY);
2426 }
2427}
2428
2429const GLubyte* __stdcall glGetString(GLenum name)
2430{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002431 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002432
2433 try
2434 {
2435 switch (name)
2436 {
2437 case GL_VENDOR:
2438 return (GLubyte*)"TransGaming Inc.";
2439 case GL_RENDERER:
2440 return (GLubyte*)"ANGLE";
2441 case GL_VERSION:
2442 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2443 case GL_SHADING_LANGUAGE_VERSION:
2444 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2445 case GL_EXTENSIONS:
2446 return (GLubyte*)"";
2447 default:
2448 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2449 }
2450 }
2451 catch(std::bad_alloc&)
2452 {
2453 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2454 }
2455
2456 return NULL;
2457}
2458
2459void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2460{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002461 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 +00002462
2463 try
2464 {
2465 UNIMPLEMENTED(); // FIXME
2466 }
2467 catch(std::bad_alloc&)
2468 {
2469 return error(GL_OUT_OF_MEMORY);
2470 }
2471}
2472
2473void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2474{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002475 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 +00002476
2477 try
2478 {
2479 UNIMPLEMENTED(); // FIXME
2480 }
2481 catch(std::bad_alloc&)
2482 {
2483 return error(GL_OUT_OF_MEMORY);
2484 }
2485}
2486
2487void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2488{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002489 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002490
2491 try
2492 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002493 gl::Context *context = gl::getContext();
2494
2495 if (context)
2496 {
2497 if (program == 0)
2498 {
2499 return error(GL_INVALID_VALUE);
2500 }
2501
2502 gl::Program *programObject = context->getProgram(program);
2503
2504 if (!programObject || !programObject->isLinked())
2505 {
2506 return error(GL_INVALID_OPERATION);
2507 }
2508
2509 if (!programObject->getUniformfv(location, params))
2510 {
2511 return error(GL_INVALID_OPERATION);
2512 }
2513 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002514 }
2515 catch(std::bad_alloc&)
2516 {
2517 return error(GL_OUT_OF_MEMORY);
2518 }
2519}
2520
2521void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2522{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002523 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002524
2525 try
2526 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002527 gl::Context *context = gl::getContext();
2528
2529 if (context)
2530 {
2531 if (program == 0)
2532 {
2533 return error(GL_INVALID_VALUE);
2534 }
2535
2536 gl::Program *programObject = context->getProgram(program);
2537
2538 if (!programObject || !programObject->isLinked())
2539 {
2540 return error(GL_INVALID_OPERATION);
2541 }
2542
2543 if (!programObject)
2544 {
2545 return error(GL_INVALID_OPERATION);
2546 }
2547
2548 if (!programObject->getUniformiv(location, params))
2549 {
2550 return error(GL_INVALID_OPERATION);
2551 }
2552 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002553 }
2554 catch(std::bad_alloc&)
2555 {
2556 return error(GL_OUT_OF_MEMORY);
2557 }
2558}
2559
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002560int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002561{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002562 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002563
2564 try
2565 {
2566 gl::Context *context = gl::getContext();
2567
2568 if (strstr(name, "gl_") == name)
2569 {
2570 return -1;
2571 }
2572
2573 if (context)
2574 {
2575 gl::Program *programObject = context->getProgram(program);
2576
2577 if (!programObject)
2578 {
2579 return error(GL_INVALID_VALUE, -1);
2580 }
2581
2582 if (!programObject->isLinked())
2583 {
2584 return error(GL_INVALID_OPERATION, -1);
2585 }
2586
2587 return programObject->getUniformLocation(name);
2588 }
2589 }
2590 catch(std::bad_alloc&)
2591 {
2592 return error(GL_OUT_OF_MEMORY, -1);
2593 }
2594
2595 return -1;
2596}
2597
2598void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2599{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002600 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002601
2602 try
2603 {
2604 if (index >= gl::MAX_VERTEX_ATTRIBS)
2605 {
2606 return error(GL_INVALID_VALUE);
2607 }
2608
2609 UNIMPLEMENTED(); // FIXME
2610 }
2611 catch(std::bad_alloc&)
2612 {
2613 return error(GL_OUT_OF_MEMORY);
2614 }
2615}
2616
2617void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2618{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002619 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002620
2621 try
2622 {
2623 if (index >= gl::MAX_VERTEX_ATTRIBS)
2624 {
2625 return error(GL_INVALID_VALUE);
2626 }
2627
2628 UNIMPLEMENTED(); // FIXME
2629 }
2630 catch(std::bad_alloc&)
2631 {
2632 return error(GL_OUT_OF_MEMORY);
2633 }
2634}
2635
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002636void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002637{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002638 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002639
2640 try
2641 {
2642 if (index >= gl::MAX_VERTEX_ATTRIBS)
2643 {
2644 return error(GL_INVALID_VALUE);
2645 }
2646
2647 UNIMPLEMENTED(); // FIXME
2648 }
2649 catch(std::bad_alloc&)
2650 {
2651 return error(GL_OUT_OF_MEMORY);
2652 }
2653}
2654
2655void __stdcall glHint(GLenum target, GLenum mode)
2656{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002657 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002658
2659 try
2660 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002661 switch (target)
2662 {
2663 case GL_GENERATE_MIPMAP_HINT:
2664 switch (mode)
2665 {
2666 case GL_FASTEST:
2667 case GL_NICEST:
2668 case GL_DONT_CARE:
2669 break;
2670 default:
2671 return error(GL_INVALID_ENUM);
2672 }
2673 break;
2674 default:
2675 return error(GL_INVALID_ENUM);
2676 }
2677
2678 gl::Context *context = gl::getContext();
2679 if (context)
2680 {
2681 if (target == GL_GENERATE_MIPMAP_HINT)
2682 context->generateMipmapHint = mode;
2683 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002684 }
2685 catch(std::bad_alloc&)
2686 {
2687 return error(GL_OUT_OF_MEMORY);
2688 }
2689}
2690
2691GLboolean __stdcall glIsBuffer(GLuint buffer)
2692{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002693 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002694
2695 try
2696 {
2697 gl::Context *context = gl::getContext();
2698
2699 if (context && buffer)
2700 {
2701 gl::Buffer *bufferObject = context->getBuffer(buffer);
2702
2703 if (bufferObject)
2704 {
2705 return GL_TRUE;
2706 }
2707 }
2708 }
2709 catch(std::bad_alloc&)
2710 {
2711 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2712 }
2713
2714 return GL_FALSE;
2715}
2716
2717GLboolean __stdcall glIsEnabled(GLenum cap)
2718{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002719 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002720
2721 try
2722 {
2723 gl::Context *context = gl::getContext();
2724
2725 if (context)
2726 {
2727 switch (cap)
2728 {
2729 case GL_CULL_FACE: return context->cullFace;
2730 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
2731 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
2732 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
2733 case GL_SCISSOR_TEST: return context->scissorTest;
2734 case GL_STENCIL_TEST: return context->stencilTest;
2735 case GL_DEPTH_TEST: return context->depthTest;
2736 case GL_BLEND: return context->blend;
2737 case GL_DITHER: return context->dither;
2738 default:
2739 return error(GL_INVALID_ENUM, false);
2740 }
2741 }
2742 }
2743 catch(std::bad_alloc&)
2744 {
2745 return error(GL_OUT_OF_MEMORY, false);
2746 }
2747
2748 return false;
2749}
2750
2751GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
2752{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002753 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002754
2755 try
2756 {
2757 gl::Context *context = gl::getContext();
2758
2759 if (context && framebuffer)
2760 {
2761 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2762
2763 if (framebufferObject)
2764 {
2765 return GL_TRUE;
2766 }
2767 }
2768 }
2769 catch(std::bad_alloc&)
2770 {
2771 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2772 }
2773
2774 return GL_FALSE;
2775}
2776
2777GLboolean __stdcall glIsProgram(GLuint program)
2778{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002779 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002780
2781 try
2782 {
2783 gl::Context *context = gl::getContext();
2784
2785 if (context && program)
2786 {
2787 gl::Program *programObject = context->getProgram(program);
2788
2789 if (programObject)
2790 {
2791 return GL_TRUE;
2792 }
2793 }
2794 }
2795 catch(std::bad_alloc&)
2796 {
2797 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2798 }
2799
2800 return GL_FALSE;
2801}
2802
2803GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
2804{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002805 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002806
2807 try
2808 {
2809 gl::Context *context = gl::getContext();
2810
2811 if (context && renderbuffer)
2812 {
2813 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2814
2815 if (renderbufferObject)
2816 {
2817 return GL_TRUE;
2818 }
2819 }
2820 }
2821 catch(std::bad_alloc&)
2822 {
2823 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2824 }
2825
2826 return GL_FALSE;
2827}
2828
2829GLboolean __stdcall glIsShader(GLuint shader)
2830{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002831 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002832
2833 try
2834 {
2835 gl::Context *context = gl::getContext();
2836
2837 if (context && shader)
2838 {
2839 gl::Shader *shaderObject = context->getShader(shader);
2840
2841 if (shaderObject)
2842 {
2843 return GL_TRUE;
2844 }
2845 }
2846 }
2847 catch(std::bad_alloc&)
2848 {
2849 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2850 }
2851
2852 return GL_FALSE;
2853}
2854
2855GLboolean __stdcall glIsTexture(GLuint texture)
2856{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002857 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002858
2859 try
2860 {
2861 gl::Context *context = gl::getContext();
2862
2863 if (context && texture)
2864 {
2865 gl::Texture *textureObject = context->getTexture(texture);
2866
2867 if (textureObject)
2868 {
2869 return GL_TRUE;
2870 }
2871 }
2872 }
2873 catch(std::bad_alloc&)
2874 {
2875 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2876 }
2877
2878 return GL_FALSE;
2879}
2880
2881void __stdcall glLineWidth(GLfloat width)
2882{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002883 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002884
2885 try
2886 {
2887 if (width <= 0.0f)
2888 {
2889 return error(GL_INVALID_VALUE);
2890 }
2891
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002892 gl::Context *context = gl::getContext();
2893
2894 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002895 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002896 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002897 }
2898 }
2899 catch(std::bad_alloc&)
2900 {
2901 return error(GL_OUT_OF_MEMORY);
2902 }
2903}
2904
2905void __stdcall glLinkProgram(GLuint program)
2906{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002907 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002908
2909 try
2910 {
2911 gl::Context *context = gl::getContext();
2912
2913 if (context)
2914 {
2915 gl::Program *programObject = context->getProgram(program);
2916
2917 if (!programObject)
2918 {
2919 return error(GL_INVALID_VALUE);
2920 }
2921
2922 programObject->link();
2923 }
2924 }
2925 catch(std::bad_alloc&)
2926 {
2927 return error(GL_OUT_OF_MEMORY);
2928 }
2929}
2930
2931void __stdcall glPixelStorei(GLenum pname, GLint param)
2932{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002933 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002934
2935 try
2936 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002937 gl::Context *context = gl::getContext();
2938
2939 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002940 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002941 switch (pname)
2942 {
2943 case GL_UNPACK_ALIGNMENT:
2944 if (param != 1 && param != 2 && param != 4 && param != 8)
2945 {
2946 return error(GL_INVALID_VALUE);
2947 }
2948
2949 context->unpackAlignment = param;
2950 break;
2951
2952 case GL_PACK_ALIGNMENT:
2953 if (param != 1 && param != 2 && param != 4 && param != 8)
2954 {
2955 return error(GL_INVALID_VALUE);
2956 }
2957
2958 context->packAlignment = param;
2959 break;
2960
2961 default:
2962 return error(GL_INVALID_ENUM);
2963 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002964 }
2965 }
2966 catch(std::bad_alloc&)
2967 {
2968 return error(GL_OUT_OF_MEMORY);
2969 }
2970}
2971
2972void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
2973{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002974 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002975
2976 try
2977 {
2978 if (factor != 0.0f || units != 0.0f)
2979 {
2980 UNIMPLEMENTED(); // FIXME
2981 }
2982 }
2983 catch(std::bad_alloc&)
2984 {
2985 return error(GL_OUT_OF_MEMORY);
2986 }
2987}
2988
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002989void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002990{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002991 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002992 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002993 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002994
2995 try
2996 {
2997 if (width < 0 || height < 0)
2998 {
2999 return error(GL_INVALID_VALUE);
3000 }
3001
3002 switch (format)
3003 {
3004 case GL_RGBA:
3005 switch (type)
3006 {
3007 case GL_UNSIGNED_BYTE:
3008 break;
3009 default:
3010 return error(GL_INVALID_OPERATION);
3011 }
3012 break;
3013 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3014 switch (type)
3015 {
3016 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3017 break;
3018 default:
3019 return error(GL_INVALID_OPERATION);
3020 }
3021 break;
3022 default:
3023 return error(GL_INVALID_OPERATION);
3024 }
3025
3026 gl::Context *context = gl::getContext();
3027
3028 if (context)
3029 {
3030 context->readPixels(x, y, width, height, format, type, pixels);
3031 }
3032 }
3033 catch(std::bad_alloc&)
3034 {
3035 return error(GL_OUT_OF_MEMORY);
3036 }
3037}
3038
3039void __stdcall glReleaseShaderCompiler(void)
3040{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003041 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003042
3043 try
3044 {
3045 gl::Shader::releaseCompiler();
3046 }
3047 catch(std::bad_alloc&)
3048 {
3049 return error(GL_OUT_OF_MEMORY);
3050 }
3051}
3052
3053void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3054{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003055 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3056 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003057
3058 try
3059 {
3060 switch (target)
3061 {
3062 case GL_RENDERBUFFER:
3063 break;
3064 default:
3065 return error(GL_INVALID_ENUM);
3066 }
3067
3068 switch (internalformat)
3069 {
3070 case GL_DEPTH_COMPONENT16:
3071 case GL_RGBA4:
3072 case GL_RGB5_A1:
3073 case GL_RGB565:
3074 case GL_STENCIL_INDEX8:
3075 break;
3076 default:
3077 return error(GL_INVALID_ENUM);
3078 }
3079
3080 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3081 {
3082 return error(GL_INVALID_VALUE);
3083 }
3084
3085 gl::Context *context = gl::getContext();
3086
3087 if (context)
3088 {
3089 if (context->framebuffer == 0 || context->renderbuffer == 0)
3090 {
3091 return error(GL_INVALID_OPERATION);
3092 }
3093
3094 switch (internalformat)
3095 {
3096 case GL_DEPTH_COMPONENT16:
3097 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3098 break;
3099 case GL_RGBA4:
3100 case GL_RGB5_A1:
3101 case GL_RGB565:
3102 UNIMPLEMENTED(); // FIXME
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003103 // context->setRenderbuffer(new Colorbuffer(renderTarget));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003104 break;
3105 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003106 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003107 break;
3108 default:
3109 return error(GL_INVALID_ENUM);
3110 }
3111 }
3112 }
3113 catch(std::bad_alloc&)
3114 {
3115 return error(GL_OUT_OF_MEMORY);
3116 }
3117}
3118
3119void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3120{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003121 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003122
3123 try
3124 {
3125 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003126
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003127 if (context)
3128 {
3129 context->sampleCoverageValue = gl::clamp01(value);
3130 context->sampleCoverageInvert = invert;
3131 }
3132 }
3133 catch(std::bad_alloc&)
3134 {
3135 return error(GL_OUT_OF_MEMORY);
3136 }
3137}
3138
3139void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3140{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003141 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 +00003142
3143 try
3144 {
3145 if (width < 0 || height < 0)
3146 {
3147 return error(GL_INVALID_VALUE);
3148 }
3149
3150 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003151
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003152 if (context)
3153 {
3154 context->scissorX = x;
3155 context->scissorY = y;
3156 context->scissorWidth = width;
3157 context->scissorHeight = height;
3158 }
3159 }
3160 catch(std::bad_alloc&)
3161 {
3162 return error(GL_OUT_OF_MEMORY);
3163 }
3164}
3165
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003166void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003167{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003168 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003169 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003170 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003171
3172 try
3173 {
3174 if (n < 0 || length < 0)
3175 {
3176 return error(GL_INVALID_VALUE);
3177 }
3178
3179 UNIMPLEMENTED(); // FIXME
3180 }
3181 catch(std::bad_alloc&)
3182 {
3183 return error(GL_OUT_OF_MEMORY);
3184 }
3185}
3186
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003187void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003188{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003189 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 +00003190 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003191
3192 try
3193 {
daniel@transgaming.com57a0bab2010-04-03 20:56:10 +00003194 if (shader == 0 || count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003195 {
3196 return error(GL_INVALID_VALUE);
3197 }
3198
3199 gl::Context *context = gl::getContext();
3200
3201 if (context)
3202 {
3203 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003204
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003205 if (!shaderObject)
3206 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003207 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003208 }
3209
3210 shaderObject->setSource(count, string, length);
3211 }
3212 }
3213 catch(std::bad_alloc&)
3214 {
3215 return error(GL_OUT_OF_MEMORY);
3216 }
3217}
3218
3219void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3220{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003221 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003222}
3223
3224void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3225{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003226 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 +00003227
3228 try
3229 {
3230 switch (face)
3231 {
3232 case GL_FRONT:
3233 case GL_BACK:
3234 case GL_FRONT_AND_BACK:
3235 break;
3236 default:
3237 return error(GL_INVALID_ENUM);
3238 }
3239
3240 switch (func)
3241 {
3242 case GL_NEVER:
3243 case GL_ALWAYS:
3244 case GL_LESS:
3245 case GL_LEQUAL:
3246 case GL_EQUAL:
3247 case GL_GEQUAL:
3248 case GL_GREATER:
3249 case GL_NOTEQUAL:
3250 break;
3251 default:
3252 return error(GL_INVALID_ENUM);
3253 }
3254
3255 gl::Context *context = gl::getContext();
3256
3257 if (context)
3258 {
3259 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3260 {
3261 context->stencilFunc = func;
3262 context->stencilRef = ref;
3263 context->stencilMask = mask;
3264 }
3265
3266 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3267 {
3268 context->stencilBackFunc = func;
3269 context->stencilBackRef = ref;
3270 context->stencilBackMask = mask;
3271 }
3272 }
3273 }
3274 catch(std::bad_alloc&)
3275 {
3276 return error(GL_OUT_OF_MEMORY);
3277 }
3278}
3279
3280void __stdcall glStencilMask(GLuint mask)
3281{
3282 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3283}
3284
3285void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3286{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003287 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003288
3289 try
3290 {
3291 switch (face)
3292 {
3293 case GL_FRONT:
3294 case GL_BACK:
3295 case GL_FRONT_AND_BACK:
3296 break;
3297 default:
3298 return error(GL_INVALID_ENUM);
3299 }
3300
3301 gl::Context *context = gl::getContext();
3302
3303 if (context)
3304 {
3305 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3306 {
3307 context->stencilWritemask = mask;
3308 }
3309
3310 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3311 {
3312 context->stencilBackWritemask = mask;
3313 }
3314 }
3315 }
3316 catch(std::bad_alloc&)
3317 {
3318 return error(GL_OUT_OF_MEMORY);
3319 }
3320}
3321
3322void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3323{
3324 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3325}
3326
3327void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3328{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003329 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3330 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003331
3332 try
3333 {
3334 switch (face)
3335 {
3336 case GL_FRONT:
3337 case GL_BACK:
3338 case GL_FRONT_AND_BACK:
3339 break;
3340 default:
3341 return error(GL_INVALID_ENUM);
3342 }
3343
3344 switch (fail)
3345 {
3346 case GL_ZERO:
3347 case GL_KEEP:
3348 case GL_REPLACE:
3349 case GL_INCR:
3350 case GL_DECR:
3351 case GL_INVERT:
3352 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003353 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003354 break;
3355 default:
3356 return error(GL_INVALID_ENUM);
3357 }
3358
3359 switch (zfail)
3360 {
3361 case GL_ZERO:
3362 case GL_KEEP:
3363 case GL_REPLACE:
3364 case GL_INCR:
3365 case GL_DECR:
3366 case GL_INVERT:
3367 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003368 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003369 break;
3370 default:
3371 return error(GL_INVALID_ENUM);
3372 }
3373
3374 switch (zpass)
3375 {
3376 case GL_ZERO:
3377 case GL_KEEP:
3378 case GL_REPLACE:
3379 case GL_INCR:
3380 case GL_DECR:
3381 case GL_INVERT:
3382 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003383 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003384 break;
3385 default:
3386 return error(GL_INVALID_ENUM);
3387 }
3388
3389 gl::Context *context = gl::getContext();
3390
3391 if (context)
3392 {
3393 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3394 {
3395 context->stencilFail = fail;
3396 context->stencilPassDepthFail = zfail;
3397 context->stencilPassDepthPass = zpass;
3398 }
3399
3400 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3401 {
3402 context->stencilBackFail = fail;
3403 context->stencilBackPassDepthFail = zfail;
3404 context->stencilBackPassDepthPass = zpass;
3405 }
3406 }
3407 }
3408 catch(std::bad_alloc&)
3409 {
3410 return error(GL_OUT_OF_MEMORY);
3411 }
3412}
3413
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003414void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3415 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003416{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003417 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 +00003418 "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 +00003419 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003420
3421 try
3422 {
3423 if (level < 0 || width < 0 || height < 0)
3424 {
3425 return error(GL_INVALID_VALUE);
3426 }
3427
3428 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3429 {
3430 return error(GL_INVALID_VALUE);
3431 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003432
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003433 switch (target)
3434 {
3435 case GL_TEXTURE_2D:
3436 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3437 {
3438 return error(GL_INVALID_VALUE);
3439 }
3440 break;
3441 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3442 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3443 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3444 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3445 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3446 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3447 if (!gl::isPow2(width) || !gl::isPow2(height))
3448 {
3449 return error(GL_INVALID_VALUE);
3450 }
3451
3452 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3453 {
3454 return error(GL_INVALID_VALUE);
3455 }
3456 break;
3457 default:
3458 return error(GL_INVALID_ENUM);
3459 }
3460
3461 if (internalformat != format)
3462 {
3463 return error(GL_INVALID_OPERATION);
3464 }
3465
3466 switch (internalformat)
3467 {
3468 case GL_ALPHA:
3469 case GL_LUMINANCE:
3470 case GL_LUMINANCE_ALPHA:
3471 switch (type)
3472 {
3473 case GL_UNSIGNED_BYTE:
3474 break;
3475 default:
3476 return error(GL_INVALID_ENUM);
3477 }
3478 break;
3479 case GL_RGB:
3480 switch (type)
3481 {
3482 case GL_UNSIGNED_BYTE:
3483 case GL_UNSIGNED_SHORT_5_6_5:
3484 break;
3485 default:
3486 return error(GL_INVALID_ENUM);
3487 }
3488 break;
3489 case GL_RGBA:
3490 switch (type)
3491 {
3492 case GL_UNSIGNED_BYTE:
3493 case GL_UNSIGNED_SHORT_4_4_4_4:
3494 case GL_UNSIGNED_SHORT_5_5_5_1:
3495 break;
3496 default:
3497 return error(GL_INVALID_ENUM);
3498 }
3499 break;
3500 default:
3501 return error(GL_INVALID_VALUE);
3502 }
3503
3504 if (border != 0)
3505 {
3506 return error(GL_INVALID_VALUE);
3507 }
3508
3509 gl::Context *context = gl::getContext();
3510
3511 if (context)
3512 {
3513 if (target == GL_TEXTURE_2D)
3514 {
3515 gl::Texture2D *texture = context->getTexture2D();
3516
3517 if (!texture)
3518 {
3519 return error(GL_INVALID_OPERATION);
3520 }
3521
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003522 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003523 }
3524 else
3525 {
3526 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3527
3528 if (!texture)
3529 {
3530 return error(GL_INVALID_OPERATION);
3531 }
3532
3533 switch (target)
3534 {
3535 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003536 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003537 break;
3538 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003539 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003540 break;
3541 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003542 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003543 break;
3544 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003545 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003546 break;
3547 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003548 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003549 break;
3550 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003551 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003552 break;
3553 default: UNREACHABLE();
3554 }
3555 }
3556 }
3557 }
3558 catch(std::bad_alloc&)
3559 {
3560 return error(GL_OUT_OF_MEMORY);
3561 }
3562}
3563
3564void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3565{
3566 glTexParameteri(target, pname, (GLint)param);
3567}
3568
3569void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3570{
3571 glTexParameteri(target, pname, (GLint)*params);
3572}
3573
3574void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3575{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003576 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003577
3578 try
3579 {
3580 gl::Context *context = gl::getContext();
3581
3582 if (context)
3583 {
3584 gl::Texture *texture;
3585
3586 switch (target)
3587 {
3588 case GL_TEXTURE_2D:
3589 texture = context->getTexture2D();
3590 break;
3591 case GL_TEXTURE_CUBE_MAP:
3592 texture = context->getTextureCubeMap();
3593 break;
3594 default:
3595 return error(GL_INVALID_ENUM);
3596 }
3597
3598 switch (pname)
3599 {
3600 case GL_TEXTURE_WRAP_S:
3601 if (!texture->setWrapS((GLenum)param))
3602 {
3603 return error(GL_INVALID_ENUM);
3604 }
3605 break;
3606 case GL_TEXTURE_WRAP_T:
3607 if (!texture->setWrapT((GLenum)param))
3608 {
3609 return error(GL_INVALID_ENUM);
3610 }
3611 break;
3612 case GL_TEXTURE_MIN_FILTER:
3613 if (!texture->setMinFilter((GLenum)param))
3614 {
3615 return error(GL_INVALID_ENUM);
3616 }
3617 break;
3618 case GL_TEXTURE_MAG_FILTER:
3619 if (!texture->setMagFilter((GLenum)param))
3620 {
3621 return error(GL_INVALID_ENUM);
3622 }
3623 break;
3624 default:
3625 return error(GL_INVALID_ENUM);
3626 }
3627 }
3628 }
3629 catch(std::bad_alloc&)
3630 {
3631 return error(GL_OUT_OF_MEMORY);
3632 }
3633}
3634
3635void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3636{
3637 glTexParameteri(target, pname, *params);
3638}
3639
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003640void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3641 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003642{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003643 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3644 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003645 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003646 target, level, xoffset, yoffset, width, height, format, type, pixels);
3647
3648 try
3649 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003650 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
3651 {
3652 return error(GL_INVALID_ENUM);
3653 }
3654
3655 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003656 {
3657 return error(GL_INVALID_VALUE);
3658 }
3659
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003660 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
3661 {
3662 return error(GL_INVALID_VALUE);
3663 }
3664
3665 if (!es2dx::CheckTextureFormatType(format, type))
3666 {
3667 return error(GL_INVALID_ENUM);
3668 }
3669
3670 if (width == 0 || height == 0 || pixels == NULL)
3671 {
3672 return;
3673 }
3674
3675 gl::Context *context = gl::getContext();
3676
3677 if (context)
3678 {
3679 if (target == GL_TEXTURE_2D)
3680 {
3681 gl::Texture2D *texture = context->getTexture2D();
3682
3683 if (!texture)
3684 {
3685 return error(GL_INVALID_OPERATION);
3686 }
3687
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003688 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003689 }
3690 else if (es2dx::IsCubemapTextureTarget(target))
3691 {
3692 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3693
3694 if (!texture)
3695 {
3696 return error(GL_INVALID_OPERATION);
3697 }
3698
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003699 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003700 }
3701 else
3702 {
3703 UNREACHABLE();
3704 }
3705 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003706 }
3707 catch(std::bad_alloc&)
3708 {
3709 return error(GL_OUT_OF_MEMORY);
3710 }
3711}
3712
3713void __stdcall glUniform1f(GLint location, GLfloat x)
3714{
3715 glUniform1fv(location, 1, &x);
3716}
3717
3718void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
3719{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003720 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003721
3722 try
3723 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003724 if (count < 0)
3725 {
3726 return error(GL_INVALID_VALUE);
3727 }
3728
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003729 if (location == -1)
3730 {
3731 return;
3732 }
3733
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003734 gl::Context *context = gl::getContext();
3735
3736 if (context)
3737 {
3738 gl::Program *program = context->getCurrentProgram();
3739
3740 if (!program)
3741 {
3742 return error(GL_INVALID_OPERATION);
3743 }
3744
3745 if (!program->setUniform1fv(location, count, v))
3746 {
3747 return error(GL_INVALID_OPERATION);
3748 }
3749 }
3750 }
3751 catch(std::bad_alloc&)
3752 {
3753 return error(GL_OUT_OF_MEMORY);
3754 }
3755}
3756
3757void __stdcall glUniform1i(GLint location, GLint x)
3758{
3759 glUniform1iv(location, 1, &x);
3760}
3761
3762void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
3763{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003764 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003765
3766 try
3767 {
3768 if (count < 0)
3769 {
3770 return error(GL_INVALID_VALUE);
3771 }
3772
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003773 if (location == -1)
3774 {
3775 return;
3776 }
3777
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003778 gl::Context *context = gl::getContext();
3779
3780 if (context)
3781 {
3782 gl::Program *program = context->getCurrentProgram();
3783
3784 if (!program)
3785 {
3786 return error(GL_INVALID_OPERATION);
3787 }
3788
3789 if (!program->setUniform1iv(location, count, v))
3790 {
3791 return error(GL_INVALID_OPERATION);
3792 }
3793 }
3794 }
3795 catch(std::bad_alloc&)
3796 {
3797 return error(GL_OUT_OF_MEMORY);
3798 }
3799}
3800
3801void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
3802{
3803 GLfloat xy[2] = {x, y};
3804
3805 glUniform2fv(location, 1, (GLfloat*)&xy);
3806}
3807
3808void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
3809{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003810 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003811
3812 try
3813 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003814 if (count < 0)
3815 {
3816 return error(GL_INVALID_VALUE);
3817 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003818
3819 if (location == -1)
3820 {
3821 return;
3822 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003823
3824 gl::Context *context = gl::getContext();
3825
3826 if (context)
3827 {
3828 gl::Program *program = context->getCurrentProgram();
3829
3830 if (!program)
3831 {
3832 return error(GL_INVALID_OPERATION);
3833 }
3834
3835 if (!program->setUniform2fv(location, count, v))
3836 {
3837 return error(GL_INVALID_OPERATION);
3838 }
3839 }
3840 }
3841 catch(std::bad_alloc&)
3842 {
3843 return error(GL_OUT_OF_MEMORY);
3844 }
3845}
3846
3847void __stdcall glUniform2i(GLint location, GLint x, GLint y)
3848{
3849 GLint xy[4] = {x, y};
3850
3851 glUniform2iv(location, 1, (GLint*)&xy);
3852}
3853
3854void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
3855{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003856 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003857
3858 try
3859 {
3860 if (count < 0)
3861 {
3862 return error(GL_INVALID_VALUE);
3863 }
3864
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003865 if (location == -1)
3866 {
3867 return;
3868 }
3869
3870 gl::Context *context = gl::getContext();
3871
3872 if (context)
3873 {
3874 gl::Program *program = context->getCurrentProgram();
3875
3876 if (!program)
3877 {
3878 return error(GL_INVALID_OPERATION);
3879 }
3880
3881 if (!program->setUniform2iv(location, count, v))
3882 {
3883 return error(GL_INVALID_OPERATION);
3884 }
3885 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003886 }
3887 catch(std::bad_alloc&)
3888 {
3889 return error(GL_OUT_OF_MEMORY);
3890 }
3891}
3892
3893void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
3894{
3895 GLfloat xyz[3] = {x, y, z};
3896
3897 glUniform3fv(location, 1, (GLfloat*)&xyz);
3898}
3899
3900void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
3901{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003902 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003903
3904 try
3905 {
3906 if (count < 0)
3907 {
3908 return error(GL_INVALID_VALUE);
3909 }
3910
3911 if (location == -1)
3912 {
3913 return;
3914 }
3915
3916 gl::Context *context = gl::getContext();
3917
3918 if (context)
3919 {
3920 gl::Program *program = context->getCurrentProgram();
3921
3922 if (!program)
3923 {
3924 return error(GL_INVALID_OPERATION);
3925 }
3926
3927 if (!program->setUniform3fv(location, count, v))
3928 {
3929 return error(GL_INVALID_OPERATION);
3930 }
3931 }
3932 }
3933 catch(std::bad_alloc&)
3934 {
3935 return error(GL_OUT_OF_MEMORY);
3936 }
3937}
3938
3939void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
3940{
3941 GLint xyz[3] = {x, y, z};
3942
3943 glUniform3iv(location, 1, (GLint*)&xyz);
3944}
3945
3946void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
3947{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003948 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003949
3950 try
3951 {
3952 if (count < 0)
3953 {
3954 return error(GL_INVALID_VALUE);
3955 }
3956
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003957 if (location == -1)
3958 {
3959 return;
3960 }
3961
3962 gl::Context *context = gl::getContext();
3963
3964 if (context)
3965 {
3966 gl::Program *program = context->getCurrentProgram();
3967
3968 if (!program)
3969 {
3970 return error(GL_INVALID_OPERATION);
3971 }
3972
3973 if (!program->setUniform3iv(location, count, v))
3974 {
3975 return error(GL_INVALID_OPERATION);
3976 }
3977 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003978 }
3979 catch(std::bad_alloc&)
3980 {
3981 return error(GL_OUT_OF_MEMORY);
3982 }
3983}
3984
3985void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3986{
3987 GLfloat xyzw[4] = {x, y, z, w};
3988
3989 glUniform4fv(location, 1, (GLfloat*)&xyzw);
3990}
3991
3992void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
3993{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003994 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003995
3996 try
3997 {
3998 if (count < 0)
3999 {
4000 return error(GL_INVALID_VALUE);
4001 }
4002
4003 if (location == -1)
4004 {
4005 return;
4006 }
4007
4008 gl::Context *context = gl::getContext();
4009
4010 if (context)
4011 {
4012 gl::Program *program = context->getCurrentProgram();
4013
4014 if (!program)
4015 {
4016 return error(GL_INVALID_OPERATION);
4017 }
4018
4019 if (!program->setUniform4fv(location, count, v))
4020 {
4021 return error(GL_INVALID_OPERATION);
4022 }
4023 }
4024 }
4025 catch(std::bad_alloc&)
4026 {
4027 return error(GL_OUT_OF_MEMORY);
4028 }
4029}
4030
4031void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4032{
4033 GLint xyzw[4] = {x, y, z, w};
4034
4035 glUniform4iv(location, 1, (GLint*)&xyzw);
4036}
4037
4038void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4039{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004040 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004041
4042 try
4043 {
4044 if (count < 0)
4045 {
4046 return error(GL_INVALID_VALUE);
4047 }
4048
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004049 if (location == -1)
4050 {
4051 return;
4052 }
4053
4054 gl::Context *context = gl::getContext();
4055
4056 if (context)
4057 {
4058 gl::Program *program = context->getCurrentProgram();
4059
4060 if (!program)
4061 {
4062 return error(GL_INVALID_OPERATION);
4063 }
4064
4065 if (!program->setUniform4iv(location, count, v))
4066 {
4067 return error(GL_INVALID_OPERATION);
4068 }
4069 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004070 }
4071 catch(std::bad_alloc&)
4072 {
4073 return error(GL_OUT_OF_MEMORY);
4074 }
4075}
4076
4077void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4078{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004079 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4080 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004081
4082 try
4083 {
4084 if (count < 0 || transpose != GL_FALSE)
4085 {
4086 return error(GL_INVALID_VALUE);
4087 }
4088
4089 if (location == -1)
4090 {
4091 return;
4092 }
4093
4094 gl::Context *context = gl::getContext();
4095
4096 if (context)
4097 {
4098 gl::Program *program = context->getCurrentProgram();
4099
4100 if (!program)
4101 {
4102 return error(GL_INVALID_OPERATION);
4103 }
4104
4105 if (!program->setUniformMatrix2fv(location, count, value))
4106 {
4107 return error(GL_INVALID_OPERATION);
4108 }
4109 }
4110 }
4111 catch(std::bad_alloc&)
4112 {
4113 return error(GL_OUT_OF_MEMORY);
4114 }
4115}
4116
4117void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4118{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004119 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4120 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004121
4122 try
4123 {
4124 if (count < 0 || transpose != GL_FALSE)
4125 {
4126 return error(GL_INVALID_VALUE);
4127 }
4128
4129 if (location == -1)
4130 {
4131 return;
4132 }
4133
4134 gl::Context *context = gl::getContext();
4135
4136 if (context)
4137 {
4138 gl::Program *program = context->getCurrentProgram();
4139
4140 if (!program)
4141 {
4142 return error(GL_INVALID_OPERATION);
4143 }
4144
4145 if (!program->setUniformMatrix3fv(location, count, value))
4146 {
4147 return error(GL_INVALID_OPERATION);
4148 }
4149 }
4150 }
4151 catch(std::bad_alloc&)
4152 {
4153 return error(GL_OUT_OF_MEMORY);
4154 }
4155}
4156
4157void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4158{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004159 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4160 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004161
4162 try
4163 {
4164 if (count < 0 || transpose != GL_FALSE)
4165 {
4166 return error(GL_INVALID_VALUE);
4167 }
4168
4169 if (location == -1)
4170 {
4171 return;
4172 }
4173
4174 gl::Context *context = gl::getContext();
4175
4176 if (context)
4177 {
4178 gl::Program *program = context->getCurrentProgram();
4179
4180 if (!program)
4181 {
4182 return error(GL_INVALID_OPERATION);
4183 }
4184
4185 if (!program->setUniformMatrix4fv(location, count, value))
4186 {
4187 return error(GL_INVALID_OPERATION);
4188 }
4189 }
4190 }
4191 catch(std::bad_alloc&)
4192 {
4193 return error(GL_OUT_OF_MEMORY);
4194 }
4195}
4196
4197void __stdcall glUseProgram(GLuint program)
4198{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004199 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004200
4201 try
4202 {
4203 gl::Context *context = gl::getContext();
4204
4205 if (context)
4206 {
4207 gl::Program *programObject = context->getProgram(program);
4208
4209 if (programObject && !programObject->isLinked())
4210 {
4211 return error(GL_INVALID_OPERATION);
4212 }
4213
4214 context->useProgram(program);
4215 }
4216 }
4217 catch(std::bad_alloc&)
4218 {
4219 return error(GL_OUT_OF_MEMORY);
4220 }
4221}
4222
4223void __stdcall glValidateProgram(GLuint program)
4224{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004225 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004226
4227 try
4228 {
4229 UNIMPLEMENTED(); // FIXME
4230 }
4231 catch(std::bad_alloc&)
4232 {
4233 return error(GL_OUT_OF_MEMORY);
4234 }
4235}
4236
4237void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4238{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004239 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004240
4241 try
4242 {
4243 if (index >= gl::MAX_VERTEX_ATTRIBS)
4244 {
4245 return error(GL_INVALID_VALUE);
4246 }
4247
4248 UNIMPLEMENTED(); // FIXME
4249 }
4250 catch(std::bad_alloc&)
4251 {
4252 return error(GL_OUT_OF_MEMORY);
4253 }
4254}
4255
4256void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4257{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004258 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004259
4260 try
4261 {
4262 if (index >= gl::MAX_VERTEX_ATTRIBS)
4263 {
4264 return error(GL_INVALID_VALUE);
4265 }
4266
4267 UNIMPLEMENTED(); // FIXME
4268 }
4269 catch(std::bad_alloc&)
4270 {
4271 return error(GL_OUT_OF_MEMORY);
4272 }
4273}
4274
4275void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4276{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004277 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004278
4279 try
4280 {
4281 if (index >= gl::MAX_VERTEX_ATTRIBS)
4282 {
4283 return error(GL_INVALID_VALUE);
4284 }
4285
4286 UNIMPLEMENTED(); // FIXME
4287 }
4288 catch(std::bad_alloc&)
4289 {
4290 return error(GL_OUT_OF_MEMORY);
4291 }
4292}
4293
4294void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4295{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004296 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004297
4298 try
4299 {
4300 if (index >= gl::MAX_VERTEX_ATTRIBS)
4301 {
4302 return error(GL_INVALID_VALUE);
4303 }
4304
4305 UNIMPLEMENTED(); // FIXME
4306 }
4307 catch(std::bad_alloc&)
4308 {
4309 return error(GL_OUT_OF_MEMORY);
4310 }
4311}
4312
4313void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4314{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004315 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 +00004316
4317 try
4318 {
4319 if (index >= gl::MAX_VERTEX_ATTRIBS)
4320 {
4321 return error(GL_INVALID_VALUE);
4322 }
4323
4324 UNIMPLEMENTED(); // FIXME
4325 }
4326 catch(std::bad_alloc&)
4327 {
4328 return error(GL_OUT_OF_MEMORY);
4329 }
4330}
4331
4332void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4333{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004334 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004335
4336 try
4337 {
4338 if (index >= gl::MAX_VERTEX_ATTRIBS)
4339 {
4340 return error(GL_INVALID_VALUE);
4341 }
4342
4343 UNIMPLEMENTED(); // FIXME
4344 }
4345 catch(std::bad_alloc&)
4346 {
4347 return error(GL_OUT_OF_MEMORY);
4348 }
4349}
4350
4351void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4352{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004353 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 +00004354
4355 try
4356 {
4357 if (index >= gl::MAX_VERTEX_ATTRIBS)
4358 {
4359 return error(GL_INVALID_VALUE);
4360 }
4361
4362 UNIMPLEMENTED(); // FIXME
4363 }
4364 catch(std::bad_alloc&)
4365 {
4366 return error(GL_OUT_OF_MEMORY);
4367 }
4368}
4369
4370void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4371{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004372 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004373
4374 try
4375 {
4376 if (index >= gl::MAX_VERTEX_ATTRIBS)
4377 {
4378 return error(GL_INVALID_VALUE);
4379 }
4380
4381 UNIMPLEMENTED(); // FIXME
4382 }
4383 catch(std::bad_alloc&)
4384 {
4385 return error(GL_OUT_OF_MEMORY);
4386 }
4387}
4388
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004389void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004390{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004391 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004392 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004393 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004394
4395 try
4396 {
4397 if (index >= gl::MAX_VERTEX_ATTRIBS)
4398 {
4399 return error(GL_INVALID_VALUE);
4400 }
4401
4402 if (size < 1 || size > 4)
4403 {
4404 return error(GL_INVALID_VALUE);
4405 }
4406
4407 switch (type)
4408 {
4409 case GL_BYTE:
4410 case GL_UNSIGNED_BYTE:
4411 case GL_SHORT:
4412 case GL_UNSIGNED_SHORT:
4413 case GL_FIXED:
4414 case GL_FLOAT:
4415 break;
4416 default:
4417 return error(GL_INVALID_ENUM);
4418 }
4419
4420 if (stride < 0)
4421 {
4422 return error(GL_INVALID_VALUE);
4423 }
4424
4425 gl::Context *context = gl::getContext();
4426
4427 if (context)
4428 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004429 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4430 context->vertexAttribute[index].mSize = size;
4431 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004432 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004433 context->vertexAttribute[index].mStride = stride;
4434 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004435 }
4436 }
4437 catch(std::bad_alloc&)
4438 {
4439 return error(GL_OUT_OF_MEMORY);
4440 }
4441}
4442
4443void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4444{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004445 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 +00004446
4447 try
4448 {
4449 if (width < 0 || height < 0)
4450 {
4451 return error(GL_INVALID_VALUE);
4452 }
4453
4454 gl::Context *context = gl::getContext();
4455
4456 if (context)
4457 {
4458 context->viewportX = x;
4459 context->viewportY = y;
4460 context->viewportWidth = width;
4461 context->viewportHeight = height;
4462 }
4463 }
4464 catch(std::bad_alloc&)
4465 {
4466 return error(GL_OUT_OF_MEMORY);
4467 }
4468}
4469
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004470void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4471 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004472{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004473 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4474 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004475 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004476 target, level, internalformat, width, height, depth, border, format, type, pixels);
4477
4478 try
4479 {
4480 UNIMPLEMENTED(); // FIXME
4481 }
4482 catch(std::bad_alloc&)
4483 {
4484 return error(GL_OUT_OF_MEMORY);
4485 }
4486}
4487}