blob: 104ae6bad61c547108a85ecc93a44454285210bd [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016#include "Context.h"
17#include "main.h"
18#include "Program.h"
19#include "Shader.h"
20#include "Buffer.h"
21#include "Texture.h"
22#include "Renderbuffer.h"
23#include "Framebuffer.h"
24#include "mathutil.h"
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000025#include "common/debug.h"
daniel@transgaming.com00c75962010-03-11 20:36:15 +000026#include "utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027
28extern "C"
29{
30
31void __stdcall glActiveTexture(GLenum texture)
32{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000033 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034
35 try
36 {
37 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
38 {
39 return error(GL_INVALID_ENUM);
40 }
41
42 gl::Context *context = gl::getContext();
43
44 if (context)
45 {
46 context->activeSampler = texture - GL_TEXTURE0;
47 }
48 }
49 catch(std::bad_alloc&)
50 {
51 return error(GL_OUT_OF_MEMORY);
52 }
53}
54
55void __stdcall glAttachShader(GLuint program, GLuint shader)
56{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000057 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000058
59 try
60 {
61 gl::Context *context = gl::getContext();
62
63 if (context)
64 {
65 gl::Program *programObject = context->getProgram(program);
66 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000067
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000068 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000069 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000070 if (context->getShader(program))
71 {
72 return error(GL_INVALID_OPERATION);
73 }
74 else
75 {
76 return error(GL_INVALID_VALUE);
77 }
78 }
79
80 if (!shaderObject)
81 {
82 if (context->getProgram(shader))
83 {
84 return error(GL_INVALID_OPERATION);
85 }
86 else
87 {
88 return error(GL_INVALID_VALUE);
89 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090 }
91
92 if (!programObject->attachShader(shaderObject))
93 {
94 return error(GL_INVALID_OPERATION);
95 }
96 }
97 }
98 catch(std::bad_alloc&)
99 {
100 return error(GL_OUT_OF_MEMORY);
101 }
102}
103
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000104void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000105{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000106 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107
108 try
109 {
110 if (index >= gl::MAX_VERTEX_ATTRIBS)
111 {
112 return error(GL_INVALID_VALUE);
113 }
114
115 gl::Context *context = gl::getContext();
116
117 if (context)
118 {
119 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000120
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000121 if (!programObject)
122 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000123 if (context->getShader(program))
124 {
125 return error(GL_INVALID_OPERATION);
126 }
127 else
128 {
129 return error(GL_INVALID_VALUE);
130 }
131 }
132
133 if (strncmp(name, "gl_", 3) == 0)
134 {
135 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000136 }
137
138 programObject->bindAttributeLocation(index, name);
139 }
140 }
141 catch(std::bad_alloc&)
142 {
143 return error(GL_OUT_OF_MEMORY);
144 }
145}
146
147void __stdcall glBindBuffer(GLenum target, GLuint buffer)
148{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000149 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150
151 try
152 {
153 gl::Context *context = gl::getContext();
154
155 if (context)
156 {
157 switch (target)
158 {
159 case GL_ARRAY_BUFFER:
160 context->bindArrayBuffer(buffer);
161 return;
162 case GL_ELEMENT_ARRAY_BUFFER:
163 context->bindElementArrayBuffer(buffer);
164 return;
165 default:
166 return error(GL_INVALID_ENUM);
167 }
168 }
169 }
170 catch(std::bad_alloc&)
171 {
172 return error(GL_OUT_OF_MEMORY);
173 }
174}
175
176void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
177{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000178 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000179
180 try
181 {
182 if (target != GL_FRAMEBUFFER)
183 {
184 return error(GL_INVALID_ENUM);
185 }
186
187 gl::Context *context = gl::getContext();
188
189 if (context)
190 {
191 context->bindFramebuffer(framebuffer);
192 }
193 }
194 catch(std::bad_alloc&)
195 {
196 return error(GL_OUT_OF_MEMORY);
197 }
198}
199
200void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
201{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000202 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203
204 try
205 {
206 if (target != GL_RENDERBUFFER)
207 {
208 return error(GL_INVALID_ENUM);
209 }
210
211 gl::Context *context = gl::getContext();
212
213 if (context)
214 {
215 context->bindRenderbuffer(renderbuffer);
216 }
217 }
218 catch(std::bad_alloc&)
219 {
220 return error(GL_OUT_OF_MEMORY);
221 }
222}
223
224void __stdcall glBindTexture(GLenum target, GLuint texture)
225{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000226 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227
228 try
229 {
230 gl::Context *context = gl::getContext();
231
232 if (context)
233 {
234 gl::Texture *textureObject = context->getTexture(texture);
235
236 if (textureObject && textureObject->getTarget() != target && texture != 0)
237 {
238 return error(GL_INVALID_OPERATION);
239 }
240
241 switch (target)
242 {
243 case GL_TEXTURE_2D:
244 context->bindTexture2D(texture);
245 return;
246 case GL_TEXTURE_CUBE_MAP:
247 context->bindTextureCubeMap(texture);
248 return;
249 default:
250 return error(GL_INVALID_ENUM);
251 }
252 }
253 }
254 catch(std::bad_alloc&)
255 {
256 return error(GL_OUT_OF_MEMORY);
257 }
258}
259
260void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
261{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000262 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
263 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264
265 try
266 {
267 gl::Context* context = gl::getContext();
268
269 if (context)
270 {
271 context->blendColor.red = gl::clamp01(red);
272 context->blendColor.blue = gl::clamp01(blue);
273 context->blendColor.green = gl::clamp01(green);
274 context->blendColor.alpha = gl::clamp01(alpha);
275 }
276 }
277 catch(std::bad_alloc&)
278 {
279 return error(GL_OUT_OF_MEMORY);
280 }
281}
282
283void __stdcall glBlendEquation(GLenum mode)
284{
285 glBlendEquationSeparate(mode, mode);
286}
287
288void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
289{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000290 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000291
292 try
293 {
294 switch (modeRGB)
295 {
296 case GL_FUNC_ADD:
297 case GL_FUNC_SUBTRACT:
298 case GL_FUNC_REVERSE_SUBTRACT:
299 break;
300 default:
301 return error(GL_INVALID_ENUM);
302 }
303
304 switch (modeAlpha)
305 {
306 case GL_FUNC_ADD:
307 case GL_FUNC_SUBTRACT:
308 case GL_FUNC_REVERSE_SUBTRACT:
309 break;
310 default:
311 return error(GL_INVALID_ENUM);
312 }
313
314 gl::Context *context = gl::getContext();
315
316 if (context)
317 {
318 context->blendEquationRGB = modeRGB;
319 context->blendEquationAlpha = modeAlpha;
320 }
321 }
322 catch(std::bad_alloc&)
323 {
324 return error(GL_OUT_OF_MEMORY);
325 }
326}
327
328void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
329{
330 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
331}
332
333void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
334{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000335 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
336 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000337
338 try
339 {
340 switch (srcRGB)
341 {
342 case GL_ZERO:
343 case GL_ONE:
344 case GL_SRC_COLOR:
345 case GL_ONE_MINUS_SRC_COLOR:
346 case GL_DST_COLOR:
347 case GL_ONE_MINUS_DST_COLOR:
348 case GL_SRC_ALPHA:
349 case GL_ONE_MINUS_SRC_ALPHA:
350 case GL_DST_ALPHA:
351 case GL_ONE_MINUS_DST_ALPHA:
352 case GL_CONSTANT_COLOR:
353 case GL_ONE_MINUS_CONSTANT_COLOR:
354 case GL_CONSTANT_ALPHA:
355 case GL_ONE_MINUS_CONSTANT_ALPHA:
356 case GL_SRC_ALPHA_SATURATE:
357 break;
358 default:
359 return error(GL_INVALID_ENUM);
360 }
361
362 switch (dstRGB)
363 {
364 case GL_ZERO:
365 case GL_ONE:
366 case GL_SRC_COLOR:
367 case GL_ONE_MINUS_SRC_COLOR:
368 case GL_DST_COLOR:
369 case GL_ONE_MINUS_DST_COLOR:
370 case GL_SRC_ALPHA:
371 case GL_ONE_MINUS_SRC_ALPHA:
372 case GL_DST_ALPHA:
373 case GL_ONE_MINUS_DST_ALPHA:
374 case GL_CONSTANT_COLOR:
375 case GL_ONE_MINUS_CONSTANT_COLOR:
376 case GL_CONSTANT_ALPHA:
377 case GL_ONE_MINUS_CONSTANT_ALPHA:
378 break;
379 default:
380 return error(GL_INVALID_ENUM);
381 }
382
383 switch (srcAlpha)
384 {
385 case GL_ZERO:
386 case GL_ONE:
387 case GL_SRC_COLOR:
388 case GL_ONE_MINUS_SRC_COLOR:
389 case GL_DST_COLOR:
390 case GL_ONE_MINUS_DST_COLOR:
391 case GL_SRC_ALPHA:
392 case GL_ONE_MINUS_SRC_ALPHA:
393 case GL_DST_ALPHA:
394 case GL_ONE_MINUS_DST_ALPHA:
395 case GL_CONSTANT_COLOR:
396 case GL_ONE_MINUS_CONSTANT_COLOR:
397 case GL_CONSTANT_ALPHA:
398 case GL_ONE_MINUS_CONSTANT_ALPHA:
399 case GL_SRC_ALPHA_SATURATE:
400 break;
401 default:
402 return error(GL_INVALID_ENUM);
403 }
404
405 switch (dstAlpha)
406 {
407 case GL_ZERO:
408 case GL_ONE:
409 case GL_SRC_COLOR:
410 case GL_ONE_MINUS_SRC_COLOR:
411 case GL_DST_COLOR:
412 case GL_ONE_MINUS_DST_COLOR:
413 case GL_SRC_ALPHA:
414 case GL_ONE_MINUS_SRC_ALPHA:
415 case GL_DST_ALPHA:
416 case GL_ONE_MINUS_DST_ALPHA:
417 case GL_CONSTANT_COLOR:
418 case GL_ONE_MINUS_CONSTANT_COLOR:
419 case GL_CONSTANT_ALPHA:
420 case GL_ONE_MINUS_CONSTANT_ALPHA:
421 break;
422 default:
423 return error(GL_INVALID_ENUM);
424 }
425
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000426 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
427 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
428
429 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
430 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
431
432 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000433 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000434 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
435 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000436 }
437
438 gl::Context *context = gl::getContext();
439
440 if (context)
441 {
442 context->sourceBlendRGB = srcRGB;
443 context->sourceBlendAlpha = srcAlpha;
444 context->destBlendRGB = dstRGB;
445 context->destBlendAlpha = dstAlpha;
446 }
447 }
448 catch(std::bad_alloc&)
449 {
450 return error(GL_OUT_OF_MEMORY);
451 }
452}
453
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000454void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000455{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000456 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000457 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000458
459 try
460 {
461 if (size < 0)
462 {
463 return error(GL_INVALID_VALUE);
464 }
465
466 switch (usage)
467 {
468 case GL_STREAM_DRAW:
469 case GL_STATIC_DRAW:
470 case GL_DYNAMIC_DRAW:
471 break;
472 default:
473 return error(GL_INVALID_ENUM);
474 }
475
476 gl::Context *context = gl::getContext();
477
478 if (context)
479 {
480 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000481
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000482 switch (target)
483 {
484 case GL_ARRAY_BUFFER:
485 buffer = context->getArrayBuffer();
486 break;
487 case GL_ELEMENT_ARRAY_BUFFER:
488 buffer = context->getElementArrayBuffer();
489 break;
490 default:
491 return error(GL_INVALID_ENUM);
492 }
493
494 if (!buffer)
495 {
496 return error(GL_INVALID_OPERATION);
497 }
498
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000499 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000500 }
501 }
502 catch(std::bad_alloc&)
503 {
504 return error(GL_OUT_OF_MEMORY);
505 }
506}
507
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000508void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000509{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000510 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000511 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512
513 try
514 {
515 if (size < 0)
516 {
517 return error(GL_INVALID_VALUE);
518 }
519
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000520 if (data == NULL)
521 {
522 return;
523 }
524
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000525 gl::Context *context = gl::getContext();
526
527 if (context)
528 {
529 gl::Buffer *buffer;
530
531 switch (target)
532 {
533 case GL_ARRAY_BUFFER:
534 buffer = context->getArrayBuffer();
535 break;
536 case GL_ELEMENT_ARRAY_BUFFER:
537 buffer = context->getElementArrayBuffer();
538 break;
539 default:
540 return error(GL_INVALID_ENUM);
541 }
542
543 if (!buffer)
544 {
545 return error(GL_INVALID_OPERATION);
546 }
547
548 GLenum err = buffer->bufferSubData(data, size, offset);
549
550 if (err != GL_NO_ERROR)
551 {
552 return error(err);
553 }
554 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000555 }
556 catch(std::bad_alloc&)
557 {
558 return error(GL_OUT_OF_MEMORY);
559 }
560}
561
562GLenum __stdcall glCheckFramebufferStatus(GLenum target)
563{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000564 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000565
566 try
567 {
568 if (target != GL_FRAMEBUFFER)
569 {
570 return error(GL_INVALID_ENUM, 0);
571 }
572
573 gl::Context *context = gl::getContext();
574
575 if (context)
576 {
577 gl::Framebuffer *framebuffer = context->getFramebuffer();
578
579 return framebuffer->completeness();
580 }
581 }
582 catch(std::bad_alloc&)
583 {
584 return error(GL_OUT_OF_MEMORY, 0);
585 }
586
587 return 0;
588}
589
590void __stdcall glClear(GLbitfield mask)
591{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000592 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000593
594 try
595 {
596 gl::Context *context = gl::getContext();
597
598 if (context)
599 {
600 context->clear(mask);
601 }
602 }
603 catch(std::bad_alloc&)
604 {
605 return error(GL_OUT_OF_MEMORY);
606 }
607}
608
609void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
610{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000611 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
612 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000613
614 try
615 {
616 gl::Context *context = gl::getContext();
617
618 if (context)
619 {
620 context->setClearColor(red, green, blue, alpha);
621 }
622 }
623 catch(std::bad_alloc&)
624 {
625 return error(GL_OUT_OF_MEMORY);
626 }
627}
628
629void __stdcall glClearDepthf(GLclampf depth)
630{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000631 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000632
633 try
634 {
635 gl::Context *context = gl::getContext();
636
637 if (context)
638 {
639 context->setClearDepth(depth);
640 }
641 }
642 catch(std::bad_alloc&)
643 {
644 return error(GL_OUT_OF_MEMORY);
645 }
646}
647
648void __stdcall glClearStencil(GLint s)
649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000650 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000651
652 try
653 {
654 gl::Context *context = gl::getContext();
655
656 if (context)
657 {
658 context->setClearStencil(s);
659 }
660 }
661 catch(std::bad_alloc&)
662 {
663 return error(GL_OUT_OF_MEMORY);
664 }
665}
666
667void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
668{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000669 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
670 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000671
672 try
673 {
674 gl::Context *context = gl::getContext();
675
676 if (context)
677 {
678 context->colorMaskRed = red != GL_FALSE;
679 context->colorMaskGreen = green != GL_FALSE;
680 context->colorMaskBlue = blue != GL_FALSE;
681 context->colorMaskAlpha = alpha != GL_FALSE;
682 }
683 }
684 catch(std::bad_alloc&)
685 {
686 return error(GL_OUT_OF_MEMORY);
687 }
688}
689
690void __stdcall glCompileShader(GLuint shader)
691{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000692 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000693
694 try
695 {
696 gl::Context *context = gl::getContext();
697
698 if (context)
699 {
700 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000701
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000702 if (!shaderObject)
703 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000704 if (context->getProgram(shader))
705 {
706 return error(GL_INVALID_OPERATION);
707 }
708 else
709 {
710 return error(GL_INVALID_VALUE);
711 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000712 }
713
714 shaderObject->compile();
715 }
716 }
717 catch(std::bad_alloc&)
718 {
719 return error(GL_OUT_OF_MEMORY);
720 }
721}
722
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000723void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
724 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000725{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000726 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000727 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000728 target, level, internalformat, width, height, border, imageSize, data);
729
730 try
731 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000732 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
733 {
734 return error(GL_INVALID_ENUM);
735 }
736
737 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000738 {
739 return error(GL_INVALID_VALUE);
740 }
741
daniel@transgaming.com41430492010-03-11 20:36:18 +0000742 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
743 {
744 return error(GL_INVALID_VALUE);
745 }
746
747 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748 }
749 catch(std::bad_alloc&)
750 {
751 return error(GL_OUT_OF_MEMORY);
752 }
753}
754
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000755void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
756 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000757{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000758 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
759 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000760 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000761 target, level, xoffset, yoffset, width, height, format, imageSize, data);
762
763 try
764 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000765 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
766 {
767 return error(GL_INVALID_ENUM);
768 }
769
770 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000771 {
772 return error(GL_INVALID_VALUE);
773 }
774
daniel@transgaming.com41430492010-03-11 20:36:18 +0000775 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
776 {
777 return error(GL_INVALID_VALUE);
778 }
779
780 if (xoffset != 0 || yoffset != 0)
781 {
782 return error(GL_INVALID_OPERATION);
783 }
784
785 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000786 }
787 catch(std::bad_alloc&)
788 {
789 return error(GL_OUT_OF_MEMORY);
790 }
791}
792
793void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
794{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000795 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
796 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000797 target, level, internalformat, x, y, width, height, border);
798
799 try
800 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000801 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000802 {
803 return error(GL_INVALID_VALUE);
804 }
805
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000806 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
807 {
808 return error(GL_INVALID_VALUE);
809 }
810
811 switch (target)
812 {
813 case GL_TEXTURE_2D:
814 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
815 {
816 return error(GL_INVALID_VALUE);
817 }
818 break;
819 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
820 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
821 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
822 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
823 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
824 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +0000825 if (width != height)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000826 {
827 return error(GL_INVALID_VALUE);
828 }
829
830 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
831 {
832 return error(GL_INVALID_VALUE);
833 }
834 break;
835 default:
836 return error(GL_INVALID_ENUM);
837 }
838
839 switch (internalformat)
840 {
841 case GL_ALPHA:
842 case GL_LUMINANCE:
843 case GL_LUMINANCE_ALPHA:
844 case GL_RGB:
845 case GL_RGBA:
846 break;
847 default:
848 return error(GL_INVALID_VALUE);
849 }
850
851 if (border != 0)
852 {
853 return error(GL_INVALID_VALUE);
854 }
855
856 gl::Context *context = gl::getContext();
857
858 if (context)
859 {
860 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
861
862 if (target == GL_TEXTURE_2D)
863 {
864 gl::Texture2D *texture = context->getTexture2D();
865
866 if (!texture)
867 {
868 return error(GL_INVALID_OPERATION);
869 }
870
871 texture->copyImage(level, internalformat, x, y, width, height, source);
872 }
873 else if (es2dx::IsCubemapTextureTarget(target))
874 {
875 gl::TextureCubeMap *texture = context->getTextureCubeMap();
876
877 if (!texture)
878 {
879 return error(GL_INVALID_OPERATION);
880 }
881
882 texture->copyImage(target, level, internalformat, x, y, width, height, source);
883 }
884 else
885 {
886 UNREACHABLE();
887 }
888 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000889 }
890 catch(std::bad_alloc&)
891 {
892 return error(GL_OUT_OF_MEMORY);
893 }
894}
895
896void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
897{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000898 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
899 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000900 target, level, xoffset, yoffset, x, y, width, height);
901
902 try
903 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000904 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
905 {
906 return error(GL_INVALID_ENUM);
907 }
908
909 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000910 {
911 return error(GL_INVALID_VALUE);
912 }
913
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000914 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
915 {
916 return error(GL_INVALID_VALUE);
917 }
918
919 if (width == 0 || height == 0)
920 {
921 return;
922 }
923
924 gl::Context *context = gl::getContext();
925
926 if (context)
927 {
928 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
929
930 if (target == GL_TEXTURE_2D)
931 {
932 gl::Texture2D *texture = context->getTexture2D();
933
934 if (!texture)
935 {
936 return error(GL_INVALID_OPERATION);
937 }
938
939 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
940 }
941 else if (es2dx::IsCubemapTextureTarget(target))
942 {
943 gl::TextureCubeMap *texture = context->getTextureCubeMap();
944
945 if (!texture)
946 {
947 return error(GL_INVALID_OPERATION);
948 }
949
950 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
951 }
952 else
953 {
954 UNREACHABLE();
955 }
956 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000957 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000958
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000959 catch(std::bad_alloc&)
960 {
961 return error(GL_OUT_OF_MEMORY);
962 }
963}
964
965GLuint __stdcall glCreateProgram(void)
966{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000967 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000968
969 try
970 {
971 gl::Context *context = gl::getContext();
972
973 if (context)
974 {
975 return context->createProgram();
976 }
977 }
978 catch(std::bad_alloc&)
979 {
980 return error(GL_OUT_OF_MEMORY, 0);
981 }
982
983 return 0;
984}
985
986GLuint __stdcall glCreateShader(GLenum type)
987{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000988 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000989
990 try
991 {
992 gl::Context *context = gl::getContext();
993
994 if (context)
995 {
996 switch (type)
997 {
998 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000999 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001000 return context->createShader(type);
1001 default:
1002 return error(GL_INVALID_ENUM, 0);
1003 }
1004 }
1005 }
1006 catch(std::bad_alloc&)
1007 {
1008 return error(GL_OUT_OF_MEMORY, 0);
1009 }
1010
1011 return 0;
1012}
1013
1014void __stdcall glCullFace(GLenum mode)
1015{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001016 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001017
1018 try
1019 {
1020 switch (mode)
1021 {
1022 case GL_FRONT:
1023 case GL_BACK:
1024 case GL_FRONT_AND_BACK:
1025 {
1026 gl::Context *context = gl::getContext();
1027
1028 if (context)
1029 {
1030 context->cullMode = mode;
1031 }
1032 }
1033 break;
1034 default:
1035 return error(GL_INVALID_ENUM);
1036 }
1037 }
1038 catch(std::bad_alloc&)
1039 {
1040 return error(GL_OUT_OF_MEMORY);
1041 }
1042}
1043
1044void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1045{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001046 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001047
1048 try
1049 {
1050 if (n < 0)
1051 {
1052 return error(GL_INVALID_VALUE);
1053 }
1054
1055 gl::Context *context = gl::getContext();
1056
1057 if (context)
1058 {
1059 for (int i = 0; i < n; i++)
1060 {
1061 context->deleteBuffer(buffers[i]);
1062 }
1063 }
1064 }
1065 catch(std::bad_alloc&)
1066 {
1067 return error(GL_OUT_OF_MEMORY);
1068 }
1069}
1070
1071void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1072{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001073 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001074
1075 try
1076 {
1077 if (n < 0)
1078 {
1079 return error(GL_INVALID_VALUE);
1080 }
1081
1082 gl::Context *context = gl::getContext();
1083
1084 if (context)
1085 {
1086 for (int i = 0; i < n; i++)
1087 {
1088 if (framebuffers[i] != 0)
1089 {
1090 context->deleteFramebuffer(framebuffers[i]);
1091 }
1092 }
1093 }
1094 }
1095 catch(std::bad_alloc&)
1096 {
1097 return error(GL_OUT_OF_MEMORY);
1098 }
1099}
1100
1101void __stdcall glDeleteProgram(GLuint program)
1102{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001103 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001104
1105 try
1106 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001107 if (program == 0)
1108 {
1109 return;
1110 }
1111
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001112 gl::Context *context = gl::getContext();
1113
1114 if (context)
1115 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001116 if (!context->getProgram(program))
1117 {
1118 if(context->getShader(program))
1119 {
1120 return error(GL_INVALID_OPERATION);
1121 }
1122 else
1123 {
1124 return error(GL_INVALID_VALUE);
1125 }
1126 }
1127
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001128 context->deleteProgram(program);
1129 }
1130 }
1131 catch(std::bad_alloc&)
1132 {
1133 return error(GL_OUT_OF_MEMORY);
1134 }
1135}
1136
1137void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1138{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001139 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001140
1141 try
1142 {
1143 if (n < 0)
1144 {
1145 return error(GL_INVALID_VALUE);
1146 }
1147
1148 gl::Context *context = gl::getContext();
1149
1150 if (context)
1151 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001152 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001153 {
1154 context->deleteRenderbuffer(renderbuffers[i]);
1155 }
1156 }
1157 }
1158 catch(std::bad_alloc&)
1159 {
1160 return error(GL_OUT_OF_MEMORY);
1161 }
1162}
1163
1164void __stdcall glDeleteShader(GLuint shader)
1165{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001166 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001167
1168 try
1169 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001170 if (shader == 0)
1171 {
1172 return;
1173 }
1174
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001175 gl::Context *context = gl::getContext();
1176
1177 if (context)
1178 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001179 if (!context->getShader(shader))
1180 {
1181 if(context->getProgram(shader))
1182 {
1183 return error(GL_INVALID_OPERATION);
1184 }
1185 else
1186 {
1187 return error(GL_INVALID_VALUE);
1188 }
1189 }
1190
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001191 context->deleteShader(shader);
1192 }
1193 }
1194 catch(std::bad_alloc&)
1195 {
1196 return error(GL_OUT_OF_MEMORY);
1197 }
1198}
1199
1200void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1201{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001202 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001203
1204 try
1205 {
1206 if (n < 0)
1207 {
1208 return error(GL_INVALID_VALUE);
1209 }
1210
1211 gl::Context *context = gl::getContext();
1212
1213 if (context)
1214 {
1215 for (int i = 0; i < n; i++)
1216 {
1217 if (textures[i] != 0)
1218 {
1219 context->deleteTexture(textures[i]);
1220 }
1221 }
1222 }
1223 }
1224 catch(std::bad_alloc&)
1225 {
1226 return error(GL_OUT_OF_MEMORY);
1227 }
1228}
1229
1230void __stdcall glDepthFunc(GLenum func)
1231{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001232 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001233
1234 try
1235 {
1236 switch (func)
1237 {
1238 case GL_NEVER:
1239 case GL_ALWAYS:
1240 case GL_LESS:
1241 case GL_LEQUAL:
1242 case GL_EQUAL:
1243 case GL_GREATER:
1244 case GL_GEQUAL:
1245 case GL_NOTEQUAL:
1246 break;
1247 default:
1248 return error(GL_INVALID_ENUM);
1249 }
1250
1251 gl::Context *context = gl::getContext();
1252
1253 if (context)
1254 {
1255 context->depthFunc = func;
1256 }
1257 }
1258 catch(std::bad_alloc&)
1259 {
1260 return error(GL_OUT_OF_MEMORY);
1261 }
1262}
1263
1264void __stdcall glDepthMask(GLboolean flag)
1265{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001266 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001267
1268 try
1269 {
1270 gl::Context *context = gl::getContext();
1271
1272 if (context)
1273 {
1274 context->depthMask = flag != GL_FALSE;
1275 }
1276 }
1277 catch(std::bad_alloc&)
1278 {
1279 return error(GL_OUT_OF_MEMORY);
1280 }
1281}
1282
1283void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1284{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001285 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001286
1287 try
1288 {
1289 gl::Context *context = gl::getContext();
1290
1291 if (context)
1292 {
1293 context->zNear = zNear;
1294 context->zFar = zFar;
1295 }
1296 }
1297 catch(std::bad_alloc&)
1298 {
1299 return error(GL_OUT_OF_MEMORY);
1300 }
1301}
1302
1303void __stdcall glDetachShader(GLuint program, GLuint shader)
1304{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001305 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001306
1307 try
1308 {
1309 gl::Context *context = gl::getContext();
1310
1311 if (context)
1312 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001313
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001314 gl::Program *programObject = context->getProgram(program);
1315 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001316
1317 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001318 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001319 gl::Shader *shaderByProgramHandle;
1320 shaderByProgramHandle = context->getShader(program);
1321 if (!shaderByProgramHandle)
1322 {
1323 return error(GL_INVALID_VALUE);
1324 }
1325 else
1326 {
1327 return error(GL_INVALID_OPERATION);
1328 }
1329 }
1330
1331 if (!shaderObject)
1332 {
1333 gl::Program *programByShaderHandle = context->getProgram(shader);
1334 if (!programByShaderHandle)
1335 {
1336 return error(GL_INVALID_VALUE);
1337 }
1338 else
1339 {
1340 return error(GL_INVALID_OPERATION);
1341 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001342 }
1343
1344 if (!programObject->detachShader(shaderObject))
1345 {
1346 return error(GL_INVALID_OPERATION);
1347 }
1348
1349 if (shaderObject->isDeletable())
1350 {
1351 context->deleteShader(shader);
1352 }
1353 }
1354 }
1355 catch(std::bad_alloc&)
1356 {
1357 return error(GL_OUT_OF_MEMORY);
1358 }
1359}
1360
1361void __stdcall glDisable(GLenum cap)
1362{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001363 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001364
1365 try
1366 {
1367 gl::Context *context = gl::getContext();
1368
1369 if (context)
1370 {
1371 switch (cap)
1372 {
1373 case GL_CULL_FACE: context->cullFace = false; break;
1374 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1375 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1376 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1377 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1378 case GL_STENCIL_TEST: context->stencilTest = false; break;
1379 case GL_DEPTH_TEST: context->depthTest = false; break;
1380 case GL_BLEND: context->blend = false; break;
1381 case GL_DITHER: context->dither = false; break;
1382 default:
1383 return error(GL_INVALID_ENUM);
1384 }
1385 }
1386 }
1387 catch(std::bad_alloc&)
1388 {
1389 return error(GL_OUT_OF_MEMORY);
1390 }
1391}
1392
1393void __stdcall glDisableVertexAttribArray(GLuint index)
1394{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001395 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001396
1397 try
1398 {
1399 if (index >= gl::MAX_VERTEX_ATTRIBS)
1400 {
1401 return error(GL_INVALID_VALUE);
1402 }
1403
1404 gl::Context *context = gl::getContext();
1405
1406 if (context)
1407 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001408 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001409 }
1410 }
1411 catch(std::bad_alloc&)
1412 {
1413 return error(GL_OUT_OF_MEMORY);
1414 }
1415}
1416
1417void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1418{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001419 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001420
1421 try
1422 {
1423 if (count < 0 || first < 0)
1424 {
1425 return error(GL_INVALID_VALUE);
1426 }
1427
1428 gl::Context *context = gl::getContext();
1429
1430 if (context)
1431 {
1432 context->drawArrays(mode, first, count);
1433 }
1434 }
1435 catch(std::bad_alloc&)
1436 {
1437 return error(GL_OUT_OF_MEMORY);
1438 }
1439}
1440
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001441void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001442{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001443 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001444 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001445
1446 try
1447 {
1448 if (count < 0)
1449 {
1450 return error(GL_INVALID_VALUE);
1451 }
1452
1453 switch (type)
1454 {
1455 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001456 case GL_UNSIGNED_SHORT:
1457 break;
1458 default:
1459 return error(GL_INVALID_ENUM);
1460 }
1461
1462 gl::Context *context = gl::getContext();
1463
1464 if (context)
1465 {
1466 context->drawElements(mode, count, type, indices);
1467 }
1468 }
1469 catch(std::bad_alloc&)
1470 {
1471 return error(GL_OUT_OF_MEMORY);
1472 }
1473}
1474
1475void __stdcall glEnable(GLenum cap)
1476{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001477 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001478
1479 try
1480 {
1481 gl::Context *context = gl::getContext();
1482
1483 if (context)
1484 {
1485 switch (cap)
1486 {
1487 case GL_CULL_FACE: context->cullFace = true; break;
1488 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1489 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1490 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1491 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1492 case GL_STENCIL_TEST: context->stencilTest = true; break;
1493 case GL_DEPTH_TEST: context->depthTest = true; break;
1494 case GL_BLEND: context->blend = true; break;
1495 case GL_DITHER: context->dither = true; break;
1496 default:
1497 return error(GL_INVALID_ENUM);
1498 }
1499 }
1500 }
1501 catch(std::bad_alloc&)
1502 {
1503 return error(GL_OUT_OF_MEMORY);
1504 }
1505}
1506
1507void __stdcall glEnableVertexAttribArray(GLuint index)
1508{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001509 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001510
1511 try
1512 {
1513 if (index >= gl::MAX_VERTEX_ATTRIBS)
1514 {
1515 return error(GL_INVALID_VALUE);
1516 }
1517
1518 gl::Context *context = gl::getContext();
1519
1520 if (context)
1521 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001522 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001523 }
1524 }
1525 catch(std::bad_alloc&)
1526 {
1527 return error(GL_OUT_OF_MEMORY);
1528 }
1529}
1530
1531void __stdcall glFinish(void)
1532{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001533 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001534
1535 try
1536 {
1537 gl::Context *context = gl::getContext();
1538
1539 if (context)
1540 {
1541 context->finish();
1542 }
1543 }
1544 catch(std::bad_alloc&)
1545 {
1546 return error(GL_OUT_OF_MEMORY);
1547 }
1548}
1549
1550void __stdcall glFlush(void)
1551{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001552 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001553
1554 try
1555 {
1556 gl::Context *context = gl::getContext();
1557
1558 if (context)
1559 {
1560 context->flush();
1561 }
1562 }
1563 catch(std::bad_alloc&)
1564 {
1565 return error(GL_OUT_OF_MEMORY);
1566 }
1567}
1568
1569void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1570{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001571 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1572 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001573
1574 try
1575 {
1576 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1577 {
1578 return error(GL_INVALID_ENUM);
1579 }
1580
1581 gl::Context *context = gl::getContext();
1582
1583 if (context)
1584 {
1585 gl::Framebuffer *framebuffer = context->getFramebuffer();
1586
1587 if (context->framebuffer == 0 || !framebuffer)
1588 {
1589 return error(GL_INVALID_OPERATION);
1590 }
1591
1592 switch (attachment)
1593 {
1594 case GL_COLOR_ATTACHMENT0:
1595 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1596 break;
1597 case GL_DEPTH_ATTACHMENT:
1598 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1599 break;
1600 case GL_STENCIL_ATTACHMENT:
1601 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1602 break;
1603 default:
1604 return error(GL_INVALID_ENUM);
1605 }
1606 }
1607 }
1608 catch(std::bad_alloc&)
1609 {
1610 return error(GL_OUT_OF_MEMORY);
1611 }
1612}
1613
1614void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1615{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001616 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1617 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001618
1619 try
1620 {
1621 if (target != GL_FRAMEBUFFER)
1622 {
1623 return error(GL_INVALID_ENUM);
1624 }
1625
1626 switch (attachment)
1627 {
1628 case GL_COLOR_ATTACHMENT0:
1629 break;
1630 default:
1631 return error(GL_INVALID_ENUM);
1632 }
1633
1634 gl::Context *context = gl::getContext();
1635
1636 if (context)
1637 {
1638 if (texture)
1639 {
1640 switch (textarget)
1641 {
1642 case GL_TEXTURE_2D:
1643 if (!context->getTexture2D())
1644 {
1645 return error(GL_INVALID_OPERATION);
1646 }
1647 break;
1648 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1649 UNIMPLEMENTED(); // FIXME
1650 break;
1651 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1652 UNIMPLEMENTED(); // FIXME
1653 break;
1654 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1655 UNIMPLEMENTED(); // FIXME
1656 break;
1657 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1658 UNIMPLEMENTED(); // FIXME
1659 break;
1660 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1661 UNIMPLEMENTED(); // FIXME
1662 break;
1663 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1664 UNIMPLEMENTED(); // FIXME
1665 break;
1666 default:
1667 return error(GL_INVALID_ENUM);
1668 }
1669
1670 if (level != 0)
1671 {
1672 return error(GL_INVALID_VALUE);
1673 }
1674 }
1675
1676 gl::Framebuffer *framebuffer = context->getFramebuffer();
1677
1678 if (context->framebuffer == 0 || !framebuffer)
1679 {
1680 return error(GL_INVALID_OPERATION);
1681 }
1682
1683 framebuffer->setColorbuffer(GL_TEXTURE, texture);
1684 }
1685 }
1686 catch(std::bad_alloc&)
1687 {
1688 return error(GL_OUT_OF_MEMORY);
1689 }
1690}
1691
1692void __stdcall glFrontFace(GLenum mode)
1693{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001694 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001695
1696 try
1697 {
1698 switch (mode)
1699 {
1700 case GL_CW:
1701 case GL_CCW:
1702 {
1703 gl::Context *context = gl::getContext();
1704
1705 if (context)
1706 {
1707 context->frontFace = mode;
1708 }
1709 }
1710 break;
1711 default:
1712 return error(GL_INVALID_ENUM);
1713 }
1714 }
1715 catch(std::bad_alloc&)
1716 {
1717 return error(GL_OUT_OF_MEMORY);
1718 }
1719}
1720
1721void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1722{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001723 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001724
1725 try
1726 {
1727 if (n < 0)
1728 {
1729 return error(GL_INVALID_VALUE);
1730 }
1731
1732 gl::Context *context = gl::getContext();
1733
1734 if (context)
1735 {
1736 for (int i = 0; i < n; i++)
1737 {
1738 buffers[i] = context->createBuffer();
1739 }
1740 }
1741 }
1742 catch(std::bad_alloc&)
1743 {
1744 return error(GL_OUT_OF_MEMORY);
1745 }
1746}
1747
1748void __stdcall glGenerateMipmap(GLenum target)
1749{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001750 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001751
1752 try
1753 {
1754 UNIMPLEMENTED(); // FIXME
1755 }
1756 catch(std::bad_alloc&)
1757 {
1758 return error(GL_OUT_OF_MEMORY);
1759 }
1760}
1761
1762void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1763{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001764 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001765
1766 try
1767 {
1768 if (n < 0)
1769 {
1770 return error(GL_INVALID_VALUE);
1771 }
1772
1773 gl::Context *context = gl::getContext();
1774
1775 if (context)
1776 {
1777 for (int i = 0; i < n; i++)
1778 {
1779 framebuffers[i] = context->createFramebuffer();
1780 }
1781 }
1782 }
1783 catch(std::bad_alloc&)
1784 {
1785 return error(GL_OUT_OF_MEMORY);
1786 }
1787}
1788
1789void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1790{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001791 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001792
1793 try
1794 {
1795 if (n < 0)
1796 {
1797 return error(GL_INVALID_VALUE);
1798 }
1799
1800 gl::Context *context = gl::getContext();
1801
1802 if (context)
1803 {
1804 for (int i = 0; i < n; i++)
1805 {
1806 renderbuffers[i] = context->createRenderbuffer();
1807 }
1808 }
1809 }
1810 catch(std::bad_alloc&)
1811 {
1812 return error(GL_OUT_OF_MEMORY);
1813 }
1814}
1815
1816void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1817{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001818 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001819
1820 try
1821 {
1822 if (n < 0)
1823 {
1824 return error(GL_INVALID_VALUE);
1825 }
1826
1827 gl::Context *context = gl::getContext();
1828
1829 if (context)
1830 {
1831 for (int i = 0; i < n; i++)
1832 {
1833 textures[i] = context->createTexture();
1834 }
1835 }
1836 }
1837 catch(std::bad_alloc&)
1838 {
1839 return error(GL_OUT_OF_MEMORY);
1840 }
1841}
1842
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001843void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001844{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001845 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001846 "GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001847 program, index, bufsize, length, size, type, name);
1848
1849 try
1850 {
1851 if (bufsize < 0)
1852 {
1853 return error(GL_INVALID_VALUE);
1854 }
1855
1856 UNIMPLEMENTED(); // FIXME
1857 }
1858 catch(std::bad_alloc&)
1859 {
1860 return error(GL_OUT_OF_MEMORY);
1861 }
1862}
1863
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001864void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001865{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001866 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001867 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001868 program, index, bufsize, length, size, type, name);
1869
1870 try
1871 {
1872 if (bufsize < 0)
1873 {
1874 return error(GL_INVALID_VALUE);
1875 }
1876
1877 UNIMPLEMENTED(); // FIXME
1878 }
1879 catch(std::bad_alloc&)
1880 {
1881 return error(GL_OUT_OF_MEMORY);
1882 }
1883}
1884
1885void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1886{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001887 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1888 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001889
1890 try
1891 {
1892 if (maxcount < 0)
1893 {
1894 return error(GL_INVALID_VALUE);
1895 }
1896
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001897 gl::Context *context = gl::getContext();
1898
1899 if (context)
1900 {
1901 gl::Program *programObject = context->getProgram(program);
1902
1903 if (!programObject)
1904 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001905 if (context->getShader(program))
1906 {
1907 return error(GL_INVALID_OPERATION);
1908 }
1909 else
1910 {
1911 return error(GL_INVALID_VALUE);
1912 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001913 }
1914
1915 return programObject->getAttachedShaders(maxcount, count, shaders);
1916 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001917 }
1918 catch(std::bad_alloc&)
1919 {
1920 return error(GL_OUT_OF_MEMORY);
1921 }
1922}
1923
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001924int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001925{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001926 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001927
1928 try
1929 {
1930 gl::Context *context = gl::getContext();
1931
1932 if (context)
1933 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001934
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001935 gl::Program *programObject = context->getProgram(program);
1936
1937 if (!programObject)
1938 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001939 if (context->getShader(program))
1940 {
1941 return error(GL_INVALID_OPERATION, -1);
1942 }
1943 else
1944 {
1945 return error(GL_INVALID_VALUE, -1);
1946 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001947 }
1948
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00001949 if (!programObject->isLinked())
1950 {
1951 return error(GL_INVALID_OPERATION, -1);
1952 }
1953
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001954 return programObject->getAttributeLocation(name);
1955 }
1956 }
1957 catch(std::bad_alloc&)
1958 {
1959 return error(GL_OUT_OF_MEMORY, -1);
1960 }
1961
1962 return -1;
1963}
1964
1965void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1966{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001967 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001968
1969 try
1970 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001971 gl::Context *context = gl::getContext();
1972
1973 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001974 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001975 if (!(context->getBooleanv(pname, params)))
1976 {
1977 GLenum nativeType;
1978 unsigned int numParams = 0;
1979 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1980 return error(GL_INVALID_ENUM);
1981
1982 if (numParams == 0)
1983 return; // it is known that the pname is valid, but there are no parameters to return
1984
1985 if (nativeType == GL_FLOAT)
1986 {
1987 GLfloat *floatParams = NULL;
1988 floatParams = new GLfloat[numParams];
1989
1990 context->getFloatv(pname, floatParams);
1991
1992 for (unsigned int i = 0; i < numParams; ++i)
1993 {
1994 if (floatParams[i] == 0.0f)
1995 params[i] = GL_FALSE;
1996 else
1997 params[i] = GL_TRUE;
1998 }
1999
2000 delete [] floatParams;
2001 }
2002 else if (nativeType == GL_INT)
2003 {
2004 GLint *intParams = NULL;
2005 intParams = new GLint[numParams];
2006
2007 context->getIntegerv(pname, intParams);
2008
2009 for (unsigned int i = 0; i < numParams; ++i)
2010 {
2011 if (intParams[i] == 0)
2012 params[i] = GL_FALSE;
2013 else
2014 params[i] = GL_TRUE;
2015 }
2016
2017 delete [] intParams;
2018 }
2019 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002020 }
2021 }
2022 catch(std::bad_alloc&)
2023 {
2024 return error(GL_OUT_OF_MEMORY);
2025 }
2026}
2027
2028void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2029{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002030 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002031
2032 try
2033 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002034 gl::Context *context = gl::getContext();
2035
2036 if (context)
2037 {
2038 gl::Buffer *buffer;
2039
2040 switch (target)
2041 {
2042 case GL_ARRAY_BUFFER:
2043 buffer = context->getArrayBuffer();
2044 break;
2045 case GL_ELEMENT_ARRAY_BUFFER:
2046 buffer = context->getElementArrayBuffer();
2047 break;
2048 default: return error(GL_INVALID_ENUM);
2049 }
2050
2051 if (!buffer)
2052 {
2053 // A null buffer means that "0" is bound to the requested buffer target
2054 return error(GL_INVALID_OPERATION);
2055 }
2056
2057 switch (pname)
2058 {
2059 case GL_BUFFER_USAGE:
2060 *params = buffer->usage();
2061 break;
2062 case GL_BUFFER_SIZE:
2063 *params = buffer->size();
2064 break;
2065 default: return error(GL_INVALID_ENUM);
2066 }
2067 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002068 }
2069 catch(std::bad_alloc&)
2070 {
2071 return error(GL_OUT_OF_MEMORY);
2072 }
2073}
2074
2075GLenum __stdcall glGetError(void)
2076{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002077 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002078
2079 gl::Context *context = gl::getContext();
2080
2081 if (context)
2082 {
2083 return context->getError();
2084 }
2085
2086 return GL_NO_ERROR;
2087}
2088
2089void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2090{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002091 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002092
2093 try
2094 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002095 gl::Context *context = gl::getContext();
2096
2097 if (context)
2098 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002099 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002100 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002101 GLenum nativeType;
2102 unsigned int numParams = 0;
2103 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2104 return error(GL_INVALID_ENUM);
2105
2106 if (numParams == 0)
2107 return; // it is known that the pname is valid, but that there are no parameters to return.
2108
2109 if (nativeType == GL_BOOL)
2110 {
2111 GLboolean *boolParams = NULL;
2112 boolParams = new GLboolean[numParams];
2113
2114 context->getBooleanv(pname, boolParams);
2115
2116 for (unsigned int i = 0; i < numParams; ++i)
2117 {
2118 if (boolParams[i] == GL_FALSE)
2119 params[i] = 0.0f;
2120 else
2121 params[i] = 1.0f;
2122 }
2123
2124 delete [] boolParams;
2125 }
2126 else if (nativeType == GL_INT)
2127 {
2128 GLint *intParams = NULL;
2129 intParams = new GLint[numParams];
2130
2131 context->getIntegerv(pname, intParams);
2132
2133 for (unsigned int i = 0; i < numParams; ++i)
2134 {
2135 params[i] = (GLfloat)intParams[i];
2136 }
2137
2138 delete [] intParams;
2139 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002140 }
2141 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002142 }
2143 catch(std::bad_alloc&)
2144 {
2145 return error(GL_OUT_OF_MEMORY);
2146 }
2147}
2148
2149void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2150{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002151 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2152 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002153
2154 try
2155 {
2156 gl::Context *context = gl::getContext();
2157
2158 if (context)
2159 {
2160 if (context->framebuffer == 0)
2161 {
2162 return error(GL_INVALID_OPERATION);
2163 }
2164
2165 UNIMPLEMENTED(); // FIXME
2166 }
2167 }
2168 catch(std::bad_alloc&)
2169 {
2170 return error(GL_OUT_OF_MEMORY);
2171 }
2172}
2173
2174void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2175{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002176 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002177
2178 try
2179 {
2180 gl::Context *context = gl::getContext();
2181
2182 if (context)
2183 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002184 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002185 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002186 GLenum nativeType;
2187 unsigned int numParams = 0;
2188 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2189 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002190
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002191 if (numParams == 0)
2192 return; // it is known that pname is valid, but there are no parameters to return
2193
2194 if (nativeType == GL_BOOL)
2195 {
2196 GLboolean *boolParams = NULL;
2197 boolParams = new GLboolean[numParams];
2198
2199 context->getBooleanv(pname, boolParams);
2200
2201 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002202 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002203 if (boolParams[i] == GL_FALSE)
2204 params[i] = 0;
2205 else
2206 params[i] = 1;
2207 }
2208
2209 delete [] boolParams;
2210 }
2211 else if (nativeType == GL_FLOAT)
2212 {
2213 GLfloat *floatParams = NULL;
2214 floatParams = new GLfloat[numParams];
2215
2216 context->getFloatv(pname, floatParams);
2217
2218 for (unsigned int i = 0; i < numParams; ++i)
2219 {
2220 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002221 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002222 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002223 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002224 else
2225 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 +00002226 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002227
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002228 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002229 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002230 }
2231 }
2232 }
2233 catch(std::bad_alloc&)
2234 {
2235 return error(GL_OUT_OF_MEMORY);
2236 }
2237}
2238
2239void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2240{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002241 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002242
2243 try
2244 {
2245 gl::Context *context = gl::getContext();
2246
2247 if (context)
2248 {
2249 gl::Program *programObject = context->getProgram(program);
2250
2251 if (!programObject)
2252 {
2253 return error(GL_INVALID_VALUE);
2254 }
2255
2256 switch (pname)
2257 {
2258 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002259 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002260 return;
2261 case GL_LINK_STATUS:
2262 *params = programObject->isLinked();
2263 return;
2264 case GL_VALIDATE_STATUS:
2265 UNIMPLEMENTED(); // FIXME
2266 *params = GL_TRUE;
2267 return;
2268 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002269 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002270 return;
2271 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002272 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002273 return;
2274 case GL_ACTIVE_ATTRIBUTES:
2275 UNIMPLEMENTED(); // FIXME
2276 *params = 0;
2277 return;
2278 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2279 UNIMPLEMENTED(); // FIXME
2280 *params = 0;
2281 return;
2282 case GL_ACTIVE_UNIFORMS:
2283 UNIMPLEMENTED(); // FIXME
2284 *params = 0;
2285 return;
2286 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2287 UNIMPLEMENTED(); // FIXME
2288 *params = 0;
2289 return;
2290 default:
2291 return error(GL_INVALID_ENUM);
2292 }
2293 }
2294 }
2295 catch(std::bad_alloc&)
2296 {
2297 return error(GL_OUT_OF_MEMORY);
2298 }
2299}
2300
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002301void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002302{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002303 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 +00002304 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002305
2306 try
2307 {
2308 if (bufsize < 0)
2309 {
2310 return error(GL_INVALID_VALUE);
2311 }
2312
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002313 gl::Context *context = gl::getContext();
2314
2315 if (context)
2316 {
2317 gl::Program *programObject = context->getProgram(program);
2318
2319 if (!programObject)
2320 {
2321 return error(GL_INVALID_VALUE);
2322 }
2323
2324 programObject->getInfoLog(bufsize, length, infolog);
2325 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002326 }
2327 catch(std::bad_alloc&)
2328 {
2329 return error(GL_OUT_OF_MEMORY);
2330 }
2331}
2332
2333void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2334{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002335 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 +00002336
2337 try
2338 {
2339 UNIMPLEMENTED(); // FIXME
2340 }
2341 catch(std::bad_alloc&)
2342 {
2343 return error(GL_OUT_OF_MEMORY);
2344 }
2345}
2346
2347void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2348{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002349 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002350
2351 try
2352 {
2353 gl::Context *context = gl::getContext();
2354
2355 if (context)
2356 {
2357 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002358
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002359 if (!shaderObject)
2360 {
2361 return error(GL_INVALID_VALUE);
2362 }
2363
2364 switch (pname)
2365 {
2366 case GL_SHADER_TYPE:
2367 *params = shaderObject->getType();
2368 return;
2369 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002370 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002371 return;
2372 case GL_COMPILE_STATUS:
2373 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2374 return;
2375 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002376 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002377 return;
2378 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002379 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002380 return;
2381 default:
2382 return error(GL_INVALID_ENUM);
2383 }
2384 }
2385 }
2386 catch(std::bad_alloc&)
2387 {
2388 return error(GL_OUT_OF_MEMORY);
2389 }
2390}
2391
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002392void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002393{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002394 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 +00002395 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002396
2397 try
2398 {
2399 if (bufsize < 0)
2400 {
2401 return error(GL_INVALID_VALUE);
2402 }
2403
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002404 gl::Context *context = gl::getContext();
2405
2406 if (context)
2407 {
2408 gl::Shader *shaderObject = context->getShader(shader);
2409
2410 if (!shaderObject)
2411 {
2412 return error(GL_INVALID_VALUE);
2413 }
2414
2415 shaderObject->getInfoLog(bufsize, length, infolog);
2416 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002417 }
2418 catch(std::bad_alloc&)
2419 {
2420 return error(GL_OUT_OF_MEMORY);
2421 }
2422}
2423
2424void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2425{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002426 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2427 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002428
2429 try
2430 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002431 switch (shadertype)
2432 {
2433 case GL_VERTEX_SHADER:
2434 case GL_FRAGMENT_SHADER:
2435 break;
2436 default:
2437 return error(GL_INVALID_ENUM);
2438 }
2439
2440 switch (precisiontype)
2441 {
2442 case GL_LOW_FLOAT:
2443 case GL_MEDIUM_FLOAT:
2444 case GL_HIGH_FLOAT:
2445 // Assume IEEE 754 precision
2446 range[0] = 127;
2447 range[1] = 127;
2448 precision[0] = 23;
2449 precision[1] = 23;
2450 break;
2451 case GL_LOW_INT:
2452 case GL_MEDIUM_INT:
2453 case GL_HIGH_INT:
2454 // Some (most) hardware only supports single-precision floating-point numbers,
2455 // which can accurately represent integers up to +/-16777216
2456 range[0] = 24;
2457 range[1] = 24;
2458 precision[0] = 0;
2459 precision[1] = 0;
2460 break;
2461 default:
2462 return error(GL_INVALID_ENUM);
2463 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002464 }
2465 catch(std::bad_alloc&)
2466 {
2467 return error(GL_OUT_OF_MEMORY);
2468 }
2469}
2470
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002471void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002472{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002473 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 +00002474 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002475
2476 try
2477 {
2478 if (bufsize < 0)
2479 {
2480 return error(GL_INVALID_VALUE);
2481 }
2482
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002483 gl::Context *context = gl::getContext();
2484
2485 if (context)
2486 {
2487 gl::Shader *shaderObject = context->getShader(shader);
2488
2489 if (!shaderObject)
2490 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002491 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002492 }
2493
2494 shaderObject->getSource(bufsize, length, source);
2495 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002496 }
2497 catch(std::bad_alloc&)
2498 {
2499 return error(GL_OUT_OF_MEMORY);
2500 }
2501}
2502
2503const GLubyte* __stdcall glGetString(GLenum name)
2504{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002505 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002506
2507 try
2508 {
2509 switch (name)
2510 {
2511 case GL_VENDOR:
2512 return (GLubyte*)"TransGaming Inc.";
2513 case GL_RENDERER:
2514 return (GLubyte*)"ANGLE";
2515 case GL_VERSION:
2516 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2517 case GL_SHADING_LANGUAGE_VERSION:
2518 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2519 case GL_EXTENSIONS:
2520 return (GLubyte*)"";
2521 default:
2522 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2523 }
2524 }
2525 catch(std::bad_alloc&)
2526 {
2527 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2528 }
2529
2530 return NULL;
2531}
2532
2533void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2534{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002535 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 +00002536
2537 try
2538 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002539 gl::Context *context = gl::getContext();
2540
2541 if (context)
2542 {
2543 gl::Texture *texture;
2544
2545 switch (target)
2546 {
2547 case GL_TEXTURE_2D:
2548 texture = context->getTexture2D();
2549 break;
2550 case GL_TEXTURE_CUBE_MAP:
2551 texture = context->getTextureCubeMap();
2552 break;
2553 default:
2554 return error(GL_INVALID_ENUM);
2555 }
2556
2557 switch (pname)
2558 {
2559 case GL_TEXTURE_MAG_FILTER:
2560 *params = (GLfloat)texture->getMagFilter();
2561 break;
2562 case GL_TEXTURE_MIN_FILTER:
2563 *params = (GLfloat)texture->getMinFilter();
2564 break;
2565 case GL_TEXTURE_WRAP_S:
2566 *params = (GLfloat)texture->getWrapS();
2567 break;
2568 case GL_TEXTURE_WRAP_T:
2569 *params = (GLfloat)texture->getWrapT();
2570 break;
2571 default:
2572 return error(GL_INVALID_ENUM);
2573 }
2574 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002575 }
2576 catch(std::bad_alloc&)
2577 {
2578 return error(GL_OUT_OF_MEMORY);
2579 }
2580}
2581
2582void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2583{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002584 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 +00002585
2586 try
2587 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002588 gl::Context *context = gl::getContext();
2589
2590 if (context)
2591 {
2592 gl::Texture *texture;
2593
2594 switch (target)
2595 {
2596 case GL_TEXTURE_2D:
2597 texture = context->getTexture2D();
2598 break;
2599 case GL_TEXTURE_CUBE_MAP:
2600 texture = context->getTextureCubeMap();
2601 break;
2602 default:
2603 return error(GL_INVALID_ENUM);
2604 }
2605
2606 switch (pname)
2607 {
2608 case GL_TEXTURE_MAG_FILTER:
2609 *params = texture->getMagFilter();
2610 break;
2611 case GL_TEXTURE_MIN_FILTER:
2612 *params = texture->getMinFilter();
2613 break;
2614 case GL_TEXTURE_WRAP_S:
2615 *params = texture->getWrapS();
2616 break;
2617 case GL_TEXTURE_WRAP_T:
2618 *params = texture->getWrapT();
2619 break;
2620 default:
2621 return error(GL_INVALID_ENUM);
2622 }
2623 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002624 }
2625 catch(std::bad_alloc&)
2626 {
2627 return error(GL_OUT_OF_MEMORY);
2628 }
2629}
2630
2631void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2632{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002633 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002634
2635 try
2636 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002637 gl::Context *context = gl::getContext();
2638
2639 if (context)
2640 {
2641 if (program == 0)
2642 {
2643 return error(GL_INVALID_VALUE);
2644 }
2645
2646 gl::Program *programObject = context->getProgram(program);
2647
2648 if (!programObject || !programObject->isLinked())
2649 {
2650 return error(GL_INVALID_OPERATION);
2651 }
2652
2653 if (!programObject->getUniformfv(location, params))
2654 {
2655 return error(GL_INVALID_OPERATION);
2656 }
2657 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002658 }
2659 catch(std::bad_alloc&)
2660 {
2661 return error(GL_OUT_OF_MEMORY);
2662 }
2663}
2664
2665void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2666{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002667 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002668
2669 try
2670 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002671 gl::Context *context = gl::getContext();
2672
2673 if (context)
2674 {
2675 if (program == 0)
2676 {
2677 return error(GL_INVALID_VALUE);
2678 }
2679
2680 gl::Program *programObject = context->getProgram(program);
2681
2682 if (!programObject || !programObject->isLinked())
2683 {
2684 return error(GL_INVALID_OPERATION);
2685 }
2686
2687 if (!programObject)
2688 {
2689 return error(GL_INVALID_OPERATION);
2690 }
2691
2692 if (!programObject->getUniformiv(location, params))
2693 {
2694 return error(GL_INVALID_OPERATION);
2695 }
2696 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002697 }
2698 catch(std::bad_alloc&)
2699 {
2700 return error(GL_OUT_OF_MEMORY);
2701 }
2702}
2703
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002704int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002705{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002706 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002707
2708 try
2709 {
2710 gl::Context *context = gl::getContext();
2711
2712 if (strstr(name, "gl_") == name)
2713 {
2714 return -1;
2715 }
2716
2717 if (context)
2718 {
2719 gl::Program *programObject = context->getProgram(program);
2720
2721 if (!programObject)
2722 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002723 if (context->getShader(program))
2724 {
2725 return error(GL_INVALID_OPERATION, -1);
2726 }
2727 else
2728 {
2729 return error(GL_INVALID_VALUE, -1);
2730 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002731 }
2732
2733 if (!programObject->isLinked())
2734 {
2735 return error(GL_INVALID_OPERATION, -1);
2736 }
2737
2738 return programObject->getUniformLocation(name);
2739 }
2740 }
2741 catch(std::bad_alloc&)
2742 {
2743 return error(GL_OUT_OF_MEMORY, -1);
2744 }
2745
2746 return -1;
2747}
2748
2749void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2750{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002751 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002752
2753 try
2754 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002755 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002756
daniel@transgaming.come0078962010-04-15 20:45:08 +00002757 if (context)
2758 {
2759 if (index >= gl::MAX_VERTEX_ATTRIBS)
2760 {
2761 return error(GL_INVALID_VALUE);
2762 }
2763
2764 switch (pname)
2765 {
2766 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2767 *params = (GLfloat)(context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2768 break;
2769 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2770 *params = (GLfloat)context->vertexAttribute[index].mSize;
2771 break;
2772 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2773 *params = (GLfloat)context->vertexAttribute[index].mStride;
2774 break;
2775 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2776 *params = (GLfloat)context->vertexAttribute[index].mType;
2777 break;
2778 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2779 *params = (GLfloat)(context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2780 break;
2781 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2782 *params = (GLfloat)context->vertexAttribute[index].mBoundBuffer;
2783 break;
2784 case GL_CURRENT_VERTEX_ATTRIB:
2785 for (int i = 0; i < 4; ++i)
2786 {
2787 params[i] = context->vertexAttribute[index].mCurrentValue[i];
2788 }
2789 break;
2790 default: return error(GL_INVALID_ENUM);
2791 }
2792 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002793 }
2794 catch(std::bad_alloc&)
2795 {
2796 return error(GL_OUT_OF_MEMORY);
2797 }
2798}
2799
2800void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2801{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002802 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002803
2804 try
2805 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002806 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002807
daniel@transgaming.come0078962010-04-15 20:45:08 +00002808 if (context)
2809 {
2810 if (index >= gl::MAX_VERTEX_ATTRIBS)
2811 {
2812 return error(GL_INVALID_VALUE);
2813 }
2814
2815 switch (pname)
2816 {
2817 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2818 *params = (context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2819 break;
2820 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2821 *params = context->vertexAttribute[index].mSize;
2822 break;
2823 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2824 *params = context->vertexAttribute[index].mStride;
2825 break;
2826 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2827 *params = context->vertexAttribute[index].mType;
2828 break;
2829 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2830 *params = (context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2831 break;
2832 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2833 *params = context->vertexAttribute[index].mBoundBuffer;
2834 break;
2835 case GL_CURRENT_VERTEX_ATTRIB:
2836 for (int i = 0; i < 4; ++i)
2837 {
2838 float currentValue = context->vertexAttribute[index].mCurrentValue[i];
2839 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
2840 }
2841 break;
2842 default: return error(GL_INVALID_ENUM);
2843 }
2844 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002845 }
2846 catch(std::bad_alloc&)
2847 {
2848 return error(GL_OUT_OF_MEMORY);
2849 }
2850}
2851
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002852void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002853{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002854 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002855
2856 try
2857 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002858 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002859
daniel@transgaming.come0078962010-04-15 20:45:08 +00002860 if (context)
2861 {
2862 if (index >= gl::MAX_VERTEX_ATTRIBS)
2863 {
2864 return error(GL_INVALID_VALUE);
2865 }
2866
2867 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
2868 {
2869 return error(GL_INVALID_ENUM);
2870 }
2871
2872 *pointer = const_cast<GLvoid*>(context->vertexAttribute[index].mPointer);
2873 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002874 }
2875 catch(std::bad_alloc&)
2876 {
2877 return error(GL_OUT_OF_MEMORY);
2878 }
2879}
2880
2881void __stdcall glHint(GLenum target, GLenum mode)
2882{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002883 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002884
2885 try
2886 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002887 switch (target)
2888 {
2889 case GL_GENERATE_MIPMAP_HINT:
2890 switch (mode)
2891 {
2892 case GL_FASTEST:
2893 case GL_NICEST:
2894 case GL_DONT_CARE:
2895 break;
2896 default:
2897 return error(GL_INVALID_ENUM);
2898 }
2899 break;
2900 default:
2901 return error(GL_INVALID_ENUM);
2902 }
2903
2904 gl::Context *context = gl::getContext();
2905 if (context)
2906 {
2907 if (target == GL_GENERATE_MIPMAP_HINT)
2908 context->generateMipmapHint = mode;
2909 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002910 }
2911 catch(std::bad_alloc&)
2912 {
2913 return error(GL_OUT_OF_MEMORY);
2914 }
2915}
2916
2917GLboolean __stdcall glIsBuffer(GLuint buffer)
2918{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002919 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002920
2921 try
2922 {
2923 gl::Context *context = gl::getContext();
2924
2925 if (context && buffer)
2926 {
2927 gl::Buffer *bufferObject = context->getBuffer(buffer);
2928
2929 if (bufferObject)
2930 {
2931 return GL_TRUE;
2932 }
2933 }
2934 }
2935 catch(std::bad_alloc&)
2936 {
2937 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2938 }
2939
2940 return GL_FALSE;
2941}
2942
2943GLboolean __stdcall glIsEnabled(GLenum cap)
2944{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002945 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002946
2947 try
2948 {
2949 gl::Context *context = gl::getContext();
2950
2951 if (context)
2952 {
2953 switch (cap)
2954 {
2955 case GL_CULL_FACE: return context->cullFace;
2956 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
2957 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
2958 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
2959 case GL_SCISSOR_TEST: return context->scissorTest;
2960 case GL_STENCIL_TEST: return context->stencilTest;
2961 case GL_DEPTH_TEST: return context->depthTest;
2962 case GL_BLEND: return context->blend;
2963 case GL_DITHER: return context->dither;
2964 default:
2965 return error(GL_INVALID_ENUM, false);
2966 }
2967 }
2968 }
2969 catch(std::bad_alloc&)
2970 {
2971 return error(GL_OUT_OF_MEMORY, false);
2972 }
2973
2974 return false;
2975}
2976
2977GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
2978{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002979 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002980
2981 try
2982 {
2983 gl::Context *context = gl::getContext();
2984
2985 if (context && framebuffer)
2986 {
2987 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2988
2989 if (framebufferObject)
2990 {
2991 return GL_TRUE;
2992 }
2993 }
2994 }
2995 catch(std::bad_alloc&)
2996 {
2997 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2998 }
2999
3000 return GL_FALSE;
3001}
3002
3003GLboolean __stdcall glIsProgram(GLuint program)
3004{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003005 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003006
3007 try
3008 {
3009 gl::Context *context = gl::getContext();
3010
3011 if (context && program)
3012 {
3013 gl::Program *programObject = context->getProgram(program);
3014
3015 if (programObject)
3016 {
3017 return GL_TRUE;
3018 }
3019 }
3020 }
3021 catch(std::bad_alloc&)
3022 {
3023 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3024 }
3025
3026 return GL_FALSE;
3027}
3028
3029GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3030{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003031 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003032
3033 try
3034 {
3035 gl::Context *context = gl::getContext();
3036
3037 if (context && renderbuffer)
3038 {
3039 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3040
3041 if (renderbufferObject)
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 glIsShader(GLuint shader)
3056{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003057 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003058
3059 try
3060 {
3061 gl::Context *context = gl::getContext();
3062
3063 if (context && shader)
3064 {
3065 gl::Shader *shaderObject = context->getShader(shader);
3066
3067 if (shaderObject)
3068 {
3069 return GL_TRUE;
3070 }
3071 }
3072 }
3073 catch(std::bad_alloc&)
3074 {
3075 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3076 }
3077
3078 return GL_FALSE;
3079}
3080
3081GLboolean __stdcall glIsTexture(GLuint texture)
3082{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003083 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003084
3085 try
3086 {
3087 gl::Context *context = gl::getContext();
3088
3089 if (context && texture)
3090 {
3091 gl::Texture *textureObject = context->getTexture(texture);
3092
3093 if (textureObject)
3094 {
3095 return GL_TRUE;
3096 }
3097 }
3098 }
3099 catch(std::bad_alloc&)
3100 {
3101 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3102 }
3103
3104 return GL_FALSE;
3105}
3106
3107void __stdcall glLineWidth(GLfloat width)
3108{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003109 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003110
3111 try
3112 {
3113 if (width <= 0.0f)
3114 {
3115 return error(GL_INVALID_VALUE);
3116 }
3117
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003118 gl::Context *context = gl::getContext();
3119
3120 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003121 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003122 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003123 }
3124 }
3125 catch(std::bad_alloc&)
3126 {
3127 return error(GL_OUT_OF_MEMORY);
3128 }
3129}
3130
3131void __stdcall glLinkProgram(GLuint program)
3132{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003133 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003134
3135 try
3136 {
3137 gl::Context *context = gl::getContext();
3138
3139 if (context)
3140 {
3141 gl::Program *programObject = context->getProgram(program);
3142
3143 if (!programObject)
3144 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003145 if (context->getShader(program))
3146 {
3147 return error(GL_INVALID_OPERATION);
3148 }
3149 else
3150 {
3151 return error(GL_INVALID_VALUE);
3152 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003153 }
3154
3155 programObject->link();
3156 }
3157 }
3158 catch(std::bad_alloc&)
3159 {
3160 return error(GL_OUT_OF_MEMORY);
3161 }
3162}
3163
3164void __stdcall glPixelStorei(GLenum pname, GLint param)
3165{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003166 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003167
3168 try
3169 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003170 gl::Context *context = gl::getContext();
3171
3172 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003173 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003174 switch (pname)
3175 {
3176 case GL_UNPACK_ALIGNMENT:
3177 if (param != 1 && param != 2 && param != 4 && param != 8)
3178 {
3179 return error(GL_INVALID_VALUE);
3180 }
3181
3182 context->unpackAlignment = param;
3183 break;
3184
3185 case GL_PACK_ALIGNMENT:
3186 if (param != 1 && param != 2 && param != 4 && param != 8)
3187 {
3188 return error(GL_INVALID_VALUE);
3189 }
3190
3191 context->packAlignment = param;
3192 break;
3193
3194 default:
3195 return error(GL_INVALID_ENUM);
3196 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003197 }
3198 }
3199 catch(std::bad_alloc&)
3200 {
3201 return error(GL_OUT_OF_MEMORY);
3202 }
3203}
3204
3205void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3206{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003207 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003208
3209 try
3210 {
3211 if (factor != 0.0f || units != 0.0f)
3212 {
3213 UNIMPLEMENTED(); // FIXME
3214 }
3215 }
3216 catch(std::bad_alloc&)
3217 {
3218 return error(GL_OUT_OF_MEMORY);
3219 }
3220}
3221
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003222void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003223{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003224 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003225 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003226 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003227
3228 try
3229 {
3230 if (width < 0 || height < 0)
3231 {
3232 return error(GL_INVALID_VALUE);
3233 }
3234
3235 switch (format)
3236 {
3237 case GL_RGBA:
3238 switch (type)
3239 {
3240 case GL_UNSIGNED_BYTE:
3241 break;
3242 default:
3243 return error(GL_INVALID_OPERATION);
3244 }
3245 break;
3246 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3247 switch (type)
3248 {
3249 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3250 break;
3251 default:
3252 return error(GL_INVALID_OPERATION);
3253 }
3254 break;
3255 default:
3256 return error(GL_INVALID_OPERATION);
3257 }
3258
3259 gl::Context *context = gl::getContext();
3260
3261 if (context)
3262 {
3263 context->readPixels(x, y, width, height, format, type, pixels);
3264 }
3265 }
3266 catch(std::bad_alloc&)
3267 {
3268 return error(GL_OUT_OF_MEMORY);
3269 }
3270}
3271
3272void __stdcall glReleaseShaderCompiler(void)
3273{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003274 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003275
3276 try
3277 {
3278 gl::Shader::releaseCompiler();
3279 }
3280 catch(std::bad_alloc&)
3281 {
3282 return error(GL_OUT_OF_MEMORY);
3283 }
3284}
3285
3286void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3287{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003288 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3289 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003290
3291 try
3292 {
3293 switch (target)
3294 {
3295 case GL_RENDERBUFFER:
3296 break;
3297 default:
3298 return error(GL_INVALID_ENUM);
3299 }
3300
3301 switch (internalformat)
3302 {
3303 case GL_DEPTH_COMPONENT16:
3304 case GL_RGBA4:
3305 case GL_RGB5_A1:
3306 case GL_RGB565:
3307 case GL_STENCIL_INDEX8:
3308 break;
3309 default:
3310 return error(GL_INVALID_ENUM);
3311 }
3312
3313 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3314 {
3315 return error(GL_INVALID_VALUE);
3316 }
3317
3318 gl::Context *context = gl::getContext();
3319
3320 if (context)
3321 {
3322 if (context->framebuffer == 0 || context->renderbuffer == 0)
3323 {
3324 return error(GL_INVALID_OPERATION);
3325 }
3326
3327 switch (internalformat)
3328 {
3329 case GL_DEPTH_COMPONENT16:
3330 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3331 break;
3332 case GL_RGBA4:
3333 case GL_RGB5_A1:
3334 case GL_RGB565:
3335 UNIMPLEMENTED(); // FIXME
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003336 // context->setRenderbuffer(new Colorbuffer(renderTarget));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003337 break;
3338 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003339 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003340 break;
3341 default:
3342 return error(GL_INVALID_ENUM);
3343 }
3344 }
3345 }
3346 catch(std::bad_alloc&)
3347 {
3348 return error(GL_OUT_OF_MEMORY);
3349 }
3350}
3351
3352void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3353{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003354 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003355
3356 try
3357 {
3358 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003359
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003360 if (context)
3361 {
3362 context->sampleCoverageValue = gl::clamp01(value);
3363 context->sampleCoverageInvert = invert;
3364 }
3365 }
3366 catch(std::bad_alloc&)
3367 {
3368 return error(GL_OUT_OF_MEMORY);
3369 }
3370}
3371
3372void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3373{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003374 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 +00003375
3376 try
3377 {
3378 if (width < 0 || height < 0)
3379 {
3380 return error(GL_INVALID_VALUE);
3381 }
3382
3383 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003384
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003385 if (context)
3386 {
3387 context->scissorX = x;
3388 context->scissorY = y;
3389 context->scissorWidth = width;
3390 context->scissorHeight = height;
3391 }
3392 }
3393 catch(std::bad_alloc&)
3394 {
3395 return error(GL_OUT_OF_MEMORY);
3396 }
3397}
3398
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003399void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003400{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003401 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003402 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003403 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003404
3405 try
3406 {
3407 if (n < 0 || length < 0)
3408 {
3409 return error(GL_INVALID_VALUE);
3410 }
3411
3412 UNIMPLEMENTED(); // FIXME
3413 }
3414 catch(std::bad_alloc&)
3415 {
3416 return error(GL_OUT_OF_MEMORY);
3417 }
3418}
3419
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003420void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003421{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003422 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 +00003423 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003424
3425 try
3426 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003427 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003428 {
3429 return error(GL_INVALID_VALUE);
3430 }
3431
3432 gl::Context *context = gl::getContext();
3433
3434 if (context)
3435 {
3436 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003437
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003438 if (!shaderObject)
3439 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003440 if (context->getProgram(shader))
3441 {
3442 return error(GL_INVALID_OPERATION);
3443 }
3444 else
3445 {
3446 return error(GL_INVALID_VALUE);
3447 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003448 }
3449
3450 shaderObject->setSource(count, string, length);
3451 }
3452 }
3453 catch(std::bad_alloc&)
3454 {
3455 return error(GL_OUT_OF_MEMORY);
3456 }
3457}
3458
3459void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3460{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003461 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003462}
3463
3464void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3465{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003466 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 +00003467
3468 try
3469 {
3470 switch (face)
3471 {
3472 case GL_FRONT:
3473 case GL_BACK:
3474 case GL_FRONT_AND_BACK:
3475 break;
3476 default:
3477 return error(GL_INVALID_ENUM);
3478 }
3479
3480 switch (func)
3481 {
3482 case GL_NEVER:
3483 case GL_ALWAYS:
3484 case GL_LESS:
3485 case GL_LEQUAL:
3486 case GL_EQUAL:
3487 case GL_GEQUAL:
3488 case GL_GREATER:
3489 case GL_NOTEQUAL:
3490 break;
3491 default:
3492 return error(GL_INVALID_ENUM);
3493 }
3494
3495 gl::Context *context = gl::getContext();
3496
3497 if (context)
3498 {
3499 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3500 {
3501 context->stencilFunc = func;
3502 context->stencilRef = ref;
3503 context->stencilMask = mask;
3504 }
3505
3506 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3507 {
3508 context->stencilBackFunc = func;
3509 context->stencilBackRef = ref;
3510 context->stencilBackMask = mask;
3511 }
3512 }
3513 }
3514 catch(std::bad_alloc&)
3515 {
3516 return error(GL_OUT_OF_MEMORY);
3517 }
3518}
3519
3520void __stdcall glStencilMask(GLuint mask)
3521{
3522 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3523}
3524
3525void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3526{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003527 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003528
3529 try
3530 {
3531 switch (face)
3532 {
3533 case GL_FRONT:
3534 case GL_BACK:
3535 case GL_FRONT_AND_BACK:
3536 break;
3537 default:
3538 return error(GL_INVALID_ENUM);
3539 }
3540
3541 gl::Context *context = gl::getContext();
3542
3543 if (context)
3544 {
3545 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3546 {
3547 context->stencilWritemask = mask;
3548 }
3549
3550 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3551 {
3552 context->stencilBackWritemask = mask;
3553 }
3554 }
3555 }
3556 catch(std::bad_alloc&)
3557 {
3558 return error(GL_OUT_OF_MEMORY);
3559 }
3560}
3561
3562void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3563{
3564 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3565}
3566
3567void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3568{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003569 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3570 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003571
3572 try
3573 {
3574 switch (face)
3575 {
3576 case GL_FRONT:
3577 case GL_BACK:
3578 case GL_FRONT_AND_BACK:
3579 break;
3580 default:
3581 return error(GL_INVALID_ENUM);
3582 }
3583
3584 switch (fail)
3585 {
3586 case GL_ZERO:
3587 case GL_KEEP:
3588 case GL_REPLACE:
3589 case GL_INCR:
3590 case GL_DECR:
3591 case GL_INVERT:
3592 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003593 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003594 break;
3595 default:
3596 return error(GL_INVALID_ENUM);
3597 }
3598
3599 switch (zfail)
3600 {
3601 case GL_ZERO:
3602 case GL_KEEP:
3603 case GL_REPLACE:
3604 case GL_INCR:
3605 case GL_DECR:
3606 case GL_INVERT:
3607 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003608 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003609 break;
3610 default:
3611 return error(GL_INVALID_ENUM);
3612 }
3613
3614 switch (zpass)
3615 {
3616 case GL_ZERO:
3617 case GL_KEEP:
3618 case GL_REPLACE:
3619 case GL_INCR:
3620 case GL_DECR:
3621 case GL_INVERT:
3622 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003623 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003624 break;
3625 default:
3626 return error(GL_INVALID_ENUM);
3627 }
3628
3629 gl::Context *context = gl::getContext();
3630
3631 if (context)
3632 {
3633 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3634 {
3635 context->stencilFail = fail;
3636 context->stencilPassDepthFail = zfail;
3637 context->stencilPassDepthPass = zpass;
3638 }
3639
3640 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3641 {
3642 context->stencilBackFail = fail;
3643 context->stencilBackPassDepthFail = zfail;
3644 context->stencilBackPassDepthPass = zpass;
3645 }
3646 }
3647 }
3648 catch(std::bad_alloc&)
3649 {
3650 return error(GL_OUT_OF_MEMORY);
3651 }
3652}
3653
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003654void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3655 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003656{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003657 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 +00003658 "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 +00003659 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003660
3661 try
3662 {
3663 if (level < 0 || width < 0 || height < 0)
3664 {
3665 return error(GL_INVALID_VALUE);
3666 }
3667
3668 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3669 {
3670 return error(GL_INVALID_VALUE);
3671 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003672
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003673 switch (target)
3674 {
3675 case GL_TEXTURE_2D:
3676 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3677 {
3678 return error(GL_INVALID_VALUE);
3679 }
3680 break;
3681 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3682 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3683 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3684 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3685 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3686 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003687 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003688 {
3689 return error(GL_INVALID_VALUE);
3690 }
3691
3692 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3693 {
3694 return error(GL_INVALID_VALUE);
3695 }
3696 break;
3697 default:
3698 return error(GL_INVALID_ENUM);
3699 }
3700
3701 if (internalformat != format)
3702 {
3703 return error(GL_INVALID_OPERATION);
3704 }
3705
3706 switch (internalformat)
3707 {
3708 case GL_ALPHA:
3709 case GL_LUMINANCE:
3710 case GL_LUMINANCE_ALPHA:
3711 switch (type)
3712 {
3713 case GL_UNSIGNED_BYTE:
3714 break;
3715 default:
3716 return error(GL_INVALID_ENUM);
3717 }
3718 break;
3719 case GL_RGB:
3720 switch (type)
3721 {
3722 case GL_UNSIGNED_BYTE:
3723 case GL_UNSIGNED_SHORT_5_6_5:
3724 break;
3725 default:
3726 return error(GL_INVALID_ENUM);
3727 }
3728 break;
3729 case GL_RGBA:
3730 switch (type)
3731 {
3732 case GL_UNSIGNED_BYTE:
3733 case GL_UNSIGNED_SHORT_4_4_4_4:
3734 case GL_UNSIGNED_SHORT_5_5_5_1:
3735 break;
3736 default:
3737 return error(GL_INVALID_ENUM);
3738 }
3739 break;
3740 default:
3741 return error(GL_INVALID_VALUE);
3742 }
3743
3744 if (border != 0)
3745 {
3746 return error(GL_INVALID_VALUE);
3747 }
3748
3749 gl::Context *context = gl::getContext();
3750
3751 if (context)
3752 {
3753 if (target == GL_TEXTURE_2D)
3754 {
3755 gl::Texture2D *texture = context->getTexture2D();
3756
3757 if (!texture)
3758 {
3759 return error(GL_INVALID_OPERATION);
3760 }
3761
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003762 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003763 }
3764 else
3765 {
3766 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3767
3768 if (!texture)
3769 {
3770 return error(GL_INVALID_OPERATION);
3771 }
3772
3773 switch (target)
3774 {
3775 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003776 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003777 break;
3778 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003779 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003780 break;
3781 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003782 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003783 break;
3784 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003785 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003786 break;
3787 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003788 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003789 break;
3790 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003791 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003792 break;
3793 default: UNREACHABLE();
3794 }
3795 }
3796 }
3797 }
3798 catch(std::bad_alloc&)
3799 {
3800 return error(GL_OUT_OF_MEMORY);
3801 }
3802}
3803
3804void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3805{
3806 glTexParameteri(target, pname, (GLint)param);
3807}
3808
3809void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3810{
3811 glTexParameteri(target, pname, (GLint)*params);
3812}
3813
3814void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3815{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003816 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003817
3818 try
3819 {
3820 gl::Context *context = gl::getContext();
3821
3822 if (context)
3823 {
3824 gl::Texture *texture;
3825
3826 switch (target)
3827 {
3828 case GL_TEXTURE_2D:
3829 texture = context->getTexture2D();
3830 break;
3831 case GL_TEXTURE_CUBE_MAP:
3832 texture = context->getTextureCubeMap();
3833 break;
3834 default:
3835 return error(GL_INVALID_ENUM);
3836 }
3837
3838 switch (pname)
3839 {
3840 case GL_TEXTURE_WRAP_S:
3841 if (!texture->setWrapS((GLenum)param))
3842 {
3843 return error(GL_INVALID_ENUM);
3844 }
3845 break;
3846 case GL_TEXTURE_WRAP_T:
3847 if (!texture->setWrapT((GLenum)param))
3848 {
3849 return error(GL_INVALID_ENUM);
3850 }
3851 break;
3852 case GL_TEXTURE_MIN_FILTER:
3853 if (!texture->setMinFilter((GLenum)param))
3854 {
3855 return error(GL_INVALID_ENUM);
3856 }
3857 break;
3858 case GL_TEXTURE_MAG_FILTER:
3859 if (!texture->setMagFilter((GLenum)param))
3860 {
3861 return error(GL_INVALID_ENUM);
3862 }
3863 break;
3864 default:
3865 return error(GL_INVALID_ENUM);
3866 }
3867 }
3868 }
3869 catch(std::bad_alloc&)
3870 {
3871 return error(GL_OUT_OF_MEMORY);
3872 }
3873}
3874
3875void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3876{
3877 glTexParameteri(target, pname, *params);
3878}
3879
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003880void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3881 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003882{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003883 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3884 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003885 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003886 target, level, xoffset, yoffset, width, height, format, type, pixels);
3887
3888 try
3889 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003890 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
3891 {
3892 return error(GL_INVALID_ENUM);
3893 }
3894
3895 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003896 {
3897 return error(GL_INVALID_VALUE);
3898 }
3899
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003900 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
3901 {
3902 return error(GL_INVALID_VALUE);
3903 }
3904
3905 if (!es2dx::CheckTextureFormatType(format, type))
3906 {
3907 return error(GL_INVALID_ENUM);
3908 }
3909
3910 if (width == 0 || height == 0 || pixels == NULL)
3911 {
3912 return;
3913 }
3914
3915 gl::Context *context = gl::getContext();
3916
3917 if (context)
3918 {
3919 if (target == GL_TEXTURE_2D)
3920 {
3921 gl::Texture2D *texture = context->getTexture2D();
3922
3923 if (!texture)
3924 {
3925 return error(GL_INVALID_OPERATION);
3926 }
3927
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003928 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003929 }
3930 else if (es2dx::IsCubemapTextureTarget(target))
3931 {
3932 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3933
3934 if (!texture)
3935 {
3936 return error(GL_INVALID_OPERATION);
3937 }
3938
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003939 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003940 }
3941 else
3942 {
3943 UNREACHABLE();
3944 }
3945 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003946 }
3947 catch(std::bad_alloc&)
3948 {
3949 return error(GL_OUT_OF_MEMORY);
3950 }
3951}
3952
3953void __stdcall glUniform1f(GLint location, GLfloat x)
3954{
3955 glUniform1fv(location, 1, &x);
3956}
3957
3958void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
3959{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003960 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003961
3962 try
3963 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003964 if (count < 0)
3965 {
3966 return error(GL_INVALID_VALUE);
3967 }
3968
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003969 if (location == -1)
3970 {
3971 return;
3972 }
3973
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003974 gl::Context *context = gl::getContext();
3975
3976 if (context)
3977 {
3978 gl::Program *program = context->getCurrentProgram();
3979
3980 if (!program)
3981 {
3982 return error(GL_INVALID_OPERATION);
3983 }
3984
3985 if (!program->setUniform1fv(location, count, v))
3986 {
3987 return error(GL_INVALID_OPERATION);
3988 }
3989 }
3990 }
3991 catch(std::bad_alloc&)
3992 {
3993 return error(GL_OUT_OF_MEMORY);
3994 }
3995}
3996
3997void __stdcall glUniform1i(GLint location, GLint x)
3998{
3999 glUniform1iv(location, 1, &x);
4000}
4001
4002void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4003{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004004 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004005
4006 try
4007 {
4008 if (count < 0)
4009 {
4010 return error(GL_INVALID_VALUE);
4011 }
4012
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004013 if (location == -1)
4014 {
4015 return;
4016 }
4017
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004018 gl::Context *context = gl::getContext();
4019
4020 if (context)
4021 {
4022 gl::Program *program = context->getCurrentProgram();
4023
4024 if (!program)
4025 {
4026 return error(GL_INVALID_OPERATION);
4027 }
4028
4029 if (!program->setUniform1iv(location, count, v))
4030 {
4031 return error(GL_INVALID_OPERATION);
4032 }
4033 }
4034 }
4035 catch(std::bad_alloc&)
4036 {
4037 return error(GL_OUT_OF_MEMORY);
4038 }
4039}
4040
4041void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4042{
4043 GLfloat xy[2] = {x, y};
4044
4045 glUniform2fv(location, 1, (GLfloat*)&xy);
4046}
4047
4048void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4049{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004050 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004051
4052 try
4053 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004054 if (count < 0)
4055 {
4056 return error(GL_INVALID_VALUE);
4057 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004058
4059 if (location == -1)
4060 {
4061 return;
4062 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004063
4064 gl::Context *context = gl::getContext();
4065
4066 if (context)
4067 {
4068 gl::Program *program = context->getCurrentProgram();
4069
4070 if (!program)
4071 {
4072 return error(GL_INVALID_OPERATION);
4073 }
4074
4075 if (!program->setUniform2fv(location, count, v))
4076 {
4077 return error(GL_INVALID_OPERATION);
4078 }
4079 }
4080 }
4081 catch(std::bad_alloc&)
4082 {
4083 return error(GL_OUT_OF_MEMORY);
4084 }
4085}
4086
4087void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4088{
4089 GLint xy[4] = {x, y};
4090
4091 glUniform2iv(location, 1, (GLint*)&xy);
4092}
4093
4094void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4095{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004096 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004097
4098 try
4099 {
4100 if (count < 0)
4101 {
4102 return error(GL_INVALID_VALUE);
4103 }
4104
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004105 if (location == -1)
4106 {
4107 return;
4108 }
4109
4110 gl::Context *context = gl::getContext();
4111
4112 if (context)
4113 {
4114 gl::Program *program = context->getCurrentProgram();
4115
4116 if (!program)
4117 {
4118 return error(GL_INVALID_OPERATION);
4119 }
4120
4121 if (!program->setUniform2iv(location, count, v))
4122 {
4123 return error(GL_INVALID_OPERATION);
4124 }
4125 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004126 }
4127 catch(std::bad_alloc&)
4128 {
4129 return error(GL_OUT_OF_MEMORY);
4130 }
4131}
4132
4133void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4134{
4135 GLfloat xyz[3] = {x, y, z};
4136
4137 glUniform3fv(location, 1, (GLfloat*)&xyz);
4138}
4139
4140void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4141{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004142 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004143
4144 try
4145 {
4146 if (count < 0)
4147 {
4148 return error(GL_INVALID_VALUE);
4149 }
4150
4151 if (location == -1)
4152 {
4153 return;
4154 }
4155
4156 gl::Context *context = gl::getContext();
4157
4158 if (context)
4159 {
4160 gl::Program *program = context->getCurrentProgram();
4161
4162 if (!program)
4163 {
4164 return error(GL_INVALID_OPERATION);
4165 }
4166
4167 if (!program->setUniform3fv(location, count, v))
4168 {
4169 return error(GL_INVALID_OPERATION);
4170 }
4171 }
4172 }
4173 catch(std::bad_alloc&)
4174 {
4175 return error(GL_OUT_OF_MEMORY);
4176 }
4177}
4178
4179void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4180{
4181 GLint xyz[3] = {x, y, z};
4182
4183 glUniform3iv(location, 1, (GLint*)&xyz);
4184}
4185
4186void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4187{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004188 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004189
4190 try
4191 {
4192 if (count < 0)
4193 {
4194 return error(GL_INVALID_VALUE);
4195 }
4196
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004197 if (location == -1)
4198 {
4199 return;
4200 }
4201
4202 gl::Context *context = gl::getContext();
4203
4204 if (context)
4205 {
4206 gl::Program *program = context->getCurrentProgram();
4207
4208 if (!program)
4209 {
4210 return error(GL_INVALID_OPERATION);
4211 }
4212
4213 if (!program->setUniform3iv(location, count, v))
4214 {
4215 return error(GL_INVALID_OPERATION);
4216 }
4217 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004218 }
4219 catch(std::bad_alloc&)
4220 {
4221 return error(GL_OUT_OF_MEMORY);
4222 }
4223}
4224
4225void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4226{
4227 GLfloat xyzw[4] = {x, y, z, w};
4228
4229 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4230}
4231
4232void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4233{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004234 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004235
4236 try
4237 {
4238 if (count < 0)
4239 {
4240 return error(GL_INVALID_VALUE);
4241 }
4242
4243 if (location == -1)
4244 {
4245 return;
4246 }
4247
4248 gl::Context *context = gl::getContext();
4249
4250 if (context)
4251 {
4252 gl::Program *program = context->getCurrentProgram();
4253
4254 if (!program)
4255 {
4256 return error(GL_INVALID_OPERATION);
4257 }
4258
4259 if (!program->setUniform4fv(location, count, v))
4260 {
4261 return error(GL_INVALID_OPERATION);
4262 }
4263 }
4264 }
4265 catch(std::bad_alloc&)
4266 {
4267 return error(GL_OUT_OF_MEMORY);
4268 }
4269}
4270
4271void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4272{
4273 GLint xyzw[4] = {x, y, z, w};
4274
4275 glUniform4iv(location, 1, (GLint*)&xyzw);
4276}
4277
4278void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4279{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004280 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004281
4282 try
4283 {
4284 if (count < 0)
4285 {
4286 return error(GL_INVALID_VALUE);
4287 }
4288
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004289 if (location == -1)
4290 {
4291 return;
4292 }
4293
4294 gl::Context *context = gl::getContext();
4295
4296 if (context)
4297 {
4298 gl::Program *program = context->getCurrentProgram();
4299
4300 if (!program)
4301 {
4302 return error(GL_INVALID_OPERATION);
4303 }
4304
4305 if (!program->setUniform4iv(location, count, v))
4306 {
4307 return error(GL_INVALID_OPERATION);
4308 }
4309 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004310 }
4311 catch(std::bad_alloc&)
4312 {
4313 return error(GL_OUT_OF_MEMORY);
4314 }
4315}
4316
4317void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4318{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004319 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4320 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004321
4322 try
4323 {
4324 if (count < 0 || transpose != GL_FALSE)
4325 {
4326 return error(GL_INVALID_VALUE);
4327 }
4328
4329 if (location == -1)
4330 {
4331 return;
4332 }
4333
4334 gl::Context *context = gl::getContext();
4335
4336 if (context)
4337 {
4338 gl::Program *program = context->getCurrentProgram();
4339
4340 if (!program)
4341 {
4342 return error(GL_INVALID_OPERATION);
4343 }
4344
4345 if (!program->setUniformMatrix2fv(location, count, value))
4346 {
4347 return error(GL_INVALID_OPERATION);
4348 }
4349 }
4350 }
4351 catch(std::bad_alloc&)
4352 {
4353 return error(GL_OUT_OF_MEMORY);
4354 }
4355}
4356
4357void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4358{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004359 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4360 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004361
4362 try
4363 {
4364 if (count < 0 || transpose != GL_FALSE)
4365 {
4366 return error(GL_INVALID_VALUE);
4367 }
4368
4369 if (location == -1)
4370 {
4371 return;
4372 }
4373
4374 gl::Context *context = gl::getContext();
4375
4376 if (context)
4377 {
4378 gl::Program *program = context->getCurrentProgram();
4379
4380 if (!program)
4381 {
4382 return error(GL_INVALID_OPERATION);
4383 }
4384
4385 if (!program->setUniformMatrix3fv(location, count, value))
4386 {
4387 return error(GL_INVALID_OPERATION);
4388 }
4389 }
4390 }
4391 catch(std::bad_alloc&)
4392 {
4393 return error(GL_OUT_OF_MEMORY);
4394 }
4395}
4396
4397void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4398{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004399 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4400 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004401
4402 try
4403 {
4404 if (count < 0 || transpose != GL_FALSE)
4405 {
4406 return error(GL_INVALID_VALUE);
4407 }
4408
4409 if (location == -1)
4410 {
4411 return;
4412 }
4413
4414 gl::Context *context = gl::getContext();
4415
4416 if (context)
4417 {
4418 gl::Program *program = context->getCurrentProgram();
4419
4420 if (!program)
4421 {
4422 return error(GL_INVALID_OPERATION);
4423 }
4424
4425 if (!program->setUniformMatrix4fv(location, count, value))
4426 {
4427 return error(GL_INVALID_OPERATION);
4428 }
4429 }
4430 }
4431 catch(std::bad_alloc&)
4432 {
4433 return error(GL_OUT_OF_MEMORY);
4434 }
4435}
4436
4437void __stdcall glUseProgram(GLuint program)
4438{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004439 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004440
4441 try
4442 {
4443 gl::Context *context = gl::getContext();
4444
4445 if (context)
4446 {
4447 gl::Program *programObject = context->getProgram(program);
4448
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004449 if (!programObject && program != 0)
4450 {
4451 if (context->getShader(program))
4452 {
4453 return error(GL_INVALID_OPERATION);
4454 }
4455 else
4456 {
4457 return error(GL_INVALID_VALUE);
4458 }
4459 }
4460
4461 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004462 {
4463 return error(GL_INVALID_OPERATION);
4464 }
4465
4466 context->useProgram(program);
4467 }
4468 }
4469 catch(std::bad_alloc&)
4470 {
4471 return error(GL_OUT_OF_MEMORY);
4472 }
4473}
4474
4475void __stdcall glValidateProgram(GLuint program)
4476{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004477 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004478
4479 try
4480 {
4481 UNIMPLEMENTED(); // FIXME
4482 }
4483 catch(std::bad_alloc&)
4484 {
4485 return error(GL_OUT_OF_MEMORY);
4486 }
4487}
4488
4489void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4490{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004491 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004492
4493 try
4494 {
4495 if (index >= gl::MAX_VERTEX_ATTRIBS)
4496 {
4497 return error(GL_INVALID_VALUE);
4498 }
4499
4500 UNIMPLEMENTED(); // FIXME
4501 }
4502 catch(std::bad_alloc&)
4503 {
4504 return error(GL_OUT_OF_MEMORY);
4505 }
4506}
4507
4508void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4509{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004510 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004511
4512 try
4513 {
4514 if (index >= gl::MAX_VERTEX_ATTRIBS)
4515 {
4516 return error(GL_INVALID_VALUE);
4517 }
4518
4519 UNIMPLEMENTED(); // FIXME
4520 }
4521 catch(std::bad_alloc&)
4522 {
4523 return error(GL_OUT_OF_MEMORY);
4524 }
4525}
4526
4527void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4528{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004529 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004530
4531 try
4532 {
4533 if (index >= gl::MAX_VERTEX_ATTRIBS)
4534 {
4535 return error(GL_INVALID_VALUE);
4536 }
4537
4538 UNIMPLEMENTED(); // FIXME
4539 }
4540 catch(std::bad_alloc&)
4541 {
4542 return error(GL_OUT_OF_MEMORY);
4543 }
4544}
4545
4546void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4547{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004548 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004549
4550 try
4551 {
4552 if (index >= gl::MAX_VERTEX_ATTRIBS)
4553 {
4554 return error(GL_INVALID_VALUE);
4555 }
4556
4557 UNIMPLEMENTED(); // FIXME
4558 }
4559 catch(std::bad_alloc&)
4560 {
4561 return error(GL_OUT_OF_MEMORY);
4562 }
4563}
4564
4565void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4566{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004567 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 +00004568
4569 try
4570 {
4571 if (index >= gl::MAX_VERTEX_ATTRIBS)
4572 {
4573 return error(GL_INVALID_VALUE);
4574 }
4575
4576 UNIMPLEMENTED(); // FIXME
4577 }
4578 catch(std::bad_alloc&)
4579 {
4580 return error(GL_OUT_OF_MEMORY);
4581 }
4582}
4583
4584void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4585{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004586 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004587
4588 try
4589 {
4590 if (index >= gl::MAX_VERTEX_ATTRIBS)
4591 {
4592 return error(GL_INVALID_VALUE);
4593 }
4594
4595 UNIMPLEMENTED(); // FIXME
4596 }
4597 catch(std::bad_alloc&)
4598 {
4599 return error(GL_OUT_OF_MEMORY);
4600 }
4601}
4602
4603void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4604{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004605 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 +00004606
4607 try
4608 {
4609 if (index >= gl::MAX_VERTEX_ATTRIBS)
4610 {
4611 return error(GL_INVALID_VALUE);
4612 }
4613
4614 UNIMPLEMENTED(); // FIXME
4615 }
4616 catch(std::bad_alloc&)
4617 {
4618 return error(GL_OUT_OF_MEMORY);
4619 }
4620}
4621
4622void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4623{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004624 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004625
4626 try
4627 {
4628 if (index >= gl::MAX_VERTEX_ATTRIBS)
4629 {
4630 return error(GL_INVALID_VALUE);
4631 }
4632
4633 UNIMPLEMENTED(); // FIXME
4634 }
4635 catch(std::bad_alloc&)
4636 {
4637 return error(GL_OUT_OF_MEMORY);
4638 }
4639}
4640
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004641void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004642{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004643 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004644 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004645 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004646
4647 try
4648 {
4649 if (index >= gl::MAX_VERTEX_ATTRIBS)
4650 {
4651 return error(GL_INVALID_VALUE);
4652 }
4653
4654 if (size < 1 || size > 4)
4655 {
4656 return error(GL_INVALID_VALUE);
4657 }
4658
4659 switch (type)
4660 {
4661 case GL_BYTE:
4662 case GL_UNSIGNED_BYTE:
4663 case GL_SHORT:
4664 case GL_UNSIGNED_SHORT:
4665 case GL_FIXED:
4666 case GL_FLOAT:
4667 break;
4668 default:
4669 return error(GL_INVALID_ENUM);
4670 }
4671
4672 if (stride < 0)
4673 {
4674 return error(GL_INVALID_VALUE);
4675 }
4676
4677 gl::Context *context = gl::getContext();
4678
4679 if (context)
4680 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004681 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4682 context->vertexAttribute[index].mSize = size;
4683 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004684 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004685 context->vertexAttribute[index].mStride = stride;
4686 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004687 }
4688 }
4689 catch(std::bad_alloc&)
4690 {
4691 return error(GL_OUT_OF_MEMORY);
4692 }
4693}
4694
4695void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4696{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004697 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 +00004698
4699 try
4700 {
4701 if (width < 0 || height < 0)
4702 {
4703 return error(GL_INVALID_VALUE);
4704 }
4705
4706 gl::Context *context = gl::getContext();
4707
4708 if (context)
4709 {
4710 context->viewportX = x;
4711 context->viewportY = y;
4712 context->viewportWidth = width;
4713 context->viewportHeight = height;
4714 }
4715 }
4716 catch(std::bad_alloc&)
4717 {
4718 return error(GL_OUT_OF_MEMORY);
4719 }
4720}
4721
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004722void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4723 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004724{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004725 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4726 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004727 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004728 target, level, internalformat, width, height, depth, border, format, type, pixels);
4729
4730 try
4731 {
4732 UNIMPLEMENTED(); // FIXME
4733 }
4734 catch(std::bad_alloc&)
4735 {
4736 return error(GL_OUT_OF_MEMORY);
4737 }
4738}
4739}