blob: 5afb6fd94010e0f34829417ef4cda22f520e0694 [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
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000017
18#include "libGLESv2/main.h"
19#include "libGLESv2/mathutil.h"
20#include "libGLESv2/utilities.h"
21#include "libGLESv2/Buffer.h"
22#include "libGLESv2/Context.h"
23#include "libGLESv2/Framebuffer.h"
24#include "libGLESv2/Program.h"
25#include "libGLESv2/Renderbuffer.h"
26#include "libGLESv2/Shader.h"
27#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000028
29extern "C"
30{
31
32void __stdcall glActiveTexture(GLenum texture)
33{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000034 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035
36 try
37 {
38 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
39 {
40 return error(GL_INVALID_ENUM);
41 }
42
43 gl::Context *context = gl::getContext();
44
45 if (context)
46 {
47 context->activeSampler = texture - GL_TEXTURE0;
48 }
49 }
50 catch(std::bad_alloc&)
51 {
52 return error(GL_OUT_OF_MEMORY);
53 }
54}
55
56void __stdcall glAttachShader(GLuint program, GLuint shader)
57{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000058 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000059
60 try
61 {
62 gl::Context *context = gl::getContext();
63
64 if (context)
65 {
66 gl::Program *programObject = context->getProgram(program);
67 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000068
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000069 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000071 if (context->getShader(program))
72 {
73 return error(GL_INVALID_OPERATION);
74 }
75 else
76 {
77 return error(GL_INVALID_VALUE);
78 }
79 }
80
81 if (!shaderObject)
82 {
83 if (context->getProgram(shader))
84 {
85 return error(GL_INVALID_OPERATION);
86 }
87 else
88 {
89 return error(GL_INVALID_VALUE);
90 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000091 }
92
93 if (!programObject->attachShader(shaderObject))
94 {
95 return error(GL_INVALID_OPERATION);
96 }
97 }
98 }
99 catch(std::bad_alloc&)
100 {
101 return error(GL_OUT_OF_MEMORY);
102 }
103}
104
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000105void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000106{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000107 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108
109 try
110 {
111 if (index >= gl::MAX_VERTEX_ATTRIBS)
112 {
113 return error(GL_INVALID_VALUE);
114 }
115
116 gl::Context *context = gl::getContext();
117
118 if (context)
119 {
120 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000121
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000122 if (!programObject)
123 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000124 if (context->getShader(program))
125 {
126 return error(GL_INVALID_OPERATION);
127 }
128 else
129 {
130 return error(GL_INVALID_VALUE);
131 }
132 }
133
134 if (strncmp(name, "gl_", 3) == 0)
135 {
136 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137 }
138
139 programObject->bindAttributeLocation(index, name);
140 }
141 }
142 catch(std::bad_alloc&)
143 {
144 return error(GL_OUT_OF_MEMORY);
145 }
146}
147
148void __stdcall glBindBuffer(GLenum target, GLuint buffer)
149{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000150 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000151
152 try
153 {
154 gl::Context *context = gl::getContext();
155
156 if (context)
157 {
158 switch (target)
159 {
160 case GL_ARRAY_BUFFER:
161 context->bindArrayBuffer(buffer);
162 return;
163 case GL_ELEMENT_ARRAY_BUFFER:
164 context->bindElementArrayBuffer(buffer);
165 return;
166 default:
167 return error(GL_INVALID_ENUM);
168 }
169 }
170 }
171 catch(std::bad_alloc&)
172 {
173 return error(GL_OUT_OF_MEMORY);
174 }
175}
176
177void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
178{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000179 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000180
181 try
182 {
183 if (target != GL_FRAMEBUFFER)
184 {
185 return error(GL_INVALID_ENUM);
186 }
187
188 gl::Context *context = gl::getContext();
189
190 if (context)
191 {
192 context->bindFramebuffer(framebuffer);
193 }
194 }
195 catch(std::bad_alloc&)
196 {
197 return error(GL_OUT_OF_MEMORY);
198 }
199}
200
201void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
202{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000203 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204
205 try
206 {
207 if (target != GL_RENDERBUFFER)
208 {
209 return error(GL_INVALID_ENUM);
210 }
211
212 gl::Context *context = gl::getContext();
213
214 if (context)
215 {
216 context->bindRenderbuffer(renderbuffer);
217 }
218 }
219 catch(std::bad_alloc&)
220 {
221 return error(GL_OUT_OF_MEMORY);
222 }
223}
224
225void __stdcall glBindTexture(GLenum target, GLuint texture)
226{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000227 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228
229 try
230 {
231 gl::Context *context = gl::getContext();
232
233 if (context)
234 {
235 gl::Texture *textureObject = context->getTexture(texture);
236
237 if (textureObject && textureObject->getTarget() != target && texture != 0)
238 {
239 return error(GL_INVALID_OPERATION);
240 }
241
242 switch (target)
243 {
244 case GL_TEXTURE_2D:
245 context->bindTexture2D(texture);
246 return;
247 case GL_TEXTURE_CUBE_MAP:
248 context->bindTextureCubeMap(texture);
249 return;
250 default:
251 return error(GL_INVALID_ENUM);
252 }
253 }
254 }
255 catch(std::bad_alloc&)
256 {
257 return error(GL_OUT_OF_MEMORY);
258 }
259}
260
261void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
262{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000263 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
264 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000265
266 try
267 {
268 gl::Context* context = gl::getContext();
269
270 if (context)
271 {
272 context->blendColor.red = gl::clamp01(red);
273 context->blendColor.blue = gl::clamp01(blue);
274 context->blendColor.green = gl::clamp01(green);
275 context->blendColor.alpha = gl::clamp01(alpha);
276 }
277 }
278 catch(std::bad_alloc&)
279 {
280 return error(GL_OUT_OF_MEMORY);
281 }
282}
283
284void __stdcall glBlendEquation(GLenum mode)
285{
286 glBlendEquationSeparate(mode, mode);
287}
288
289void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
290{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000291 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000292
293 try
294 {
295 switch (modeRGB)
296 {
297 case GL_FUNC_ADD:
298 case GL_FUNC_SUBTRACT:
299 case GL_FUNC_REVERSE_SUBTRACT:
300 break;
301 default:
302 return error(GL_INVALID_ENUM);
303 }
304
305 switch (modeAlpha)
306 {
307 case GL_FUNC_ADD:
308 case GL_FUNC_SUBTRACT:
309 case GL_FUNC_REVERSE_SUBTRACT:
310 break;
311 default:
312 return error(GL_INVALID_ENUM);
313 }
314
315 gl::Context *context = gl::getContext();
316
317 if (context)
318 {
319 context->blendEquationRGB = modeRGB;
320 context->blendEquationAlpha = modeAlpha;
321 }
322 }
323 catch(std::bad_alloc&)
324 {
325 return error(GL_OUT_OF_MEMORY);
326 }
327}
328
329void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
330{
331 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
332}
333
334void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
335{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000336 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
337 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000338
339 try
340 {
341 switch (srcRGB)
342 {
343 case GL_ZERO:
344 case GL_ONE:
345 case GL_SRC_COLOR:
346 case GL_ONE_MINUS_SRC_COLOR:
347 case GL_DST_COLOR:
348 case GL_ONE_MINUS_DST_COLOR:
349 case GL_SRC_ALPHA:
350 case GL_ONE_MINUS_SRC_ALPHA:
351 case GL_DST_ALPHA:
352 case GL_ONE_MINUS_DST_ALPHA:
353 case GL_CONSTANT_COLOR:
354 case GL_ONE_MINUS_CONSTANT_COLOR:
355 case GL_CONSTANT_ALPHA:
356 case GL_ONE_MINUS_CONSTANT_ALPHA:
357 case GL_SRC_ALPHA_SATURATE:
358 break;
359 default:
360 return error(GL_INVALID_ENUM);
361 }
362
363 switch (dstRGB)
364 {
365 case GL_ZERO:
366 case GL_ONE:
367 case GL_SRC_COLOR:
368 case GL_ONE_MINUS_SRC_COLOR:
369 case GL_DST_COLOR:
370 case GL_ONE_MINUS_DST_COLOR:
371 case GL_SRC_ALPHA:
372 case GL_ONE_MINUS_SRC_ALPHA:
373 case GL_DST_ALPHA:
374 case GL_ONE_MINUS_DST_ALPHA:
375 case GL_CONSTANT_COLOR:
376 case GL_ONE_MINUS_CONSTANT_COLOR:
377 case GL_CONSTANT_ALPHA:
378 case GL_ONE_MINUS_CONSTANT_ALPHA:
379 break;
380 default:
381 return error(GL_INVALID_ENUM);
382 }
383
384 switch (srcAlpha)
385 {
386 case GL_ZERO:
387 case GL_ONE:
388 case GL_SRC_COLOR:
389 case GL_ONE_MINUS_SRC_COLOR:
390 case GL_DST_COLOR:
391 case GL_ONE_MINUS_DST_COLOR:
392 case GL_SRC_ALPHA:
393 case GL_ONE_MINUS_SRC_ALPHA:
394 case GL_DST_ALPHA:
395 case GL_ONE_MINUS_DST_ALPHA:
396 case GL_CONSTANT_COLOR:
397 case GL_ONE_MINUS_CONSTANT_COLOR:
398 case GL_CONSTANT_ALPHA:
399 case GL_ONE_MINUS_CONSTANT_ALPHA:
400 case GL_SRC_ALPHA_SATURATE:
401 break;
402 default:
403 return error(GL_INVALID_ENUM);
404 }
405
406 switch (dstAlpha)
407 {
408 case GL_ZERO:
409 case GL_ONE:
410 case GL_SRC_COLOR:
411 case GL_ONE_MINUS_SRC_COLOR:
412 case GL_DST_COLOR:
413 case GL_ONE_MINUS_DST_COLOR:
414 case GL_SRC_ALPHA:
415 case GL_ONE_MINUS_SRC_ALPHA:
416 case GL_DST_ALPHA:
417 case GL_ONE_MINUS_DST_ALPHA:
418 case GL_CONSTANT_COLOR:
419 case GL_ONE_MINUS_CONSTANT_COLOR:
420 case GL_CONSTANT_ALPHA:
421 case GL_ONE_MINUS_CONSTANT_ALPHA:
422 break;
423 default:
424 return error(GL_INVALID_ENUM);
425 }
426
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000427 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
428 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
429
430 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
431 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
432
433 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000434 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000435 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
436 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000437 }
438
439 gl::Context *context = gl::getContext();
440
441 if (context)
442 {
443 context->sourceBlendRGB = srcRGB;
444 context->sourceBlendAlpha = srcAlpha;
445 context->destBlendRGB = dstRGB;
446 context->destBlendAlpha = dstAlpha;
447 }
448 }
449 catch(std::bad_alloc&)
450 {
451 return error(GL_OUT_OF_MEMORY);
452 }
453}
454
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000455void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000456{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000457 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 +0000458 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000459
460 try
461 {
462 if (size < 0)
463 {
464 return error(GL_INVALID_VALUE);
465 }
466
467 switch (usage)
468 {
469 case GL_STREAM_DRAW:
470 case GL_STATIC_DRAW:
471 case GL_DYNAMIC_DRAW:
472 break;
473 default:
474 return error(GL_INVALID_ENUM);
475 }
476
477 gl::Context *context = gl::getContext();
478
479 if (context)
480 {
481 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000482
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000483 switch (target)
484 {
485 case GL_ARRAY_BUFFER:
486 buffer = context->getArrayBuffer();
487 break;
488 case GL_ELEMENT_ARRAY_BUFFER:
489 buffer = context->getElementArrayBuffer();
490 break;
491 default:
492 return error(GL_INVALID_ENUM);
493 }
494
495 if (!buffer)
496 {
497 return error(GL_INVALID_OPERATION);
498 }
499
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000500 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000501 }
502 }
503 catch(std::bad_alloc&)
504 {
505 return error(GL_OUT_OF_MEMORY);
506 }
507}
508
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000509void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000510{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000511 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 +0000512 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000513
514 try
515 {
516 if (size < 0)
517 {
518 return error(GL_INVALID_VALUE);
519 }
520
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000521 if (data == NULL)
522 {
523 return;
524 }
525
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000526 gl::Context *context = gl::getContext();
527
528 if (context)
529 {
530 gl::Buffer *buffer;
531
532 switch (target)
533 {
534 case GL_ARRAY_BUFFER:
535 buffer = context->getArrayBuffer();
536 break;
537 case GL_ELEMENT_ARRAY_BUFFER:
538 buffer = context->getElementArrayBuffer();
539 break;
540 default:
541 return error(GL_INVALID_ENUM);
542 }
543
544 if (!buffer)
545 {
546 return error(GL_INVALID_OPERATION);
547 }
548
549 GLenum err = buffer->bufferSubData(data, size, offset);
550
551 if (err != GL_NO_ERROR)
552 {
553 return error(err);
554 }
555 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000556 }
557 catch(std::bad_alloc&)
558 {
559 return error(GL_OUT_OF_MEMORY);
560 }
561}
562
563GLenum __stdcall glCheckFramebufferStatus(GLenum target)
564{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000565 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000566
567 try
568 {
569 if (target != GL_FRAMEBUFFER)
570 {
571 return error(GL_INVALID_ENUM, 0);
572 }
573
574 gl::Context *context = gl::getContext();
575
576 if (context)
577 {
578 gl::Framebuffer *framebuffer = context->getFramebuffer();
579
580 return framebuffer->completeness();
581 }
582 }
583 catch(std::bad_alloc&)
584 {
585 return error(GL_OUT_OF_MEMORY, 0);
586 }
587
588 return 0;
589}
590
591void __stdcall glClear(GLbitfield mask)
592{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000593 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000594
595 try
596 {
597 gl::Context *context = gl::getContext();
598
599 if (context)
600 {
601 context->clear(mask);
602 }
603 }
604 catch(std::bad_alloc&)
605 {
606 return error(GL_OUT_OF_MEMORY);
607 }
608}
609
610void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
611{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000612 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
613 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000614
615 try
616 {
617 gl::Context *context = gl::getContext();
618
619 if (context)
620 {
621 context->setClearColor(red, green, blue, alpha);
622 }
623 }
624 catch(std::bad_alloc&)
625 {
626 return error(GL_OUT_OF_MEMORY);
627 }
628}
629
630void __stdcall glClearDepthf(GLclampf depth)
631{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000632 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000633
634 try
635 {
636 gl::Context *context = gl::getContext();
637
638 if (context)
639 {
640 context->setClearDepth(depth);
641 }
642 }
643 catch(std::bad_alloc&)
644 {
645 return error(GL_OUT_OF_MEMORY);
646 }
647}
648
649void __stdcall glClearStencil(GLint s)
650{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000651 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000652
653 try
654 {
655 gl::Context *context = gl::getContext();
656
657 if (context)
658 {
659 context->setClearStencil(s);
660 }
661 }
662 catch(std::bad_alloc&)
663 {
664 return error(GL_OUT_OF_MEMORY);
665 }
666}
667
668void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
669{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000670 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
671 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000672
673 try
674 {
675 gl::Context *context = gl::getContext();
676
677 if (context)
678 {
679 context->colorMaskRed = red != GL_FALSE;
680 context->colorMaskGreen = green != GL_FALSE;
681 context->colorMaskBlue = blue != GL_FALSE;
682 context->colorMaskAlpha = alpha != GL_FALSE;
683 }
684 }
685 catch(std::bad_alloc&)
686 {
687 return error(GL_OUT_OF_MEMORY);
688 }
689}
690
691void __stdcall glCompileShader(GLuint shader)
692{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000693 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000694
695 try
696 {
697 gl::Context *context = gl::getContext();
698
699 if (context)
700 {
701 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000702
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000703 if (!shaderObject)
704 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000705 if (context->getProgram(shader))
706 {
707 return error(GL_INVALID_OPERATION);
708 }
709 else
710 {
711 return error(GL_INVALID_VALUE);
712 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000713 }
714
715 shaderObject->compile();
716 }
717 }
718 catch(std::bad_alloc&)
719 {
720 return error(GL_OUT_OF_MEMORY);
721 }
722}
723
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000724void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
725 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000726{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000727 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000728 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000729 target, level, internalformat, width, height, border, imageSize, data);
730
731 try
732 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000733 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
734 {
735 return error(GL_INVALID_ENUM);
736 }
737
738 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000739 {
740 return error(GL_INVALID_VALUE);
741 }
742
daniel@transgaming.com41430492010-03-11 20:36:18 +0000743 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
744 {
745 return error(GL_INVALID_VALUE);
746 }
747
748 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000749 }
750 catch(std::bad_alloc&)
751 {
752 return error(GL_OUT_OF_MEMORY);
753 }
754}
755
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000756void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
757 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000758{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000759 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
760 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000761 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000762 target, level, xoffset, yoffset, width, height, format, imageSize, data);
763
764 try
765 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000766 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
767 {
768 return error(GL_INVALID_ENUM);
769 }
770
771 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000772 {
773 return error(GL_INVALID_VALUE);
774 }
775
daniel@transgaming.com41430492010-03-11 20:36:18 +0000776 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
777 {
778 return error(GL_INVALID_VALUE);
779 }
780
781 if (xoffset != 0 || yoffset != 0)
782 {
783 return error(GL_INVALID_OPERATION);
784 }
785
786 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000787 }
788 catch(std::bad_alloc&)
789 {
790 return error(GL_OUT_OF_MEMORY);
791 }
792}
793
794void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
795{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000796 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
797 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000798 target, level, internalformat, x, y, width, height, border);
799
800 try
801 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000802 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000803 {
804 return error(GL_INVALID_VALUE);
805 }
806
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000807 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
808 {
809 return error(GL_INVALID_VALUE);
810 }
811
812 switch (target)
813 {
814 case GL_TEXTURE_2D:
815 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
816 {
817 return error(GL_INVALID_VALUE);
818 }
819 break;
820 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
821 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
822 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
823 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
824 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
825 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +0000826 if (width != height)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000827 {
828 return error(GL_INVALID_VALUE);
829 }
830
831 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
832 {
833 return error(GL_INVALID_VALUE);
834 }
835 break;
836 default:
837 return error(GL_INVALID_ENUM);
838 }
839
840 switch (internalformat)
841 {
842 case GL_ALPHA:
843 case GL_LUMINANCE:
844 case GL_LUMINANCE_ALPHA:
845 case GL_RGB:
846 case GL_RGBA:
847 break;
848 default:
849 return error(GL_INVALID_VALUE);
850 }
851
852 if (border != 0)
853 {
854 return error(GL_INVALID_VALUE);
855 }
856
857 gl::Context *context = gl::getContext();
858
859 if (context)
860 {
861 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
862
863 if (target == GL_TEXTURE_2D)
864 {
865 gl::Texture2D *texture = context->getTexture2D();
866
867 if (!texture)
868 {
869 return error(GL_INVALID_OPERATION);
870 }
871
872 texture->copyImage(level, internalformat, x, y, width, height, source);
873 }
874 else if (es2dx::IsCubemapTextureTarget(target))
875 {
876 gl::TextureCubeMap *texture = context->getTextureCubeMap();
877
878 if (!texture)
879 {
880 return error(GL_INVALID_OPERATION);
881 }
882
883 texture->copyImage(target, level, internalformat, x, y, width, height, source);
884 }
885 else
886 {
887 UNREACHABLE();
888 }
889 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000890 }
891 catch(std::bad_alloc&)
892 {
893 return error(GL_OUT_OF_MEMORY);
894 }
895}
896
897void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
898{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000899 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
900 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000901 target, level, xoffset, yoffset, x, y, width, height);
902
903 try
904 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000905 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
906 {
907 return error(GL_INVALID_ENUM);
908 }
909
910 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000911 {
912 return error(GL_INVALID_VALUE);
913 }
914
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000915 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
916 {
917 return error(GL_INVALID_VALUE);
918 }
919
920 if (width == 0 || height == 0)
921 {
922 return;
923 }
924
925 gl::Context *context = gl::getContext();
926
927 if (context)
928 {
929 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
930
931 if (target == GL_TEXTURE_2D)
932 {
933 gl::Texture2D *texture = context->getTexture2D();
934
935 if (!texture)
936 {
937 return error(GL_INVALID_OPERATION);
938 }
939
940 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
941 }
942 else if (es2dx::IsCubemapTextureTarget(target))
943 {
944 gl::TextureCubeMap *texture = context->getTextureCubeMap();
945
946 if (!texture)
947 {
948 return error(GL_INVALID_OPERATION);
949 }
950
951 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
952 }
953 else
954 {
955 UNREACHABLE();
956 }
957 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000958 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000959
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000960 catch(std::bad_alloc&)
961 {
962 return error(GL_OUT_OF_MEMORY);
963 }
964}
965
966GLuint __stdcall glCreateProgram(void)
967{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000968 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000969
970 try
971 {
972 gl::Context *context = gl::getContext();
973
974 if (context)
975 {
976 return context->createProgram();
977 }
978 }
979 catch(std::bad_alloc&)
980 {
981 return error(GL_OUT_OF_MEMORY, 0);
982 }
983
984 return 0;
985}
986
987GLuint __stdcall glCreateShader(GLenum type)
988{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000989 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000990
991 try
992 {
993 gl::Context *context = gl::getContext();
994
995 if (context)
996 {
997 switch (type)
998 {
999 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001000 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001001 return context->createShader(type);
1002 default:
1003 return error(GL_INVALID_ENUM, 0);
1004 }
1005 }
1006 }
1007 catch(std::bad_alloc&)
1008 {
1009 return error(GL_OUT_OF_MEMORY, 0);
1010 }
1011
1012 return 0;
1013}
1014
1015void __stdcall glCullFace(GLenum mode)
1016{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001017 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001018
1019 try
1020 {
1021 switch (mode)
1022 {
1023 case GL_FRONT:
1024 case GL_BACK:
1025 case GL_FRONT_AND_BACK:
1026 {
1027 gl::Context *context = gl::getContext();
1028
1029 if (context)
1030 {
1031 context->cullMode = mode;
1032 }
1033 }
1034 break;
1035 default:
1036 return error(GL_INVALID_ENUM);
1037 }
1038 }
1039 catch(std::bad_alloc&)
1040 {
1041 return error(GL_OUT_OF_MEMORY);
1042 }
1043}
1044
1045void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1046{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001047 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001048
1049 try
1050 {
1051 if (n < 0)
1052 {
1053 return error(GL_INVALID_VALUE);
1054 }
1055
1056 gl::Context *context = gl::getContext();
1057
1058 if (context)
1059 {
1060 for (int i = 0; i < n; i++)
1061 {
1062 context->deleteBuffer(buffers[i]);
1063 }
1064 }
1065 }
1066 catch(std::bad_alloc&)
1067 {
1068 return error(GL_OUT_OF_MEMORY);
1069 }
1070}
1071
1072void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1073{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001074 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001075
1076 try
1077 {
1078 if (n < 0)
1079 {
1080 return error(GL_INVALID_VALUE);
1081 }
1082
1083 gl::Context *context = gl::getContext();
1084
1085 if (context)
1086 {
1087 for (int i = 0; i < n; i++)
1088 {
1089 if (framebuffers[i] != 0)
1090 {
1091 context->deleteFramebuffer(framebuffers[i]);
1092 }
1093 }
1094 }
1095 }
1096 catch(std::bad_alloc&)
1097 {
1098 return error(GL_OUT_OF_MEMORY);
1099 }
1100}
1101
1102void __stdcall glDeleteProgram(GLuint program)
1103{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001104 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001105
1106 try
1107 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001108 if (program == 0)
1109 {
1110 return;
1111 }
1112
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001113 gl::Context *context = gl::getContext();
1114
1115 if (context)
1116 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001117 if (!context->getProgram(program))
1118 {
1119 if(context->getShader(program))
1120 {
1121 return error(GL_INVALID_OPERATION);
1122 }
1123 else
1124 {
1125 return error(GL_INVALID_VALUE);
1126 }
1127 }
1128
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001129 context->deleteProgram(program);
1130 }
1131 }
1132 catch(std::bad_alloc&)
1133 {
1134 return error(GL_OUT_OF_MEMORY);
1135 }
1136}
1137
1138void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1139{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001140 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001141
1142 try
1143 {
1144 if (n < 0)
1145 {
1146 return error(GL_INVALID_VALUE);
1147 }
1148
1149 gl::Context *context = gl::getContext();
1150
1151 if (context)
1152 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001153 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001154 {
1155 context->deleteRenderbuffer(renderbuffers[i]);
1156 }
1157 }
1158 }
1159 catch(std::bad_alloc&)
1160 {
1161 return error(GL_OUT_OF_MEMORY);
1162 }
1163}
1164
1165void __stdcall glDeleteShader(GLuint shader)
1166{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001167 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001168
1169 try
1170 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001171 if (shader == 0)
1172 {
1173 return;
1174 }
1175
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001176 gl::Context *context = gl::getContext();
1177
1178 if (context)
1179 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001180 if (!context->getShader(shader))
1181 {
1182 if(context->getProgram(shader))
1183 {
1184 return error(GL_INVALID_OPERATION);
1185 }
1186 else
1187 {
1188 return error(GL_INVALID_VALUE);
1189 }
1190 }
1191
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001192 context->deleteShader(shader);
1193 }
1194 }
1195 catch(std::bad_alloc&)
1196 {
1197 return error(GL_OUT_OF_MEMORY);
1198 }
1199}
1200
1201void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1202{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001203 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001204
1205 try
1206 {
1207 if (n < 0)
1208 {
1209 return error(GL_INVALID_VALUE);
1210 }
1211
1212 gl::Context *context = gl::getContext();
1213
1214 if (context)
1215 {
1216 for (int i = 0; i < n; i++)
1217 {
1218 if (textures[i] != 0)
1219 {
1220 context->deleteTexture(textures[i]);
1221 }
1222 }
1223 }
1224 }
1225 catch(std::bad_alloc&)
1226 {
1227 return error(GL_OUT_OF_MEMORY);
1228 }
1229}
1230
1231void __stdcall glDepthFunc(GLenum func)
1232{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001233 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001234
1235 try
1236 {
1237 switch (func)
1238 {
1239 case GL_NEVER:
1240 case GL_ALWAYS:
1241 case GL_LESS:
1242 case GL_LEQUAL:
1243 case GL_EQUAL:
1244 case GL_GREATER:
1245 case GL_GEQUAL:
1246 case GL_NOTEQUAL:
1247 break;
1248 default:
1249 return error(GL_INVALID_ENUM);
1250 }
1251
1252 gl::Context *context = gl::getContext();
1253
1254 if (context)
1255 {
1256 context->depthFunc = func;
1257 }
1258 }
1259 catch(std::bad_alloc&)
1260 {
1261 return error(GL_OUT_OF_MEMORY);
1262 }
1263}
1264
1265void __stdcall glDepthMask(GLboolean flag)
1266{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001267 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001268
1269 try
1270 {
1271 gl::Context *context = gl::getContext();
1272
1273 if (context)
1274 {
1275 context->depthMask = flag != GL_FALSE;
1276 }
1277 }
1278 catch(std::bad_alloc&)
1279 {
1280 return error(GL_OUT_OF_MEMORY);
1281 }
1282}
1283
1284void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1285{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001286 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001287
1288 try
1289 {
1290 gl::Context *context = gl::getContext();
1291
1292 if (context)
1293 {
1294 context->zNear = zNear;
1295 context->zFar = zFar;
1296 }
1297 }
1298 catch(std::bad_alloc&)
1299 {
1300 return error(GL_OUT_OF_MEMORY);
1301 }
1302}
1303
1304void __stdcall glDetachShader(GLuint program, GLuint shader)
1305{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001306 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001307
1308 try
1309 {
1310 gl::Context *context = gl::getContext();
1311
1312 if (context)
1313 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001314
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001315 gl::Program *programObject = context->getProgram(program);
1316 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001317
1318 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001319 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001320 gl::Shader *shaderByProgramHandle;
1321 shaderByProgramHandle = context->getShader(program);
1322 if (!shaderByProgramHandle)
1323 {
1324 return error(GL_INVALID_VALUE);
1325 }
1326 else
1327 {
1328 return error(GL_INVALID_OPERATION);
1329 }
1330 }
1331
1332 if (!shaderObject)
1333 {
1334 gl::Program *programByShaderHandle = context->getProgram(shader);
1335 if (!programByShaderHandle)
1336 {
1337 return error(GL_INVALID_VALUE);
1338 }
1339 else
1340 {
1341 return error(GL_INVALID_OPERATION);
1342 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001343 }
1344
1345 if (!programObject->detachShader(shaderObject))
1346 {
1347 return error(GL_INVALID_OPERATION);
1348 }
1349
1350 if (shaderObject->isDeletable())
1351 {
1352 context->deleteShader(shader);
1353 }
1354 }
1355 }
1356 catch(std::bad_alloc&)
1357 {
1358 return error(GL_OUT_OF_MEMORY);
1359 }
1360}
1361
1362void __stdcall glDisable(GLenum cap)
1363{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001364 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001365
1366 try
1367 {
1368 gl::Context *context = gl::getContext();
1369
1370 if (context)
1371 {
1372 switch (cap)
1373 {
1374 case GL_CULL_FACE: context->cullFace = false; break;
1375 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1376 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1377 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1378 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1379 case GL_STENCIL_TEST: context->stencilTest = false; break;
1380 case GL_DEPTH_TEST: context->depthTest = false; break;
1381 case GL_BLEND: context->blend = false; break;
1382 case GL_DITHER: context->dither = false; break;
1383 default:
1384 return error(GL_INVALID_ENUM);
1385 }
1386 }
1387 }
1388 catch(std::bad_alloc&)
1389 {
1390 return error(GL_OUT_OF_MEMORY);
1391 }
1392}
1393
1394void __stdcall glDisableVertexAttribArray(GLuint index)
1395{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001396 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001397
1398 try
1399 {
1400 if (index >= gl::MAX_VERTEX_ATTRIBS)
1401 {
1402 return error(GL_INVALID_VALUE);
1403 }
1404
1405 gl::Context *context = gl::getContext();
1406
1407 if (context)
1408 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001409 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001410 }
1411 }
1412 catch(std::bad_alloc&)
1413 {
1414 return error(GL_OUT_OF_MEMORY);
1415 }
1416}
1417
1418void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1419{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001420 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001421
1422 try
1423 {
1424 if (count < 0 || first < 0)
1425 {
1426 return error(GL_INVALID_VALUE);
1427 }
1428
1429 gl::Context *context = gl::getContext();
1430
1431 if (context)
1432 {
1433 context->drawArrays(mode, first, count);
1434 }
1435 }
1436 catch(std::bad_alloc&)
1437 {
1438 return error(GL_OUT_OF_MEMORY);
1439 }
1440}
1441
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001442void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001443{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001444 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 +00001445 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001446
1447 try
1448 {
1449 if (count < 0)
1450 {
1451 return error(GL_INVALID_VALUE);
1452 }
1453
1454 switch (type)
1455 {
1456 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001457 case GL_UNSIGNED_SHORT:
1458 break;
1459 default:
1460 return error(GL_INVALID_ENUM);
1461 }
1462
1463 gl::Context *context = gl::getContext();
1464
1465 if (context)
1466 {
1467 context->drawElements(mode, count, type, indices);
1468 }
1469 }
1470 catch(std::bad_alloc&)
1471 {
1472 return error(GL_OUT_OF_MEMORY);
1473 }
1474}
1475
1476void __stdcall glEnable(GLenum cap)
1477{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001478 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001479
1480 try
1481 {
1482 gl::Context *context = gl::getContext();
1483
1484 if (context)
1485 {
1486 switch (cap)
1487 {
1488 case GL_CULL_FACE: context->cullFace = true; break;
1489 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1490 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1491 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1492 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1493 case GL_STENCIL_TEST: context->stencilTest = true; break;
1494 case GL_DEPTH_TEST: context->depthTest = true; break;
1495 case GL_BLEND: context->blend = true; break;
1496 case GL_DITHER: context->dither = true; break;
1497 default:
1498 return error(GL_INVALID_ENUM);
1499 }
1500 }
1501 }
1502 catch(std::bad_alloc&)
1503 {
1504 return error(GL_OUT_OF_MEMORY);
1505 }
1506}
1507
1508void __stdcall glEnableVertexAttribArray(GLuint index)
1509{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001510 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001511
1512 try
1513 {
1514 if (index >= gl::MAX_VERTEX_ATTRIBS)
1515 {
1516 return error(GL_INVALID_VALUE);
1517 }
1518
1519 gl::Context *context = gl::getContext();
1520
1521 if (context)
1522 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001523 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001524 }
1525 }
1526 catch(std::bad_alloc&)
1527 {
1528 return error(GL_OUT_OF_MEMORY);
1529 }
1530}
1531
1532void __stdcall glFinish(void)
1533{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001534 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001535
1536 try
1537 {
1538 gl::Context *context = gl::getContext();
1539
1540 if (context)
1541 {
1542 context->finish();
1543 }
1544 }
1545 catch(std::bad_alloc&)
1546 {
1547 return error(GL_OUT_OF_MEMORY);
1548 }
1549}
1550
1551void __stdcall glFlush(void)
1552{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001553 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001554
1555 try
1556 {
1557 gl::Context *context = gl::getContext();
1558
1559 if (context)
1560 {
1561 context->flush();
1562 }
1563 }
1564 catch(std::bad_alloc&)
1565 {
1566 return error(GL_OUT_OF_MEMORY);
1567 }
1568}
1569
1570void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1571{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001572 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1573 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001574
1575 try
1576 {
1577 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1578 {
1579 return error(GL_INVALID_ENUM);
1580 }
1581
1582 gl::Context *context = gl::getContext();
1583
1584 if (context)
1585 {
1586 gl::Framebuffer *framebuffer = context->getFramebuffer();
1587
1588 if (context->framebuffer == 0 || !framebuffer)
1589 {
1590 return error(GL_INVALID_OPERATION);
1591 }
1592
1593 switch (attachment)
1594 {
1595 case GL_COLOR_ATTACHMENT0:
1596 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1597 break;
1598 case GL_DEPTH_ATTACHMENT:
1599 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1600 break;
1601 case GL_STENCIL_ATTACHMENT:
1602 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1603 break;
1604 default:
1605 return error(GL_INVALID_ENUM);
1606 }
1607 }
1608 }
1609 catch(std::bad_alloc&)
1610 {
1611 return error(GL_OUT_OF_MEMORY);
1612 }
1613}
1614
1615void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1616{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001617 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1618 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001619
1620 try
1621 {
1622 if (target != GL_FRAMEBUFFER)
1623 {
1624 return error(GL_INVALID_ENUM);
1625 }
1626
1627 switch (attachment)
1628 {
1629 case GL_COLOR_ATTACHMENT0:
1630 break;
1631 default:
1632 return error(GL_INVALID_ENUM);
1633 }
1634
1635 gl::Context *context = gl::getContext();
1636
1637 if (context)
1638 {
1639 if (texture)
1640 {
1641 switch (textarget)
1642 {
1643 case GL_TEXTURE_2D:
1644 if (!context->getTexture2D())
1645 {
1646 return error(GL_INVALID_OPERATION);
1647 }
1648 break;
1649 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1650 UNIMPLEMENTED(); // FIXME
1651 break;
1652 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1653 UNIMPLEMENTED(); // FIXME
1654 break;
1655 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1656 UNIMPLEMENTED(); // FIXME
1657 break;
1658 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1659 UNIMPLEMENTED(); // FIXME
1660 break;
1661 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1662 UNIMPLEMENTED(); // FIXME
1663 break;
1664 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1665 UNIMPLEMENTED(); // FIXME
1666 break;
1667 default:
1668 return error(GL_INVALID_ENUM);
1669 }
1670
1671 if (level != 0)
1672 {
1673 return error(GL_INVALID_VALUE);
1674 }
1675 }
1676
1677 gl::Framebuffer *framebuffer = context->getFramebuffer();
1678
1679 if (context->framebuffer == 0 || !framebuffer)
1680 {
1681 return error(GL_INVALID_OPERATION);
1682 }
1683
1684 framebuffer->setColorbuffer(GL_TEXTURE, texture);
1685 }
1686 }
1687 catch(std::bad_alloc&)
1688 {
1689 return error(GL_OUT_OF_MEMORY);
1690 }
1691}
1692
1693void __stdcall glFrontFace(GLenum mode)
1694{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001695 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001696
1697 try
1698 {
1699 switch (mode)
1700 {
1701 case GL_CW:
1702 case GL_CCW:
1703 {
1704 gl::Context *context = gl::getContext();
1705
1706 if (context)
1707 {
1708 context->frontFace = mode;
1709 }
1710 }
1711 break;
1712 default:
1713 return error(GL_INVALID_ENUM);
1714 }
1715 }
1716 catch(std::bad_alloc&)
1717 {
1718 return error(GL_OUT_OF_MEMORY);
1719 }
1720}
1721
1722void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1723{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001724 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001725
1726 try
1727 {
1728 if (n < 0)
1729 {
1730 return error(GL_INVALID_VALUE);
1731 }
1732
1733 gl::Context *context = gl::getContext();
1734
1735 if (context)
1736 {
1737 for (int i = 0; i < n; i++)
1738 {
1739 buffers[i] = context->createBuffer();
1740 }
1741 }
1742 }
1743 catch(std::bad_alloc&)
1744 {
1745 return error(GL_OUT_OF_MEMORY);
1746 }
1747}
1748
1749void __stdcall glGenerateMipmap(GLenum target)
1750{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001751 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001752
1753 try
1754 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00001755 gl::Context *context = gl::getContext();
1756
1757 if (context)
1758 {
1759 gl::Texture *texture;
1760
1761 switch (target)
1762 {
1763 case GL_TEXTURE_2D:
1764 texture = context->getTexture2D();
1765 break;
1766
1767 case GL_TEXTURE_CUBE_MAP:
1768 texture = context->getTextureCubeMap();
1769 break;
1770
1771 default:
1772 return error(GL_INVALID_ENUM);
1773 }
1774
1775 texture->generateMipmaps();
1776 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001777 }
1778 catch(std::bad_alloc&)
1779 {
1780 return error(GL_OUT_OF_MEMORY);
1781 }
1782}
1783
1784void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1785{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001786 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001787
1788 try
1789 {
1790 if (n < 0)
1791 {
1792 return error(GL_INVALID_VALUE);
1793 }
1794
1795 gl::Context *context = gl::getContext();
1796
1797 if (context)
1798 {
1799 for (int i = 0; i < n; i++)
1800 {
1801 framebuffers[i] = context->createFramebuffer();
1802 }
1803 }
1804 }
1805 catch(std::bad_alloc&)
1806 {
1807 return error(GL_OUT_OF_MEMORY);
1808 }
1809}
1810
1811void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1812{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001813 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001814
1815 try
1816 {
1817 if (n < 0)
1818 {
1819 return error(GL_INVALID_VALUE);
1820 }
1821
1822 gl::Context *context = gl::getContext();
1823
1824 if (context)
1825 {
1826 for (int i = 0; i < n; i++)
1827 {
1828 renderbuffers[i] = context->createRenderbuffer();
1829 }
1830 }
1831 }
1832 catch(std::bad_alloc&)
1833 {
1834 return error(GL_OUT_OF_MEMORY);
1835 }
1836}
1837
1838void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1839{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001840 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001841
1842 try
1843 {
1844 if (n < 0)
1845 {
1846 return error(GL_INVALID_VALUE);
1847 }
1848
1849 gl::Context *context = gl::getContext();
1850
1851 if (context)
1852 {
1853 for (int i = 0; i < n; i++)
1854 {
1855 textures[i] = context->createTexture();
1856 }
1857 }
1858 }
1859 catch(std::bad_alloc&)
1860 {
1861 return error(GL_OUT_OF_MEMORY);
1862 }
1863}
1864
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001865void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001866{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001867 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001868 "GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001869 program, index, bufsize, length, size, type, name);
1870
1871 try
1872 {
1873 if (bufsize < 0)
1874 {
1875 return error(GL_INVALID_VALUE);
1876 }
1877
1878 UNIMPLEMENTED(); // FIXME
1879 }
1880 catch(std::bad_alloc&)
1881 {
1882 return error(GL_OUT_OF_MEMORY);
1883 }
1884}
1885
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001886void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001887{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001888 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001889 "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 +00001890 program, index, bufsize, length, size, type, name);
1891
1892 try
1893 {
1894 if (bufsize < 0)
1895 {
1896 return error(GL_INVALID_VALUE);
1897 }
1898
1899 UNIMPLEMENTED(); // FIXME
1900 }
1901 catch(std::bad_alloc&)
1902 {
1903 return error(GL_OUT_OF_MEMORY);
1904 }
1905}
1906
1907void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1908{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001909 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1910 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001911
1912 try
1913 {
1914 if (maxcount < 0)
1915 {
1916 return error(GL_INVALID_VALUE);
1917 }
1918
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001919 gl::Context *context = gl::getContext();
1920
1921 if (context)
1922 {
1923 gl::Program *programObject = context->getProgram(program);
1924
1925 if (!programObject)
1926 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001927 if (context->getShader(program))
1928 {
1929 return error(GL_INVALID_OPERATION);
1930 }
1931 else
1932 {
1933 return error(GL_INVALID_VALUE);
1934 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001935 }
1936
1937 return programObject->getAttachedShaders(maxcount, count, shaders);
1938 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001939 }
1940 catch(std::bad_alloc&)
1941 {
1942 return error(GL_OUT_OF_MEMORY);
1943 }
1944}
1945
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001946int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001947{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001948 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001949
1950 try
1951 {
1952 gl::Context *context = gl::getContext();
1953
1954 if (context)
1955 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001956
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001957 gl::Program *programObject = context->getProgram(program);
1958
1959 if (!programObject)
1960 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001961 if (context->getShader(program))
1962 {
1963 return error(GL_INVALID_OPERATION, -1);
1964 }
1965 else
1966 {
1967 return error(GL_INVALID_VALUE, -1);
1968 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001969 }
1970
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00001971 if (!programObject->isLinked())
1972 {
1973 return error(GL_INVALID_OPERATION, -1);
1974 }
1975
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001976 return programObject->getAttributeLocation(name);
1977 }
1978 }
1979 catch(std::bad_alloc&)
1980 {
1981 return error(GL_OUT_OF_MEMORY, -1);
1982 }
1983
1984 return -1;
1985}
1986
1987void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1988{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001989 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001990
1991 try
1992 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001993 gl::Context *context = gl::getContext();
1994
1995 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001996 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001997 if (!(context->getBooleanv(pname, params)))
1998 {
1999 GLenum nativeType;
2000 unsigned int numParams = 0;
2001 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2002 return error(GL_INVALID_ENUM);
2003
2004 if (numParams == 0)
2005 return; // it is known that the pname is valid, but there are no parameters to return
2006
2007 if (nativeType == GL_FLOAT)
2008 {
2009 GLfloat *floatParams = NULL;
2010 floatParams = new GLfloat[numParams];
2011
2012 context->getFloatv(pname, floatParams);
2013
2014 for (unsigned int i = 0; i < numParams; ++i)
2015 {
2016 if (floatParams[i] == 0.0f)
2017 params[i] = GL_FALSE;
2018 else
2019 params[i] = GL_TRUE;
2020 }
2021
2022 delete [] floatParams;
2023 }
2024 else if (nativeType == GL_INT)
2025 {
2026 GLint *intParams = NULL;
2027 intParams = new GLint[numParams];
2028
2029 context->getIntegerv(pname, intParams);
2030
2031 for (unsigned int i = 0; i < numParams; ++i)
2032 {
2033 if (intParams[i] == 0)
2034 params[i] = GL_FALSE;
2035 else
2036 params[i] = GL_TRUE;
2037 }
2038
2039 delete [] intParams;
2040 }
2041 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002042 }
2043 }
2044 catch(std::bad_alloc&)
2045 {
2046 return error(GL_OUT_OF_MEMORY);
2047 }
2048}
2049
2050void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2051{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002052 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 +00002053
2054 try
2055 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002056 gl::Context *context = gl::getContext();
2057
2058 if (context)
2059 {
2060 gl::Buffer *buffer;
2061
2062 switch (target)
2063 {
2064 case GL_ARRAY_BUFFER:
2065 buffer = context->getArrayBuffer();
2066 break;
2067 case GL_ELEMENT_ARRAY_BUFFER:
2068 buffer = context->getElementArrayBuffer();
2069 break;
2070 default: return error(GL_INVALID_ENUM);
2071 }
2072
2073 if (!buffer)
2074 {
2075 // A null buffer means that "0" is bound to the requested buffer target
2076 return error(GL_INVALID_OPERATION);
2077 }
2078
2079 switch (pname)
2080 {
2081 case GL_BUFFER_USAGE:
2082 *params = buffer->usage();
2083 break;
2084 case GL_BUFFER_SIZE:
2085 *params = buffer->size();
2086 break;
2087 default: return error(GL_INVALID_ENUM);
2088 }
2089 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002090 }
2091 catch(std::bad_alloc&)
2092 {
2093 return error(GL_OUT_OF_MEMORY);
2094 }
2095}
2096
2097GLenum __stdcall glGetError(void)
2098{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002099 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002100
2101 gl::Context *context = gl::getContext();
2102
2103 if (context)
2104 {
2105 return context->getError();
2106 }
2107
2108 return GL_NO_ERROR;
2109}
2110
2111void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2112{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002113 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002114
2115 try
2116 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002117 gl::Context *context = gl::getContext();
2118
2119 if (context)
2120 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002121 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002122 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002123 GLenum nativeType;
2124 unsigned int numParams = 0;
2125 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2126 return error(GL_INVALID_ENUM);
2127
2128 if (numParams == 0)
2129 return; // it is known that the pname is valid, but that there are no parameters to return.
2130
2131 if (nativeType == GL_BOOL)
2132 {
2133 GLboolean *boolParams = NULL;
2134 boolParams = new GLboolean[numParams];
2135
2136 context->getBooleanv(pname, boolParams);
2137
2138 for (unsigned int i = 0; i < numParams; ++i)
2139 {
2140 if (boolParams[i] == GL_FALSE)
2141 params[i] = 0.0f;
2142 else
2143 params[i] = 1.0f;
2144 }
2145
2146 delete [] boolParams;
2147 }
2148 else if (nativeType == GL_INT)
2149 {
2150 GLint *intParams = NULL;
2151 intParams = new GLint[numParams];
2152
2153 context->getIntegerv(pname, intParams);
2154
2155 for (unsigned int i = 0; i < numParams; ++i)
2156 {
2157 params[i] = (GLfloat)intParams[i];
2158 }
2159
2160 delete [] intParams;
2161 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002162 }
2163 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002164 }
2165 catch(std::bad_alloc&)
2166 {
2167 return error(GL_OUT_OF_MEMORY);
2168 }
2169}
2170
2171void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2172{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002173 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2174 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002175
2176 try
2177 {
2178 gl::Context *context = gl::getContext();
2179
2180 if (context)
2181 {
2182 if (context->framebuffer == 0)
2183 {
2184 return error(GL_INVALID_OPERATION);
2185 }
2186
2187 UNIMPLEMENTED(); // FIXME
2188 }
2189 }
2190 catch(std::bad_alloc&)
2191 {
2192 return error(GL_OUT_OF_MEMORY);
2193 }
2194}
2195
2196void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2197{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002198 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002199
2200 try
2201 {
2202 gl::Context *context = gl::getContext();
2203
2204 if (context)
2205 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002206 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002207 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002208 GLenum nativeType;
2209 unsigned int numParams = 0;
2210 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2211 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002212
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002213 if (numParams == 0)
2214 return; // it is known that pname is valid, but there are no parameters to return
2215
2216 if (nativeType == GL_BOOL)
2217 {
2218 GLboolean *boolParams = NULL;
2219 boolParams = new GLboolean[numParams];
2220
2221 context->getBooleanv(pname, boolParams);
2222
2223 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002224 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002225 if (boolParams[i] == GL_FALSE)
2226 params[i] = 0;
2227 else
2228 params[i] = 1;
2229 }
2230
2231 delete [] boolParams;
2232 }
2233 else if (nativeType == GL_FLOAT)
2234 {
2235 GLfloat *floatParams = NULL;
2236 floatParams = new GLfloat[numParams];
2237
2238 context->getFloatv(pname, floatParams);
2239
2240 for (unsigned int i = 0; i < numParams; ++i)
2241 {
2242 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002243 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002244 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002245 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002246 else
2247 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 +00002248 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002249
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002250 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002251 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002252 }
2253 }
2254 }
2255 catch(std::bad_alloc&)
2256 {
2257 return error(GL_OUT_OF_MEMORY);
2258 }
2259}
2260
2261void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2262{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002263 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002264
2265 try
2266 {
2267 gl::Context *context = gl::getContext();
2268
2269 if (context)
2270 {
2271 gl::Program *programObject = context->getProgram(program);
2272
2273 if (!programObject)
2274 {
2275 return error(GL_INVALID_VALUE);
2276 }
2277
2278 switch (pname)
2279 {
2280 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002281 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002282 return;
2283 case GL_LINK_STATUS:
2284 *params = programObject->isLinked();
2285 return;
2286 case GL_VALIDATE_STATUS:
2287 UNIMPLEMENTED(); // FIXME
2288 *params = GL_TRUE;
2289 return;
2290 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002291 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002292 return;
2293 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002294 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002295 return;
2296 case GL_ACTIVE_ATTRIBUTES:
2297 UNIMPLEMENTED(); // FIXME
2298 *params = 0;
2299 return;
2300 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2301 UNIMPLEMENTED(); // FIXME
2302 *params = 0;
2303 return;
2304 case GL_ACTIVE_UNIFORMS:
2305 UNIMPLEMENTED(); // FIXME
2306 *params = 0;
2307 return;
2308 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2309 UNIMPLEMENTED(); // FIXME
2310 *params = 0;
2311 return;
2312 default:
2313 return error(GL_INVALID_ENUM);
2314 }
2315 }
2316 }
2317 catch(std::bad_alloc&)
2318 {
2319 return error(GL_OUT_OF_MEMORY);
2320 }
2321}
2322
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002323void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002324{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002325 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 +00002326 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002327
2328 try
2329 {
2330 if (bufsize < 0)
2331 {
2332 return error(GL_INVALID_VALUE);
2333 }
2334
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002335 gl::Context *context = gl::getContext();
2336
2337 if (context)
2338 {
2339 gl::Program *programObject = context->getProgram(program);
2340
2341 if (!programObject)
2342 {
2343 return error(GL_INVALID_VALUE);
2344 }
2345
2346 programObject->getInfoLog(bufsize, length, infolog);
2347 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002348 }
2349 catch(std::bad_alloc&)
2350 {
2351 return error(GL_OUT_OF_MEMORY);
2352 }
2353}
2354
2355void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2356{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002357 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 +00002358
2359 try
2360 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002361 gl::Context *context = gl::getContext();
2362
2363 if (context)
2364 {
2365 if (target != GL_RENDERBUFFER)
2366 {
2367 return error(GL_INVALID_ENUM);
2368 }
2369
2370 if (context->renderbuffer == 0)
2371 {
2372 return error(GL_INVALID_OPERATION);
2373 }
2374
2375 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->renderbuffer);
2376
2377 switch (pname)
2378 {
2379 case GL_RENDERBUFFER_WIDTH:
2380 *params = renderbuffer->getWidth();
2381 break;
2382 case GL_RENDERBUFFER_HEIGHT:
2383 *params = renderbuffer->getHeight();
2384 break;
2385 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2386 *params = renderbuffer->getFormat();
2387 break;
2388 case GL_RENDERBUFFER_RED_SIZE:
2389 if (renderbuffer->isColorbuffer())
2390 {
2391 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
2392 }
2393 else
2394 {
2395 *params = 0;
2396 }
2397 break;
2398 case GL_RENDERBUFFER_GREEN_SIZE:
2399 if (renderbuffer->isColorbuffer())
2400 {
2401 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
2402 }
2403 else
2404 {
2405 *params = 0;
2406 }
2407 break;
2408 case GL_RENDERBUFFER_BLUE_SIZE:
2409 if (renderbuffer->isColorbuffer())
2410 {
2411 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
2412 }
2413 else
2414 {
2415 *params = 0;
2416 }
2417 break;
2418 case GL_RENDERBUFFER_ALPHA_SIZE:
2419 if (renderbuffer->isColorbuffer())
2420 {
2421 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
2422 }
2423 else
2424 {
2425 *params = 0;
2426 }
2427 break;
2428 case GL_RENDERBUFFER_DEPTH_SIZE:
2429 if (renderbuffer->isDepthbuffer())
2430 {
2431 *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
2432 }
2433 else
2434 {
2435 *params = 0;
2436 }
2437 break;
2438 case GL_RENDERBUFFER_STENCIL_SIZE:
2439 if (renderbuffer->isStencilbuffer())
2440 {
2441 *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
2442 }
2443 else
2444 {
2445 *params = 0;
2446 }
2447 break;
2448 default:
2449 return error(GL_INVALID_ENUM);
2450 }
2451 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002452 }
2453 catch(std::bad_alloc&)
2454 {
2455 return error(GL_OUT_OF_MEMORY);
2456 }
2457}
2458
2459void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2460{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002461 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002462
2463 try
2464 {
2465 gl::Context *context = gl::getContext();
2466
2467 if (context)
2468 {
2469 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002470
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002471 if (!shaderObject)
2472 {
2473 return error(GL_INVALID_VALUE);
2474 }
2475
2476 switch (pname)
2477 {
2478 case GL_SHADER_TYPE:
2479 *params = shaderObject->getType();
2480 return;
2481 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002482 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002483 return;
2484 case GL_COMPILE_STATUS:
2485 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2486 return;
2487 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002488 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002489 return;
2490 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002491 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002492 return;
2493 default:
2494 return error(GL_INVALID_ENUM);
2495 }
2496 }
2497 }
2498 catch(std::bad_alloc&)
2499 {
2500 return error(GL_OUT_OF_MEMORY);
2501 }
2502}
2503
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002504void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002505{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002506 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 +00002507 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002508
2509 try
2510 {
2511 if (bufsize < 0)
2512 {
2513 return error(GL_INVALID_VALUE);
2514 }
2515
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002516 gl::Context *context = gl::getContext();
2517
2518 if (context)
2519 {
2520 gl::Shader *shaderObject = context->getShader(shader);
2521
2522 if (!shaderObject)
2523 {
2524 return error(GL_INVALID_VALUE);
2525 }
2526
2527 shaderObject->getInfoLog(bufsize, length, infolog);
2528 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002529 }
2530 catch(std::bad_alloc&)
2531 {
2532 return error(GL_OUT_OF_MEMORY);
2533 }
2534}
2535
2536void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2537{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002538 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2539 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002540
2541 try
2542 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002543 switch (shadertype)
2544 {
2545 case GL_VERTEX_SHADER:
2546 case GL_FRAGMENT_SHADER:
2547 break;
2548 default:
2549 return error(GL_INVALID_ENUM);
2550 }
2551
2552 switch (precisiontype)
2553 {
2554 case GL_LOW_FLOAT:
2555 case GL_MEDIUM_FLOAT:
2556 case GL_HIGH_FLOAT:
2557 // Assume IEEE 754 precision
2558 range[0] = 127;
2559 range[1] = 127;
2560 precision[0] = 23;
2561 precision[1] = 23;
2562 break;
2563 case GL_LOW_INT:
2564 case GL_MEDIUM_INT:
2565 case GL_HIGH_INT:
2566 // Some (most) hardware only supports single-precision floating-point numbers,
2567 // which can accurately represent integers up to +/-16777216
2568 range[0] = 24;
2569 range[1] = 24;
2570 precision[0] = 0;
2571 precision[1] = 0;
2572 break;
2573 default:
2574 return error(GL_INVALID_ENUM);
2575 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002576 }
2577 catch(std::bad_alloc&)
2578 {
2579 return error(GL_OUT_OF_MEMORY);
2580 }
2581}
2582
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002583void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002584{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002585 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 +00002586 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002587
2588 try
2589 {
2590 if (bufsize < 0)
2591 {
2592 return error(GL_INVALID_VALUE);
2593 }
2594
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002595 gl::Context *context = gl::getContext();
2596
2597 if (context)
2598 {
2599 gl::Shader *shaderObject = context->getShader(shader);
2600
2601 if (!shaderObject)
2602 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002603 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002604 }
2605
2606 shaderObject->getSource(bufsize, length, source);
2607 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002608 }
2609 catch(std::bad_alloc&)
2610 {
2611 return error(GL_OUT_OF_MEMORY);
2612 }
2613}
2614
2615const GLubyte* __stdcall glGetString(GLenum name)
2616{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002617 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002618
2619 try
2620 {
2621 switch (name)
2622 {
2623 case GL_VENDOR:
2624 return (GLubyte*)"TransGaming Inc.";
2625 case GL_RENDERER:
2626 return (GLubyte*)"ANGLE";
2627 case GL_VERSION:
2628 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2629 case GL_SHADING_LANGUAGE_VERSION:
2630 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2631 case GL_EXTENSIONS:
2632 return (GLubyte*)"";
2633 default:
2634 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2635 }
2636 }
2637 catch(std::bad_alloc&)
2638 {
2639 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2640 }
2641
2642 return NULL;
2643}
2644
2645void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2646{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002647 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 +00002648
2649 try
2650 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002651 gl::Context *context = gl::getContext();
2652
2653 if (context)
2654 {
2655 gl::Texture *texture;
2656
2657 switch (target)
2658 {
2659 case GL_TEXTURE_2D:
2660 texture = context->getTexture2D();
2661 break;
2662 case GL_TEXTURE_CUBE_MAP:
2663 texture = context->getTextureCubeMap();
2664 break;
2665 default:
2666 return error(GL_INVALID_ENUM);
2667 }
2668
2669 switch (pname)
2670 {
2671 case GL_TEXTURE_MAG_FILTER:
2672 *params = (GLfloat)texture->getMagFilter();
2673 break;
2674 case GL_TEXTURE_MIN_FILTER:
2675 *params = (GLfloat)texture->getMinFilter();
2676 break;
2677 case GL_TEXTURE_WRAP_S:
2678 *params = (GLfloat)texture->getWrapS();
2679 break;
2680 case GL_TEXTURE_WRAP_T:
2681 *params = (GLfloat)texture->getWrapT();
2682 break;
2683 default:
2684 return error(GL_INVALID_ENUM);
2685 }
2686 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002687 }
2688 catch(std::bad_alloc&)
2689 {
2690 return error(GL_OUT_OF_MEMORY);
2691 }
2692}
2693
2694void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2695{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002696 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 +00002697
2698 try
2699 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002700 gl::Context *context = gl::getContext();
2701
2702 if (context)
2703 {
2704 gl::Texture *texture;
2705
2706 switch (target)
2707 {
2708 case GL_TEXTURE_2D:
2709 texture = context->getTexture2D();
2710 break;
2711 case GL_TEXTURE_CUBE_MAP:
2712 texture = context->getTextureCubeMap();
2713 break;
2714 default:
2715 return error(GL_INVALID_ENUM);
2716 }
2717
2718 switch (pname)
2719 {
2720 case GL_TEXTURE_MAG_FILTER:
2721 *params = texture->getMagFilter();
2722 break;
2723 case GL_TEXTURE_MIN_FILTER:
2724 *params = texture->getMinFilter();
2725 break;
2726 case GL_TEXTURE_WRAP_S:
2727 *params = texture->getWrapS();
2728 break;
2729 case GL_TEXTURE_WRAP_T:
2730 *params = texture->getWrapT();
2731 break;
2732 default:
2733 return error(GL_INVALID_ENUM);
2734 }
2735 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002736 }
2737 catch(std::bad_alloc&)
2738 {
2739 return error(GL_OUT_OF_MEMORY);
2740 }
2741}
2742
2743void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2744{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002745 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002746
2747 try
2748 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002749 gl::Context *context = gl::getContext();
2750
2751 if (context)
2752 {
2753 if (program == 0)
2754 {
2755 return error(GL_INVALID_VALUE);
2756 }
2757
2758 gl::Program *programObject = context->getProgram(program);
2759
2760 if (!programObject || !programObject->isLinked())
2761 {
2762 return error(GL_INVALID_OPERATION);
2763 }
2764
2765 if (!programObject->getUniformfv(location, params))
2766 {
2767 return error(GL_INVALID_OPERATION);
2768 }
2769 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002770 }
2771 catch(std::bad_alloc&)
2772 {
2773 return error(GL_OUT_OF_MEMORY);
2774 }
2775}
2776
2777void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2778{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002779 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002780
2781 try
2782 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002783 gl::Context *context = gl::getContext();
2784
2785 if (context)
2786 {
2787 if (program == 0)
2788 {
2789 return error(GL_INVALID_VALUE);
2790 }
2791
2792 gl::Program *programObject = context->getProgram(program);
2793
2794 if (!programObject || !programObject->isLinked())
2795 {
2796 return error(GL_INVALID_OPERATION);
2797 }
2798
2799 if (!programObject)
2800 {
2801 return error(GL_INVALID_OPERATION);
2802 }
2803
2804 if (!programObject->getUniformiv(location, params))
2805 {
2806 return error(GL_INVALID_OPERATION);
2807 }
2808 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002809 }
2810 catch(std::bad_alloc&)
2811 {
2812 return error(GL_OUT_OF_MEMORY);
2813 }
2814}
2815
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002816int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002817{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002818 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002819
2820 try
2821 {
2822 gl::Context *context = gl::getContext();
2823
2824 if (strstr(name, "gl_") == name)
2825 {
2826 return -1;
2827 }
2828
2829 if (context)
2830 {
2831 gl::Program *programObject = context->getProgram(program);
2832
2833 if (!programObject)
2834 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002835 if (context->getShader(program))
2836 {
2837 return error(GL_INVALID_OPERATION, -1);
2838 }
2839 else
2840 {
2841 return error(GL_INVALID_VALUE, -1);
2842 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002843 }
2844
2845 if (!programObject->isLinked())
2846 {
2847 return error(GL_INVALID_OPERATION, -1);
2848 }
2849
2850 return programObject->getUniformLocation(name);
2851 }
2852 }
2853 catch(std::bad_alloc&)
2854 {
2855 return error(GL_OUT_OF_MEMORY, -1);
2856 }
2857
2858 return -1;
2859}
2860
2861void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2862{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002863 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002864
2865 try
2866 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002867 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002868
daniel@transgaming.come0078962010-04-15 20:45:08 +00002869 if (context)
2870 {
2871 if (index >= gl::MAX_VERTEX_ATTRIBS)
2872 {
2873 return error(GL_INVALID_VALUE);
2874 }
2875
2876 switch (pname)
2877 {
2878 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2879 *params = (GLfloat)(context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2880 break;
2881 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2882 *params = (GLfloat)context->vertexAttribute[index].mSize;
2883 break;
2884 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2885 *params = (GLfloat)context->vertexAttribute[index].mStride;
2886 break;
2887 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2888 *params = (GLfloat)context->vertexAttribute[index].mType;
2889 break;
2890 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2891 *params = (GLfloat)(context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2892 break;
2893 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2894 *params = (GLfloat)context->vertexAttribute[index].mBoundBuffer;
2895 break;
2896 case GL_CURRENT_VERTEX_ATTRIB:
2897 for (int i = 0; i < 4; ++i)
2898 {
2899 params[i] = context->vertexAttribute[index].mCurrentValue[i];
2900 }
2901 break;
2902 default: return error(GL_INVALID_ENUM);
2903 }
2904 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002905 }
2906 catch(std::bad_alloc&)
2907 {
2908 return error(GL_OUT_OF_MEMORY);
2909 }
2910}
2911
2912void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2913{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002914 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002915
2916 try
2917 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002918 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002919
daniel@transgaming.come0078962010-04-15 20:45:08 +00002920 if (context)
2921 {
2922 if (index >= gl::MAX_VERTEX_ATTRIBS)
2923 {
2924 return error(GL_INVALID_VALUE);
2925 }
2926
2927 switch (pname)
2928 {
2929 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2930 *params = (context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2931 break;
2932 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2933 *params = context->vertexAttribute[index].mSize;
2934 break;
2935 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2936 *params = context->vertexAttribute[index].mStride;
2937 break;
2938 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2939 *params = context->vertexAttribute[index].mType;
2940 break;
2941 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2942 *params = (context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2943 break;
2944 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2945 *params = context->vertexAttribute[index].mBoundBuffer;
2946 break;
2947 case GL_CURRENT_VERTEX_ATTRIB:
2948 for (int i = 0; i < 4; ++i)
2949 {
2950 float currentValue = context->vertexAttribute[index].mCurrentValue[i];
2951 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
2952 }
2953 break;
2954 default: return error(GL_INVALID_ENUM);
2955 }
2956 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002957 }
2958 catch(std::bad_alloc&)
2959 {
2960 return error(GL_OUT_OF_MEMORY);
2961 }
2962}
2963
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002964void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002965{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002966 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002967
2968 try
2969 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002970 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002971
daniel@transgaming.come0078962010-04-15 20:45:08 +00002972 if (context)
2973 {
2974 if (index >= gl::MAX_VERTEX_ATTRIBS)
2975 {
2976 return error(GL_INVALID_VALUE);
2977 }
2978
2979 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
2980 {
2981 return error(GL_INVALID_ENUM);
2982 }
2983
2984 *pointer = const_cast<GLvoid*>(context->vertexAttribute[index].mPointer);
2985 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002986 }
2987 catch(std::bad_alloc&)
2988 {
2989 return error(GL_OUT_OF_MEMORY);
2990 }
2991}
2992
2993void __stdcall glHint(GLenum target, GLenum mode)
2994{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002995 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002996
2997 try
2998 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002999 switch (target)
3000 {
3001 case GL_GENERATE_MIPMAP_HINT:
3002 switch (mode)
3003 {
3004 case GL_FASTEST:
3005 case GL_NICEST:
3006 case GL_DONT_CARE:
3007 break;
3008 default:
3009 return error(GL_INVALID_ENUM);
3010 }
3011 break;
3012 default:
3013 return error(GL_INVALID_ENUM);
3014 }
3015
3016 gl::Context *context = gl::getContext();
3017 if (context)
3018 {
3019 if (target == GL_GENERATE_MIPMAP_HINT)
3020 context->generateMipmapHint = mode;
3021 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003022 }
3023 catch(std::bad_alloc&)
3024 {
3025 return error(GL_OUT_OF_MEMORY);
3026 }
3027}
3028
3029GLboolean __stdcall glIsBuffer(GLuint buffer)
3030{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003031 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003032
3033 try
3034 {
3035 gl::Context *context = gl::getContext();
3036
3037 if (context && buffer)
3038 {
3039 gl::Buffer *bufferObject = context->getBuffer(buffer);
3040
3041 if (bufferObject)
3042 {
3043 return GL_TRUE;
3044 }
3045 }
3046 }
3047 catch(std::bad_alloc&)
3048 {
3049 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3050 }
3051
3052 return GL_FALSE;
3053}
3054
3055GLboolean __stdcall glIsEnabled(GLenum cap)
3056{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003057 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003058
3059 try
3060 {
3061 gl::Context *context = gl::getContext();
3062
3063 if (context)
3064 {
3065 switch (cap)
3066 {
3067 case GL_CULL_FACE: return context->cullFace;
3068 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
3069 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
3070 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
3071 case GL_SCISSOR_TEST: return context->scissorTest;
3072 case GL_STENCIL_TEST: return context->stencilTest;
3073 case GL_DEPTH_TEST: return context->depthTest;
3074 case GL_BLEND: return context->blend;
3075 case GL_DITHER: return context->dither;
3076 default:
3077 return error(GL_INVALID_ENUM, false);
3078 }
3079 }
3080 }
3081 catch(std::bad_alloc&)
3082 {
3083 return error(GL_OUT_OF_MEMORY, false);
3084 }
3085
3086 return false;
3087}
3088
3089GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3090{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003091 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003092
3093 try
3094 {
3095 gl::Context *context = gl::getContext();
3096
3097 if (context && framebuffer)
3098 {
3099 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3100
3101 if (framebufferObject)
3102 {
3103 return GL_TRUE;
3104 }
3105 }
3106 }
3107 catch(std::bad_alloc&)
3108 {
3109 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3110 }
3111
3112 return GL_FALSE;
3113}
3114
3115GLboolean __stdcall glIsProgram(GLuint program)
3116{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003117 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003118
3119 try
3120 {
3121 gl::Context *context = gl::getContext();
3122
3123 if (context && program)
3124 {
3125 gl::Program *programObject = context->getProgram(program);
3126
3127 if (programObject)
3128 {
3129 return GL_TRUE;
3130 }
3131 }
3132 }
3133 catch(std::bad_alloc&)
3134 {
3135 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3136 }
3137
3138 return GL_FALSE;
3139}
3140
3141GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3142{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003143 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003144
3145 try
3146 {
3147 gl::Context *context = gl::getContext();
3148
3149 if (context && renderbuffer)
3150 {
3151 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3152
3153 if (renderbufferObject)
3154 {
3155 return GL_TRUE;
3156 }
3157 }
3158 }
3159 catch(std::bad_alloc&)
3160 {
3161 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3162 }
3163
3164 return GL_FALSE;
3165}
3166
3167GLboolean __stdcall glIsShader(GLuint shader)
3168{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003169 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003170
3171 try
3172 {
3173 gl::Context *context = gl::getContext();
3174
3175 if (context && shader)
3176 {
3177 gl::Shader *shaderObject = context->getShader(shader);
3178
3179 if (shaderObject)
3180 {
3181 return GL_TRUE;
3182 }
3183 }
3184 }
3185 catch(std::bad_alloc&)
3186 {
3187 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3188 }
3189
3190 return GL_FALSE;
3191}
3192
3193GLboolean __stdcall glIsTexture(GLuint texture)
3194{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003195 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003196
3197 try
3198 {
3199 gl::Context *context = gl::getContext();
3200
3201 if (context && texture)
3202 {
3203 gl::Texture *textureObject = context->getTexture(texture);
3204
3205 if (textureObject)
3206 {
3207 return GL_TRUE;
3208 }
3209 }
3210 }
3211 catch(std::bad_alloc&)
3212 {
3213 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3214 }
3215
3216 return GL_FALSE;
3217}
3218
3219void __stdcall glLineWidth(GLfloat width)
3220{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003221 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003222
3223 try
3224 {
3225 if (width <= 0.0f)
3226 {
3227 return error(GL_INVALID_VALUE);
3228 }
3229
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003230 gl::Context *context = gl::getContext();
3231
3232 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003233 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003234 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003235 }
3236 }
3237 catch(std::bad_alloc&)
3238 {
3239 return error(GL_OUT_OF_MEMORY);
3240 }
3241}
3242
3243void __stdcall glLinkProgram(GLuint program)
3244{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003245 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003246
3247 try
3248 {
3249 gl::Context *context = gl::getContext();
3250
3251 if (context)
3252 {
3253 gl::Program *programObject = context->getProgram(program);
3254
3255 if (!programObject)
3256 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003257 if (context->getShader(program))
3258 {
3259 return error(GL_INVALID_OPERATION);
3260 }
3261 else
3262 {
3263 return error(GL_INVALID_VALUE);
3264 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003265 }
3266
3267 programObject->link();
3268 }
3269 }
3270 catch(std::bad_alloc&)
3271 {
3272 return error(GL_OUT_OF_MEMORY);
3273 }
3274}
3275
3276void __stdcall glPixelStorei(GLenum pname, GLint param)
3277{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003278 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003279
3280 try
3281 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003282 gl::Context *context = gl::getContext();
3283
3284 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003285 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003286 switch (pname)
3287 {
3288 case GL_UNPACK_ALIGNMENT:
3289 if (param != 1 && param != 2 && param != 4 && param != 8)
3290 {
3291 return error(GL_INVALID_VALUE);
3292 }
3293
3294 context->unpackAlignment = param;
3295 break;
3296
3297 case GL_PACK_ALIGNMENT:
3298 if (param != 1 && param != 2 && param != 4 && param != 8)
3299 {
3300 return error(GL_INVALID_VALUE);
3301 }
3302
3303 context->packAlignment = param;
3304 break;
3305
3306 default:
3307 return error(GL_INVALID_ENUM);
3308 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003309 }
3310 }
3311 catch(std::bad_alloc&)
3312 {
3313 return error(GL_OUT_OF_MEMORY);
3314 }
3315}
3316
3317void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3318{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003319 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003320
3321 try
3322 {
3323 if (factor != 0.0f || units != 0.0f)
3324 {
3325 UNIMPLEMENTED(); // FIXME
3326 }
3327 }
3328 catch(std::bad_alloc&)
3329 {
3330 return error(GL_OUT_OF_MEMORY);
3331 }
3332}
3333
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003334void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003335{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003336 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003337 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003338 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003339
3340 try
3341 {
3342 if (width < 0 || height < 0)
3343 {
3344 return error(GL_INVALID_VALUE);
3345 }
3346
3347 switch (format)
3348 {
3349 case GL_RGBA:
3350 switch (type)
3351 {
3352 case GL_UNSIGNED_BYTE:
3353 break;
3354 default:
3355 return error(GL_INVALID_OPERATION);
3356 }
3357 break;
3358 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3359 switch (type)
3360 {
3361 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3362 break;
3363 default:
3364 return error(GL_INVALID_OPERATION);
3365 }
3366 break;
3367 default:
3368 return error(GL_INVALID_OPERATION);
3369 }
3370
3371 gl::Context *context = gl::getContext();
3372
3373 if (context)
3374 {
3375 context->readPixels(x, y, width, height, format, type, pixels);
3376 }
3377 }
3378 catch(std::bad_alloc&)
3379 {
3380 return error(GL_OUT_OF_MEMORY);
3381 }
3382}
3383
3384void __stdcall glReleaseShaderCompiler(void)
3385{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003386 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003387
3388 try
3389 {
3390 gl::Shader::releaseCompiler();
3391 }
3392 catch(std::bad_alloc&)
3393 {
3394 return error(GL_OUT_OF_MEMORY);
3395 }
3396}
3397
3398void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3399{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003400 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3401 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003402
3403 try
3404 {
3405 switch (target)
3406 {
3407 case GL_RENDERBUFFER:
3408 break;
3409 default:
3410 return error(GL_INVALID_ENUM);
3411 }
3412
3413 switch (internalformat)
3414 {
3415 case GL_DEPTH_COMPONENT16:
3416 case GL_RGBA4:
3417 case GL_RGB5_A1:
3418 case GL_RGB565:
3419 case GL_STENCIL_INDEX8:
3420 break;
3421 default:
3422 return error(GL_INVALID_ENUM);
3423 }
3424
3425 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3426 {
3427 return error(GL_INVALID_VALUE);
3428 }
3429
3430 gl::Context *context = gl::getContext();
3431
3432 if (context)
3433 {
3434 if (context->framebuffer == 0 || context->renderbuffer == 0)
3435 {
3436 return error(GL_INVALID_OPERATION);
3437 }
3438
3439 switch (internalformat)
3440 {
3441 case GL_DEPTH_COMPONENT16:
3442 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3443 break;
3444 case GL_RGBA4:
3445 case GL_RGB5_A1:
3446 case GL_RGB565:
daniel@transgaming.com70d312a2010-04-20 18:52:38 +00003447 context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003448 break;
3449 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003450 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003451 break;
3452 default:
3453 return error(GL_INVALID_ENUM);
3454 }
3455 }
3456 }
3457 catch(std::bad_alloc&)
3458 {
3459 return error(GL_OUT_OF_MEMORY);
3460 }
3461}
3462
3463void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3464{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003465 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003466
3467 try
3468 {
3469 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003470
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003471 if (context)
3472 {
3473 context->sampleCoverageValue = gl::clamp01(value);
3474 context->sampleCoverageInvert = invert;
3475 }
3476 }
3477 catch(std::bad_alloc&)
3478 {
3479 return error(GL_OUT_OF_MEMORY);
3480 }
3481}
3482
3483void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3484{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003485 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 +00003486
3487 try
3488 {
3489 if (width < 0 || height < 0)
3490 {
3491 return error(GL_INVALID_VALUE);
3492 }
3493
3494 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003495
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003496 if (context)
3497 {
3498 context->scissorX = x;
3499 context->scissorY = y;
3500 context->scissorWidth = width;
3501 context->scissorHeight = height;
3502 }
3503 }
3504 catch(std::bad_alloc&)
3505 {
3506 return error(GL_OUT_OF_MEMORY);
3507 }
3508}
3509
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003510void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003511{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003512 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003513 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003514 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003515
3516 try
3517 {
3518 if (n < 0 || length < 0)
3519 {
3520 return error(GL_INVALID_VALUE);
3521 }
3522
3523 UNIMPLEMENTED(); // FIXME
3524 }
3525 catch(std::bad_alloc&)
3526 {
3527 return error(GL_OUT_OF_MEMORY);
3528 }
3529}
3530
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003531void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003532{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003533 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 +00003534 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003535
3536 try
3537 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003538 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003539 {
3540 return error(GL_INVALID_VALUE);
3541 }
3542
3543 gl::Context *context = gl::getContext();
3544
3545 if (context)
3546 {
3547 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003548
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003549 if (!shaderObject)
3550 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003551 if (context->getProgram(shader))
3552 {
3553 return error(GL_INVALID_OPERATION);
3554 }
3555 else
3556 {
3557 return error(GL_INVALID_VALUE);
3558 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003559 }
3560
3561 shaderObject->setSource(count, string, length);
3562 }
3563 }
3564 catch(std::bad_alloc&)
3565 {
3566 return error(GL_OUT_OF_MEMORY);
3567 }
3568}
3569
3570void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3571{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003572 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003573}
3574
3575void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3576{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003577 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 +00003578
3579 try
3580 {
3581 switch (face)
3582 {
3583 case GL_FRONT:
3584 case GL_BACK:
3585 case GL_FRONT_AND_BACK:
3586 break;
3587 default:
3588 return error(GL_INVALID_ENUM);
3589 }
3590
3591 switch (func)
3592 {
3593 case GL_NEVER:
3594 case GL_ALWAYS:
3595 case GL_LESS:
3596 case GL_LEQUAL:
3597 case GL_EQUAL:
3598 case GL_GEQUAL:
3599 case GL_GREATER:
3600 case GL_NOTEQUAL:
3601 break;
3602 default:
3603 return error(GL_INVALID_ENUM);
3604 }
3605
3606 gl::Context *context = gl::getContext();
3607
3608 if (context)
3609 {
3610 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3611 {
3612 context->stencilFunc = func;
3613 context->stencilRef = ref;
3614 context->stencilMask = mask;
3615 }
3616
3617 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3618 {
3619 context->stencilBackFunc = func;
3620 context->stencilBackRef = ref;
3621 context->stencilBackMask = mask;
3622 }
3623 }
3624 }
3625 catch(std::bad_alloc&)
3626 {
3627 return error(GL_OUT_OF_MEMORY);
3628 }
3629}
3630
3631void __stdcall glStencilMask(GLuint mask)
3632{
3633 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3634}
3635
3636void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3637{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003638 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003639
3640 try
3641 {
3642 switch (face)
3643 {
3644 case GL_FRONT:
3645 case GL_BACK:
3646 case GL_FRONT_AND_BACK:
3647 break;
3648 default:
3649 return error(GL_INVALID_ENUM);
3650 }
3651
3652 gl::Context *context = gl::getContext();
3653
3654 if (context)
3655 {
3656 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3657 {
3658 context->stencilWritemask = mask;
3659 }
3660
3661 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3662 {
3663 context->stencilBackWritemask = mask;
3664 }
3665 }
3666 }
3667 catch(std::bad_alloc&)
3668 {
3669 return error(GL_OUT_OF_MEMORY);
3670 }
3671}
3672
3673void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3674{
3675 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3676}
3677
3678void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3679{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003680 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3681 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003682
3683 try
3684 {
3685 switch (face)
3686 {
3687 case GL_FRONT:
3688 case GL_BACK:
3689 case GL_FRONT_AND_BACK:
3690 break;
3691 default:
3692 return error(GL_INVALID_ENUM);
3693 }
3694
3695 switch (fail)
3696 {
3697 case GL_ZERO:
3698 case GL_KEEP:
3699 case GL_REPLACE:
3700 case GL_INCR:
3701 case GL_DECR:
3702 case GL_INVERT:
3703 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003704 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003705 break;
3706 default:
3707 return error(GL_INVALID_ENUM);
3708 }
3709
3710 switch (zfail)
3711 {
3712 case GL_ZERO:
3713 case GL_KEEP:
3714 case GL_REPLACE:
3715 case GL_INCR:
3716 case GL_DECR:
3717 case GL_INVERT:
3718 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003719 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003720 break;
3721 default:
3722 return error(GL_INVALID_ENUM);
3723 }
3724
3725 switch (zpass)
3726 {
3727 case GL_ZERO:
3728 case GL_KEEP:
3729 case GL_REPLACE:
3730 case GL_INCR:
3731 case GL_DECR:
3732 case GL_INVERT:
3733 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003734 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003735 break;
3736 default:
3737 return error(GL_INVALID_ENUM);
3738 }
3739
3740 gl::Context *context = gl::getContext();
3741
3742 if (context)
3743 {
3744 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3745 {
3746 context->stencilFail = fail;
3747 context->stencilPassDepthFail = zfail;
3748 context->stencilPassDepthPass = zpass;
3749 }
3750
3751 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3752 {
3753 context->stencilBackFail = fail;
3754 context->stencilBackPassDepthFail = zfail;
3755 context->stencilBackPassDepthPass = zpass;
3756 }
3757 }
3758 }
3759 catch(std::bad_alloc&)
3760 {
3761 return error(GL_OUT_OF_MEMORY);
3762 }
3763}
3764
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003765void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3766 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003767{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003768 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 +00003769 "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 +00003770 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003771
3772 try
3773 {
3774 if (level < 0 || width < 0 || height < 0)
3775 {
3776 return error(GL_INVALID_VALUE);
3777 }
3778
3779 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3780 {
3781 return error(GL_INVALID_VALUE);
3782 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003783
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003784 switch (target)
3785 {
3786 case GL_TEXTURE_2D:
3787 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3788 {
3789 return error(GL_INVALID_VALUE);
3790 }
3791 break;
3792 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3793 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3794 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3795 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3796 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3797 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003798 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003799 {
3800 return error(GL_INVALID_VALUE);
3801 }
3802
3803 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3804 {
3805 return error(GL_INVALID_VALUE);
3806 }
3807 break;
3808 default:
3809 return error(GL_INVALID_ENUM);
3810 }
3811
3812 if (internalformat != format)
3813 {
3814 return error(GL_INVALID_OPERATION);
3815 }
3816
3817 switch (internalformat)
3818 {
3819 case GL_ALPHA:
3820 case GL_LUMINANCE:
3821 case GL_LUMINANCE_ALPHA:
3822 switch (type)
3823 {
3824 case GL_UNSIGNED_BYTE:
3825 break;
3826 default:
3827 return error(GL_INVALID_ENUM);
3828 }
3829 break;
3830 case GL_RGB:
3831 switch (type)
3832 {
3833 case GL_UNSIGNED_BYTE:
3834 case GL_UNSIGNED_SHORT_5_6_5:
3835 break;
3836 default:
3837 return error(GL_INVALID_ENUM);
3838 }
3839 break;
3840 case GL_RGBA:
3841 switch (type)
3842 {
3843 case GL_UNSIGNED_BYTE:
3844 case GL_UNSIGNED_SHORT_4_4_4_4:
3845 case GL_UNSIGNED_SHORT_5_5_5_1:
3846 break;
3847 default:
3848 return error(GL_INVALID_ENUM);
3849 }
3850 break;
3851 default:
3852 return error(GL_INVALID_VALUE);
3853 }
3854
3855 if (border != 0)
3856 {
3857 return error(GL_INVALID_VALUE);
3858 }
3859
3860 gl::Context *context = gl::getContext();
3861
3862 if (context)
3863 {
3864 if (target == GL_TEXTURE_2D)
3865 {
3866 gl::Texture2D *texture = context->getTexture2D();
3867
3868 if (!texture)
3869 {
3870 return error(GL_INVALID_OPERATION);
3871 }
3872
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003873 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003874 }
3875 else
3876 {
3877 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3878
3879 if (!texture)
3880 {
3881 return error(GL_INVALID_OPERATION);
3882 }
3883
3884 switch (target)
3885 {
3886 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003887 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003888 break;
3889 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003890 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003891 break;
3892 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003893 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003894 break;
3895 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003896 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003897 break;
3898 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003899 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003900 break;
3901 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003902 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003903 break;
3904 default: UNREACHABLE();
3905 }
3906 }
3907 }
3908 }
3909 catch(std::bad_alloc&)
3910 {
3911 return error(GL_OUT_OF_MEMORY);
3912 }
3913}
3914
3915void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3916{
3917 glTexParameteri(target, pname, (GLint)param);
3918}
3919
3920void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3921{
3922 glTexParameteri(target, pname, (GLint)*params);
3923}
3924
3925void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3926{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003927 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003928
3929 try
3930 {
3931 gl::Context *context = gl::getContext();
3932
3933 if (context)
3934 {
3935 gl::Texture *texture;
3936
3937 switch (target)
3938 {
3939 case GL_TEXTURE_2D:
3940 texture = context->getTexture2D();
3941 break;
3942 case GL_TEXTURE_CUBE_MAP:
3943 texture = context->getTextureCubeMap();
3944 break;
3945 default:
3946 return error(GL_INVALID_ENUM);
3947 }
3948
3949 switch (pname)
3950 {
3951 case GL_TEXTURE_WRAP_S:
3952 if (!texture->setWrapS((GLenum)param))
3953 {
3954 return error(GL_INVALID_ENUM);
3955 }
3956 break;
3957 case GL_TEXTURE_WRAP_T:
3958 if (!texture->setWrapT((GLenum)param))
3959 {
3960 return error(GL_INVALID_ENUM);
3961 }
3962 break;
3963 case GL_TEXTURE_MIN_FILTER:
3964 if (!texture->setMinFilter((GLenum)param))
3965 {
3966 return error(GL_INVALID_ENUM);
3967 }
3968 break;
3969 case GL_TEXTURE_MAG_FILTER:
3970 if (!texture->setMagFilter((GLenum)param))
3971 {
3972 return error(GL_INVALID_ENUM);
3973 }
3974 break;
3975 default:
3976 return error(GL_INVALID_ENUM);
3977 }
3978 }
3979 }
3980 catch(std::bad_alloc&)
3981 {
3982 return error(GL_OUT_OF_MEMORY);
3983 }
3984}
3985
3986void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3987{
3988 glTexParameteri(target, pname, *params);
3989}
3990
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003991void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3992 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003993{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003994 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3995 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003996 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003997 target, level, xoffset, yoffset, width, height, format, type, pixels);
3998
3999 try
4000 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004001 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
4002 {
4003 return error(GL_INVALID_ENUM);
4004 }
4005
4006 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004007 {
4008 return error(GL_INVALID_VALUE);
4009 }
4010
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004011 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4012 {
4013 return error(GL_INVALID_VALUE);
4014 }
4015
4016 if (!es2dx::CheckTextureFormatType(format, type))
4017 {
4018 return error(GL_INVALID_ENUM);
4019 }
4020
4021 if (width == 0 || height == 0 || pixels == NULL)
4022 {
4023 return;
4024 }
4025
4026 gl::Context *context = gl::getContext();
4027
4028 if (context)
4029 {
4030 if (target == GL_TEXTURE_2D)
4031 {
4032 gl::Texture2D *texture = context->getTexture2D();
4033
4034 if (!texture)
4035 {
4036 return error(GL_INVALID_OPERATION);
4037 }
4038
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004039 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004040 }
4041 else if (es2dx::IsCubemapTextureTarget(target))
4042 {
4043 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4044
4045 if (!texture)
4046 {
4047 return error(GL_INVALID_OPERATION);
4048 }
4049
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00004050 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004051 }
4052 else
4053 {
4054 UNREACHABLE();
4055 }
4056 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004057 }
4058 catch(std::bad_alloc&)
4059 {
4060 return error(GL_OUT_OF_MEMORY);
4061 }
4062}
4063
4064void __stdcall glUniform1f(GLint location, GLfloat x)
4065{
4066 glUniform1fv(location, 1, &x);
4067}
4068
4069void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4070{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004071 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004072
4073 try
4074 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004075 if (count < 0)
4076 {
4077 return error(GL_INVALID_VALUE);
4078 }
4079
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004080 if (location == -1)
4081 {
4082 return;
4083 }
4084
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004085 gl::Context *context = gl::getContext();
4086
4087 if (context)
4088 {
4089 gl::Program *program = context->getCurrentProgram();
4090
4091 if (!program)
4092 {
4093 return error(GL_INVALID_OPERATION);
4094 }
4095
4096 if (!program->setUniform1fv(location, count, v))
4097 {
4098 return error(GL_INVALID_OPERATION);
4099 }
4100 }
4101 }
4102 catch(std::bad_alloc&)
4103 {
4104 return error(GL_OUT_OF_MEMORY);
4105 }
4106}
4107
4108void __stdcall glUniform1i(GLint location, GLint x)
4109{
4110 glUniform1iv(location, 1, &x);
4111}
4112
4113void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4114{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004115 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004116
4117 try
4118 {
4119 if (count < 0)
4120 {
4121 return error(GL_INVALID_VALUE);
4122 }
4123
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004124 if (location == -1)
4125 {
4126 return;
4127 }
4128
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004129 gl::Context *context = gl::getContext();
4130
4131 if (context)
4132 {
4133 gl::Program *program = context->getCurrentProgram();
4134
4135 if (!program)
4136 {
4137 return error(GL_INVALID_OPERATION);
4138 }
4139
4140 if (!program->setUniform1iv(location, count, v))
4141 {
4142 return error(GL_INVALID_OPERATION);
4143 }
4144 }
4145 }
4146 catch(std::bad_alloc&)
4147 {
4148 return error(GL_OUT_OF_MEMORY);
4149 }
4150}
4151
4152void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4153{
4154 GLfloat xy[2] = {x, y};
4155
4156 glUniform2fv(location, 1, (GLfloat*)&xy);
4157}
4158
4159void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4160{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004161 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004162
4163 try
4164 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004165 if (count < 0)
4166 {
4167 return error(GL_INVALID_VALUE);
4168 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004169
4170 if (location == -1)
4171 {
4172 return;
4173 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004174
4175 gl::Context *context = gl::getContext();
4176
4177 if (context)
4178 {
4179 gl::Program *program = context->getCurrentProgram();
4180
4181 if (!program)
4182 {
4183 return error(GL_INVALID_OPERATION);
4184 }
4185
4186 if (!program->setUniform2fv(location, count, v))
4187 {
4188 return error(GL_INVALID_OPERATION);
4189 }
4190 }
4191 }
4192 catch(std::bad_alloc&)
4193 {
4194 return error(GL_OUT_OF_MEMORY);
4195 }
4196}
4197
4198void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4199{
4200 GLint xy[4] = {x, y};
4201
4202 glUniform2iv(location, 1, (GLint*)&xy);
4203}
4204
4205void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4206{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004207 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004208
4209 try
4210 {
4211 if (count < 0)
4212 {
4213 return error(GL_INVALID_VALUE);
4214 }
4215
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004216 if (location == -1)
4217 {
4218 return;
4219 }
4220
4221 gl::Context *context = gl::getContext();
4222
4223 if (context)
4224 {
4225 gl::Program *program = context->getCurrentProgram();
4226
4227 if (!program)
4228 {
4229 return error(GL_INVALID_OPERATION);
4230 }
4231
4232 if (!program->setUniform2iv(location, count, v))
4233 {
4234 return error(GL_INVALID_OPERATION);
4235 }
4236 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004237 }
4238 catch(std::bad_alloc&)
4239 {
4240 return error(GL_OUT_OF_MEMORY);
4241 }
4242}
4243
4244void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4245{
4246 GLfloat xyz[3] = {x, y, z};
4247
4248 glUniform3fv(location, 1, (GLfloat*)&xyz);
4249}
4250
4251void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4252{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004253 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004254
4255 try
4256 {
4257 if (count < 0)
4258 {
4259 return error(GL_INVALID_VALUE);
4260 }
4261
4262 if (location == -1)
4263 {
4264 return;
4265 }
4266
4267 gl::Context *context = gl::getContext();
4268
4269 if (context)
4270 {
4271 gl::Program *program = context->getCurrentProgram();
4272
4273 if (!program)
4274 {
4275 return error(GL_INVALID_OPERATION);
4276 }
4277
4278 if (!program->setUniform3fv(location, count, v))
4279 {
4280 return error(GL_INVALID_OPERATION);
4281 }
4282 }
4283 }
4284 catch(std::bad_alloc&)
4285 {
4286 return error(GL_OUT_OF_MEMORY);
4287 }
4288}
4289
4290void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4291{
4292 GLint xyz[3] = {x, y, z};
4293
4294 glUniform3iv(location, 1, (GLint*)&xyz);
4295}
4296
4297void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4298{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004299 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004300
4301 try
4302 {
4303 if (count < 0)
4304 {
4305 return error(GL_INVALID_VALUE);
4306 }
4307
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004308 if (location == -1)
4309 {
4310 return;
4311 }
4312
4313 gl::Context *context = gl::getContext();
4314
4315 if (context)
4316 {
4317 gl::Program *program = context->getCurrentProgram();
4318
4319 if (!program)
4320 {
4321 return error(GL_INVALID_OPERATION);
4322 }
4323
4324 if (!program->setUniform3iv(location, count, v))
4325 {
4326 return error(GL_INVALID_OPERATION);
4327 }
4328 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004329 }
4330 catch(std::bad_alloc&)
4331 {
4332 return error(GL_OUT_OF_MEMORY);
4333 }
4334}
4335
4336void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4337{
4338 GLfloat xyzw[4] = {x, y, z, w};
4339
4340 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4341}
4342
4343void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4344{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004345 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004346
4347 try
4348 {
4349 if (count < 0)
4350 {
4351 return error(GL_INVALID_VALUE);
4352 }
4353
4354 if (location == -1)
4355 {
4356 return;
4357 }
4358
4359 gl::Context *context = gl::getContext();
4360
4361 if (context)
4362 {
4363 gl::Program *program = context->getCurrentProgram();
4364
4365 if (!program)
4366 {
4367 return error(GL_INVALID_OPERATION);
4368 }
4369
4370 if (!program->setUniform4fv(location, count, v))
4371 {
4372 return error(GL_INVALID_OPERATION);
4373 }
4374 }
4375 }
4376 catch(std::bad_alloc&)
4377 {
4378 return error(GL_OUT_OF_MEMORY);
4379 }
4380}
4381
4382void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4383{
4384 GLint xyzw[4] = {x, y, z, w};
4385
4386 glUniform4iv(location, 1, (GLint*)&xyzw);
4387}
4388
4389void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4390{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004391 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004392
4393 try
4394 {
4395 if (count < 0)
4396 {
4397 return error(GL_INVALID_VALUE);
4398 }
4399
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004400 if (location == -1)
4401 {
4402 return;
4403 }
4404
4405 gl::Context *context = gl::getContext();
4406
4407 if (context)
4408 {
4409 gl::Program *program = context->getCurrentProgram();
4410
4411 if (!program)
4412 {
4413 return error(GL_INVALID_OPERATION);
4414 }
4415
4416 if (!program->setUniform4iv(location, count, v))
4417 {
4418 return error(GL_INVALID_OPERATION);
4419 }
4420 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004421 }
4422 catch(std::bad_alloc&)
4423 {
4424 return error(GL_OUT_OF_MEMORY);
4425 }
4426}
4427
4428void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4429{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004430 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4431 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004432
4433 try
4434 {
4435 if (count < 0 || transpose != GL_FALSE)
4436 {
4437 return error(GL_INVALID_VALUE);
4438 }
4439
4440 if (location == -1)
4441 {
4442 return;
4443 }
4444
4445 gl::Context *context = gl::getContext();
4446
4447 if (context)
4448 {
4449 gl::Program *program = context->getCurrentProgram();
4450
4451 if (!program)
4452 {
4453 return error(GL_INVALID_OPERATION);
4454 }
4455
4456 if (!program->setUniformMatrix2fv(location, count, value))
4457 {
4458 return error(GL_INVALID_OPERATION);
4459 }
4460 }
4461 }
4462 catch(std::bad_alloc&)
4463 {
4464 return error(GL_OUT_OF_MEMORY);
4465 }
4466}
4467
4468void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4469{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004470 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4471 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004472
4473 try
4474 {
4475 if (count < 0 || transpose != GL_FALSE)
4476 {
4477 return error(GL_INVALID_VALUE);
4478 }
4479
4480 if (location == -1)
4481 {
4482 return;
4483 }
4484
4485 gl::Context *context = gl::getContext();
4486
4487 if (context)
4488 {
4489 gl::Program *program = context->getCurrentProgram();
4490
4491 if (!program)
4492 {
4493 return error(GL_INVALID_OPERATION);
4494 }
4495
4496 if (!program->setUniformMatrix3fv(location, count, value))
4497 {
4498 return error(GL_INVALID_OPERATION);
4499 }
4500 }
4501 }
4502 catch(std::bad_alloc&)
4503 {
4504 return error(GL_OUT_OF_MEMORY);
4505 }
4506}
4507
4508void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4509{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004510 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4511 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004512
4513 try
4514 {
4515 if (count < 0 || transpose != GL_FALSE)
4516 {
4517 return error(GL_INVALID_VALUE);
4518 }
4519
4520 if (location == -1)
4521 {
4522 return;
4523 }
4524
4525 gl::Context *context = gl::getContext();
4526
4527 if (context)
4528 {
4529 gl::Program *program = context->getCurrentProgram();
4530
4531 if (!program)
4532 {
4533 return error(GL_INVALID_OPERATION);
4534 }
4535
4536 if (!program->setUniformMatrix4fv(location, count, value))
4537 {
4538 return error(GL_INVALID_OPERATION);
4539 }
4540 }
4541 }
4542 catch(std::bad_alloc&)
4543 {
4544 return error(GL_OUT_OF_MEMORY);
4545 }
4546}
4547
4548void __stdcall glUseProgram(GLuint program)
4549{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004550 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004551
4552 try
4553 {
4554 gl::Context *context = gl::getContext();
4555
4556 if (context)
4557 {
4558 gl::Program *programObject = context->getProgram(program);
4559
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004560 if (!programObject && program != 0)
4561 {
4562 if (context->getShader(program))
4563 {
4564 return error(GL_INVALID_OPERATION);
4565 }
4566 else
4567 {
4568 return error(GL_INVALID_VALUE);
4569 }
4570 }
4571
4572 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004573 {
4574 return error(GL_INVALID_OPERATION);
4575 }
4576
4577 context->useProgram(program);
4578 }
4579 }
4580 catch(std::bad_alloc&)
4581 {
4582 return error(GL_OUT_OF_MEMORY);
4583 }
4584}
4585
4586void __stdcall glValidateProgram(GLuint program)
4587{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004588 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004589
4590 try
4591 {
4592 UNIMPLEMENTED(); // FIXME
4593 }
4594 catch(std::bad_alloc&)
4595 {
4596 return error(GL_OUT_OF_MEMORY);
4597 }
4598}
4599
4600void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4601{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004602 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004603
4604 try
4605 {
4606 if (index >= gl::MAX_VERTEX_ATTRIBS)
4607 {
4608 return error(GL_INVALID_VALUE);
4609 }
4610
4611 UNIMPLEMENTED(); // FIXME
4612 }
4613 catch(std::bad_alloc&)
4614 {
4615 return error(GL_OUT_OF_MEMORY);
4616 }
4617}
4618
4619void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4620{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004621 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004622
4623 try
4624 {
4625 if (index >= gl::MAX_VERTEX_ATTRIBS)
4626 {
4627 return error(GL_INVALID_VALUE);
4628 }
4629
4630 UNIMPLEMENTED(); // FIXME
4631 }
4632 catch(std::bad_alloc&)
4633 {
4634 return error(GL_OUT_OF_MEMORY);
4635 }
4636}
4637
4638void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4639{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004640 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004641
4642 try
4643 {
4644 if (index >= gl::MAX_VERTEX_ATTRIBS)
4645 {
4646 return error(GL_INVALID_VALUE);
4647 }
4648
4649 UNIMPLEMENTED(); // FIXME
4650 }
4651 catch(std::bad_alloc&)
4652 {
4653 return error(GL_OUT_OF_MEMORY);
4654 }
4655}
4656
4657void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4658{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004659 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004660
4661 try
4662 {
4663 if (index >= gl::MAX_VERTEX_ATTRIBS)
4664 {
4665 return error(GL_INVALID_VALUE);
4666 }
4667
4668 UNIMPLEMENTED(); // FIXME
4669 }
4670 catch(std::bad_alloc&)
4671 {
4672 return error(GL_OUT_OF_MEMORY);
4673 }
4674}
4675
4676void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4677{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004678 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 +00004679
4680 try
4681 {
4682 if (index >= gl::MAX_VERTEX_ATTRIBS)
4683 {
4684 return error(GL_INVALID_VALUE);
4685 }
4686
4687 UNIMPLEMENTED(); // FIXME
4688 }
4689 catch(std::bad_alloc&)
4690 {
4691 return error(GL_OUT_OF_MEMORY);
4692 }
4693}
4694
4695void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4696{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004697 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004698
4699 try
4700 {
4701 if (index >= gl::MAX_VERTEX_ATTRIBS)
4702 {
4703 return error(GL_INVALID_VALUE);
4704 }
4705
4706 UNIMPLEMENTED(); // FIXME
4707 }
4708 catch(std::bad_alloc&)
4709 {
4710 return error(GL_OUT_OF_MEMORY);
4711 }
4712}
4713
4714void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4715{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004716 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 +00004717
4718 try
4719 {
4720 if (index >= gl::MAX_VERTEX_ATTRIBS)
4721 {
4722 return error(GL_INVALID_VALUE);
4723 }
4724
4725 UNIMPLEMENTED(); // FIXME
4726 }
4727 catch(std::bad_alloc&)
4728 {
4729 return error(GL_OUT_OF_MEMORY);
4730 }
4731}
4732
4733void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4734{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004735 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004736
4737 try
4738 {
4739 if (index >= gl::MAX_VERTEX_ATTRIBS)
4740 {
4741 return error(GL_INVALID_VALUE);
4742 }
4743
4744 UNIMPLEMENTED(); // FIXME
4745 }
4746 catch(std::bad_alloc&)
4747 {
4748 return error(GL_OUT_OF_MEMORY);
4749 }
4750}
4751
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004752void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004753{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004754 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004755 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004756 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004757
4758 try
4759 {
4760 if (index >= gl::MAX_VERTEX_ATTRIBS)
4761 {
4762 return error(GL_INVALID_VALUE);
4763 }
4764
4765 if (size < 1 || size > 4)
4766 {
4767 return error(GL_INVALID_VALUE);
4768 }
4769
4770 switch (type)
4771 {
4772 case GL_BYTE:
4773 case GL_UNSIGNED_BYTE:
4774 case GL_SHORT:
4775 case GL_UNSIGNED_SHORT:
4776 case GL_FIXED:
4777 case GL_FLOAT:
4778 break;
4779 default:
4780 return error(GL_INVALID_ENUM);
4781 }
4782
4783 if (stride < 0)
4784 {
4785 return error(GL_INVALID_VALUE);
4786 }
4787
4788 gl::Context *context = gl::getContext();
4789
4790 if (context)
4791 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004792 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4793 context->vertexAttribute[index].mSize = size;
4794 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004795 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004796 context->vertexAttribute[index].mStride = stride;
4797 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004798 }
4799 }
4800 catch(std::bad_alloc&)
4801 {
4802 return error(GL_OUT_OF_MEMORY);
4803 }
4804}
4805
4806void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4807{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004808 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 +00004809
4810 try
4811 {
4812 if (width < 0 || height < 0)
4813 {
4814 return error(GL_INVALID_VALUE);
4815 }
4816
4817 gl::Context *context = gl::getContext();
4818
4819 if (context)
4820 {
4821 context->viewportX = x;
4822 context->viewportY = y;
4823 context->viewportWidth = width;
4824 context->viewportHeight = height;
4825 }
4826 }
4827 catch(std::bad_alloc&)
4828 {
4829 return error(GL_OUT_OF_MEMORY);
4830 }
4831}
4832
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004833void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4834 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004835{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004836 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4837 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004838 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004839 target, level, internalformat, width, height, depth, border, format, type, pixels);
4840
4841 try
4842 {
4843 UNIMPLEMENTED(); // FIXME
4844 }
4845 catch(std::bad_alloc&)
4846 {
4847 return error(GL_OUT_OF_MEMORY);
4848 }
4849}
4850}