blob: 78e2667061f4234a775a550f6510d5486e761b5d [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 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00001754 gl::Context *context = gl::getContext();
1755
1756 if (context)
1757 {
1758 gl::Texture *texture;
1759
1760 switch (target)
1761 {
1762 case GL_TEXTURE_2D:
1763 texture = context->getTexture2D();
1764 break;
1765
1766 case GL_TEXTURE_CUBE_MAP:
1767 texture = context->getTextureCubeMap();
1768 break;
1769
1770 default:
1771 return error(GL_INVALID_ENUM);
1772 }
1773
1774 texture->generateMipmaps();
1775 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001776 }
1777 catch(std::bad_alloc&)
1778 {
1779 return error(GL_OUT_OF_MEMORY);
1780 }
1781}
1782
1783void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1784{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001785 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001786
1787 try
1788 {
1789 if (n < 0)
1790 {
1791 return error(GL_INVALID_VALUE);
1792 }
1793
1794 gl::Context *context = gl::getContext();
1795
1796 if (context)
1797 {
1798 for (int i = 0; i < n; i++)
1799 {
1800 framebuffers[i] = context->createFramebuffer();
1801 }
1802 }
1803 }
1804 catch(std::bad_alloc&)
1805 {
1806 return error(GL_OUT_OF_MEMORY);
1807 }
1808}
1809
1810void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1811{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001812 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001813
1814 try
1815 {
1816 if (n < 0)
1817 {
1818 return error(GL_INVALID_VALUE);
1819 }
1820
1821 gl::Context *context = gl::getContext();
1822
1823 if (context)
1824 {
1825 for (int i = 0; i < n; i++)
1826 {
1827 renderbuffers[i] = context->createRenderbuffer();
1828 }
1829 }
1830 }
1831 catch(std::bad_alloc&)
1832 {
1833 return error(GL_OUT_OF_MEMORY);
1834 }
1835}
1836
1837void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1838{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001839 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001840
1841 try
1842 {
1843 if (n < 0)
1844 {
1845 return error(GL_INVALID_VALUE);
1846 }
1847
1848 gl::Context *context = gl::getContext();
1849
1850 if (context)
1851 {
1852 for (int i = 0; i < n; i++)
1853 {
1854 textures[i] = context->createTexture();
1855 }
1856 }
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 glGetActiveAttrib(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, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001867 "GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %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
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001885void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001886{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001887 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001888 "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 +00001889 program, index, bufsize, length, size, type, name);
1890
1891 try
1892 {
1893 if (bufsize < 0)
1894 {
1895 return error(GL_INVALID_VALUE);
1896 }
1897
1898 UNIMPLEMENTED(); // FIXME
1899 }
1900 catch(std::bad_alloc&)
1901 {
1902 return error(GL_OUT_OF_MEMORY);
1903 }
1904}
1905
1906void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1907{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001908 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1909 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001910
1911 try
1912 {
1913 if (maxcount < 0)
1914 {
1915 return error(GL_INVALID_VALUE);
1916 }
1917
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001918 gl::Context *context = gl::getContext();
1919
1920 if (context)
1921 {
1922 gl::Program *programObject = context->getProgram(program);
1923
1924 if (!programObject)
1925 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001926 if (context->getShader(program))
1927 {
1928 return error(GL_INVALID_OPERATION);
1929 }
1930 else
1931 {
1932 return error(GL_INVALID_VALUE);
1933 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001934 }
1935
1936 return programObject->getAttachedShaders(maxcount, count, shaders);
1937 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001938 }
1939 catch(std::bad_alloc&)
1940 {
1941 return error(GL_OUT_OF_MEMORY);
1942 }
1943}
1944
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001945int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001946{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001947 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001948
1949 try
1950 {
1951 gl::Context *context = gl::getContext();
1952
1953 if (context)
1954 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001955
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001956 gl::Program *programObject = context->getProgram(program);
1957
1958 if (!programObject)
1959 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001960 if (context->getShader(program))
1961 {
1962 return error(GL_INVALID_OPERATION, -1);
1963 }
1964 else
1965 {
1966 return error(GL_INVALID_VALUE, -1);
1967 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001968 }
1969
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00001970 if (!programObject->isLinked())
1971 {
1972 return error(GL_INVALID_OPERATION, -1);
1973 }
1974
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001975 return programObject->getAttributeLocation(name);
1976 }
1977 }
1978 catch(std::bad_alloc&)
1979 {
1980 return error(GL_OUT_OF_MEMORY, -1);
1981 }
1982
1983 return -1;
1984}
1985
1986void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1987{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001988 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001989
1990 try
1991 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001992 gl::Context *context = gl::getContext();
1993
1994 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001995 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001996 if (!(context->getBooleanv(pname, params)))
1997 {
1998 GLenum nativeType;
1999 unsigned int numParams = 0;
2000 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2001 return error(GL_INVALID_ENUM);
2002
2003 if (numParams == 0)
2004 return; // it is known that the pname is valid, but there are no parameters to return
2005
2006 if (nativeType == GL_FLOAT)
2007 {
2008 GLfloat *floatParams = NULL;
2009 floatParams = new GLfloat[numParams];
2010
2011 context->getFloatv(pname, floatParams);
2012
2013 for (unsigned int i = 0; i < numParams; ++i)
2014 {
2015 if (floatParams[i] == 0.0f)
2016 params[i] = GL_FALSE;
2017 else
2018 params[i] = GL_TRUE;
2019 }
2020
2021 delete [] floatParams;
2022 }
2023 else if (nativeType == GL_INT)
2024 {
2025 GLint *intParams = NULL;
2026 intParams = new GLint[numParams];
2027
2028 context->getIntegerv(pname, intParams);
2029
2030 for (unsigned int i = 0; i < numParams; ++i)
2031 {
2032 if (intParams[i] == 0)
2033 params[i] = GL_FALSE;
2034 else
2035 params[i] = GL_TRUE;
2036 }
2037
2038 delete [] intParams;
2039 }
2040 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002041 }
2042 }
2043 catch(std::bad_alloc&)
2044 {
2045 return error(GL_OUT_OF_MEMORY);
2046 }
2047}
2048
2049void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2050{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002051 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 +00002052
2053 try
2054 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002055 gl::Context *context = gl::getContext();
2056
2057 if (context)
2058 {
2059 gl::Buffer *buffer;
2060
2061 switch (target)
2062 {
2063 case GL_ARRAY_BUFFER:
2064 buffer = context->getArrayBuffer();
2065 break;
2066 case GL_ELEMENT_ARRAY_BUFFER:
2067 buffer = context->getElementArrayBuffer();
2068 break;
2069 default: return error(GL_INVALID_ENUM);
2070 }
2071
2072 if (!buffer)
2073 {
2074 // A null buffer means that "0" is bound to the requested buffer target
2075 return error(GL_INVALID_OPERATION);
2076 }
2077
2078 switch (pname)
2079 {
2080 case GL_BUFFER_USAGE:
2081 *params = buffer->usage();
2082 break;
2083 case GL_BUFFER_SIZE:
2084 *params = buffer->size();
2085 break;
2086 default: return error(GL_INVALID_ENUM);
2087 }
2088 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002089 }
2090 catch(std::bad_alloc&)
2091 {
2092 return error(GL_OUT_OF_MEMORY);
2093 }
2094}
2095
2096GLenum __stdcall glGetError(void)
2097{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002098 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002099
2100 gl::Context *context = gl::getContext();
2101
2102 if (context)
2103 {
2104 return context->getError();
2105 }
2106
2107 return GL_NO_ERROR;
2108}
2109
2110void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2111{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002112 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002113
2114 try
2115 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002116 gl::Context *context = gl::getContext();
2117
2118 if (context)
2119 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002120 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002121 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002122 GLenum nativeType;
2123 unsigned int numParams = 0;
2124 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2125 return error(GL_INVALID_ENUM);
2126
2127 if (numParams == 0)
2128 return; // it is known that the pname is valid, but that there are no parameters to return.
2129
2130 if (nativeType == GL_BOOL)
2131 {
2132 GLboolean *boolParams = NULL;
2133 boolParams = new GLboolean[numParams];
2134
2135 context->getBooleanv(pname, boolParams);
2136
2137 for (unsigned int i = 0; i < numParams; ++i)
2138 {
2139 if (boolParams[i] == GL_FALSE)
2140 params[i] = 0.0f;
2141 else
2142 params[i] = 1.0f;
2143 }
2144
2145 delete [] boolParams;
2146 }
2147 else if (nativeType == GL_INT)
2148 {
2149 GLint *intParams = NULL;
2150 intParams = new GLint[numParams];
2151
2152 context->getIntegerv(pname, intParams);
2153
2154 for (unsigned int i = 0; i < numParams; ++i)
2155 {
2156 params[i] = (GLfloat)intParams[i];
2157 }
2158
2159 delete [] intParams;
2160 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002161 }
2162 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002163 }
2164 catch(std::bad_alloc&)
2165 {
2166 return error(GL_OUT_OF_MEMORY);
2167 }
2168}
2169
2170void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2171{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002172 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2173 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002174
2175 try
2176 {
2177 gl::Context *context = gl::getContext();
2178
2179 if (context)
2180 {
2181 if (context->framebuffer == 0)
2182 {
2183 return error(GL_INVALID_OPERATION);
2184 }
2185
2186 UNIMPLEMENTED(); // FIXME
2187 }
2188 }
2189 catch(std::bad_alloc&)
2190 {
2191 return error(GL_OUT_OF_MEMORY);
2192 }
2193}
2194
2195void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2196{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002197 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002198
2199 try
2200 {
2201 gl::Context *context = gl::getContext();
2202
2203 if (context)
2204 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002205 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002206 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002207 GLenum nativeType;
2208 unsigned int numParams = 0;
2209 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2210 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002211
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002212 if (numParams == 0)
2213 return; // it is known that pname is valid, but there are no parameters to return
2214
2215 if (nativeType == GL_BOOL)
2216 {
2217 GLboolean *boolParams = NULL;
2218 boolParams = new GLboolean[numParams];
2219
2220 context->getBooleanv(pname, boolParams);
2221
2222 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002223 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002224 if (boolParams[i] == GL_FALSE)
2225 params[i] = 0;
2226 else
2227 params[i] = 1;
2228 }
2229
2230 delete [] boolParams;
2231 }
2232 else if (nativeType == GL_FLOAT)
2233 {
2234 GLfloat *floatParams = NULL;
2235 floatParams = new GLfloat[numParams];
2236
2237 context->getFloatv(pname, floatParams);
2238
2239 for (unsigned int i = 0; i < numParams; ++i)
2240 {
2241 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002242 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002243 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002244 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002245 else
2246 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 +00002247 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002248
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002249 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002250 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002251 }
2252 }
2253 }
2254 catch(std::bad_alloc&)
2255 {
2256 return error(GL_OUT_OF_MEMORY);
2257 }
2258}
2259
2260void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2261{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002262 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002263
2264 try
2265 {
2266 gl::Context *context = gl::getContext();
2267
2268 if (context)
2269 {
2270 gl::Program *programObject = context->getProgram(program);
2271
2272 if (!programObject)
2273 {
2274 return error(GL_INVALID_VALUE);
2275 }
2276
2277 switch (pname)
2278 {
2279 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002280 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002281 return;
2282 case GL_LINK_STATUS:
2283 *params = programObject->isLinked();
2284 return;
2285 case GL_VALIDATE_STATUS:
2286 UNIMPLEMENTED(); // FIXME
2287 *params = GL_TRUE;
2288 return;
2289 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002290 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002291 return;
2292 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002293 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002294 return;
2295 case GL_ACTIVE_ATTRIBUTES:
2296 UNIMPLEMENTED(); // FIXME
2297 *params = 0;
2298 return;
2299 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2300 UNIMPLEMENTED(); // FIXME
2301 *params = 0;
2302 return;
2303 case GL_ACTIVE_UNIFORMS:
2304 UNIMPLEMENTED(); // FIXME
2305 *params = 0;
2306 return;
2307 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2308 UNIMPLEMENTED(); // FIXME
2309 *params = 0;
2310 return;
2311 default:
2312 return error(GL_INVALID_ENUM);
2313 }
2314 }
2315 }
2316 catch(std::bad_alloc&)
2317 {
2318 return error(GL_OUT_OF_MEMORY);
2319 }
2320}
2321
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002322void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002323{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002324 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 +00002325 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002326
2327 try
2328 {
2329 if (bufsize < 0)
2330 {
2331 return error(GL_INVALID_VALUE);
2332 }
2333
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002334 gl::Context *context = gl::getContext();
2335
2336 if (context)
2337 {
2338 gl::Program *programObject = context->getProgram(program);
2339
2340 if (!programObject)
2341 {
2342 return error(GL_INVALID_VALUE);
2343 }
2344
2345 programObject->getInfoLog(bufsize, length, infolog);
2346 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002347 }
2348 catch(std::bad_alloc&)
2349 {
2350 return error(GL_OUT_OF_MEMORY);
2351 }
2352}
2353
2354void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2355{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002356 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 +00002357
2358 try
2359 {
2360 UNIMPLEMENTED(); // FIXME
2361 }
2362 catch(std::bad_alloc&)
2363 {
2364 return error(GL_OUT_OF_MEMORY);
2365 }
2366}
2367
2368void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2369{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002370 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002371
2372 try
2373 {
2374 gl::Context *context = gl::getContext();
2375
2376 if (context)
2377 {
2378 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002379
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002380 if (!shaderObject)
2381 {
2382 return error(GL_INVALID_VALUE);
2383 }
2384
2385 switch (pname)
2386 {
2387 case GL_SHADER_TYPE:
2388 *params = shaderObject->getType();
2389 return;
2390 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002391 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002392 return;
2393 case GL_COMPILE_STATUS:
2394 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2395 return;
2396 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002397 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002398 return;
2399 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002400 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002401 return;
2402 default:
2403 return error(GL_INVALID_ENUM);
2404 }
2405 }
2406 }
2407 catch(std::bad_alloc&)
2408 {
2409 return error(GL_OUT_OF_MEMORY);
2410 }
2411}
2412
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002413void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002414{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002415 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 +00002416 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002417
2418 try
2419 {
2420 if (bufsize < 0)
2421 {
2422 return error(GL_INVALID_VALUE);
2423 }
2424
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002425 gl::Context *context = gl::getContext();
2426
2427 if (context)
2428 {
2429 gl::Shader *shaderObject = context->getShader(shader);
2430
2431 if (!shaderObject)
2432 {
2433 return error(GL_INVALID_VALUE);
2434 }
2435
2436 shaderObject->getInfoLog(bufsize, length, infolog);
2437 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002438 }
2439 catch(std::bad_alloc&)
2440 {
2441 return error(GL_OUT_OF_MEMORY);
2442 }
2443}
2444
2445void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2446{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002447 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2448 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002449
2450 try
2451 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002452 switch (shadertype)
2453 {
2454 case GL_VERTEX_SHADER:
2455 case GL_FRAGMENT_SHADER:
2456 break;
2457 default:
2458 return error(GL_INVALID_ENUM);
2459 }
2460
2461 switch (precisiontype)
2462 {
2463 case GL_LOW_FLOAT:
2464 case GL_MEDIUM_FLOAT:
2465 case GL_HIGH_FLOAT:
2466 // Assume IEEE 754 precision
2467 range[0] = 127;
2468 range[1] = 127;
2469 precision[0] = 23;
2470 precision[1] = 23;
2471 break;
2472 case GL_LOW_INT:
2473 case GL_MEDIUM_INT:
2474 case GL_HIGH_INT:
2475 // Some (most) hardware only supports single-precision floating-point numbers,
2476 // which can accurately represent integers up to +/-16777216
2477 range[0] = 24;
2478 range[1] = 24;
2479 precision[0] = 0;
2480 precision[1] = 0;
2481 break;
2482 default:
2483 return error(GL_INVALID_ENUM);
2484 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002485 }
2486 catch(std::bad_alloc&)
2487 {
2488 return error(GL_OUT_OF_MEMORY);
2489 }
2490}
2491
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002492void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002493{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002494 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 +00002495 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002496
2497 try
2498 {
2499 if (bufsize < 0)
2500 {
2501 return error(GL_INVALID_VALUE);
2502 }
2503
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002504 gl::Context *context = gl::getContext();
2505
2506 if (context)
2507 {
2508 gl::Shader *shaderObject = context->getShader(shader);
2509
2510 if (!shaderObject)
2511 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002512 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002513 }
2514
2515 shaderObject->getSource(bufsize, length, source);
2516 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002517 }
2518 catch(std::bad_alloc&)
2519 {
2520 return error(GL_OUT_OF_MEMORY);
2521 }
2522}
2523
2524const GLubyte* __stdcall glGetString(GLenum name)
2525{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002526 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002527
2528 try
2529 {
2530 switch (name)
2531 {
2532 case GL_VENDOR:
2533 return (GLubyte*)"TransGaming Inc.";
2534 case GL_RENDERER:
2535 return (GLubyte*)"ANGLE";
2536 case GL_VERSION:
2537 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2538 case GL_SHADING_LANGUAGE_VERSION:
2539 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2540 case GL_EXTENSIONS:
2541 return (GLubyte*)"";
2542 default:
2543 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2544 }
2545 }
2546 catch(std::bad_alloc&)
2547 {
2548 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2549 }
2550
2551 return NULL;
2552}
2553
2554void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2555{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002556 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 +00002557
2558 try
2559 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002560 gl::Context *context = gl::getContext();
2561
2562 if (context)
2563 {
2564 gl::Texture *texture;
2565
2566 switch (target)
2567 {
2568 case GL_TEXTURE_2D:
2569 texture = context->getTexture2D();
2570 break;
2571 case GL_TEXTURE_CUBE_MAP:
2572 texture = context->getTextureCubeMap();
2573 break;
2574 default:
2575 return error(GL_INVALID_ENUM);
2576 }
2577
2578 switch (pname)
2579 {
2580 case GL_TEXTURE_MAG_FILTER:
2581 *params = (GLfloat)texture->getMagFilter();
2582 break;
2583 case GL_TEXTURE_MIN_FILTER:
2584 *params = (GLfloat)texture->getMinFilter();
2585 break;
2586 case GL_TEXTURE_WRAP_S:
2587 *params = (GLfloat)texture->getWrapS();
2588 break;
2589 case GL_TEXTURE_WRAP_T:
2590 *params = (GLfloat)texture->getWrapT();
2591 break;
2592 default:
2593 return error(GL_INVALID_ENUM);
2594 }
2595 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002596 }
2597 catch(std::bad_alloc&)
2598 {
2599 return error(GL_OUT_OF_MEMORY);
2600 }
2601}
2602
2603void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2604{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002605 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 +00002606
2607 try
2608 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002609 gl::Context *context = gl::getContext();
2610
2611 if (context)
2612 {
2613 gl::Texture *texture;
2614
2615 switch (target)
2616 {
2617 case GL_TEXTURE_2D:
2618 texture = context->getTexture2D();
2619 break;
2620 case GL_TEXTURE_CUBE_MAP:
2621 texture = context->getTextureCubeMap();
2622 break;
2623 default:
2624 return error(GL_INVALID_ENUM);
2625 }
2626
2627 switch (pname)
2628 {
2629 case GL_TEXTURE_MAG_FILTER:
2630 *params = texture->getMagFilter();
2631 break;
2632 case GL_TEXTURE_MIN_FILTER:
2633 *params = texture->getMinFilter();
2634 break;
2635 case GL_TEXTURE_WRAP_S:
2636 *params = texture->getWrapS();
2637 break;
2638 case GL_TEXTURE_WRAP_T:
2639 *params = texture->getWrapT();
2640 break;
2641 default:
2642 return error(GL_INVALID_ENUM);
2643 }
2644 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002645 }
2646 catch(std::bad_alloc&)
2647 {
2648 return error(GL_OUT_OF_MEMORY);
2649 }
2650}
2651
2652void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2653{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002654 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002655
2656 try
2657 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002658 gl::Context *context = gl::getContext();
2659
2660 if (context)
2661 {
2662 if (program == 0)
2663 {
2664 return error(GL_INVALID_VALUE);
2665 }
2666
2667 gl::Program *programObject = context->getProgram(program);
2668
2669 if (!programObject || !programObject->isLinked())
2670 {
2671 return error(GL_INVALID_OPERATION);
2672 }
2673
2674 if (!programObject->getUniformfv(location, params))
2675 {
2676 return error(GL_INVALID_OPERATION);
2677 }
2678 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002679 }
2680 catch(std::bad_alloc&)
2681 {
2682 return error(GL_OUT_OF_MEMORY);
2683 }
2684}
2685
2686void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2687{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002688 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002689
2690 try
2691 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002692 gl::Context *context = gl::getContext();
2693
2694 if (context)
2695 {
2696 if (program == 0)
2697 {
2698 return error(GL_INVALID_VALUE);
2699 }
2700
2701 gl::Program *programObject = context->getProgram(program);
2702
2703 if (!programObject || !programObject->isLinked())
2704 {
2705 return error(GL_INVALID_OPERATION);
2706 }
2707
2708 if (!programObject)
2709 {
2710 return error(GL_INVALID_OPERATION);
2711 }
2712
2713 if (!programObject->getUniformiv(location, params))
2714 {
2715 return error(GL_INVALID_OPERATION);
2716 }
2717 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002718 }
2719 catch(std::bad_alloc&)
2720 {
2721 return error(GL_OUT_OF_MEMORY);
2722 }
2723}
2724
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002725int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002726{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002727 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002728
2729 try
2730 {
2731 gl::Context *context = gl::getContext();
2732
2733 if (strstr(name, "gl_") == name)
2734 {
2735 return -1;
2736 }
2737
2738 if (context)
2739 {
2740 gl::Program *programObject = context->getProgram(program);
2741
2742 if (!programObject)
2743 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002744 if (context->getShader(program))
2745 {
2746 return error(GL_INVALID_OPERATION, -1);
2747 }
2748 else
2749 {
2750 return error(GL_INVALID_VALUE, -1);
2751 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002752 }
2753
2754 if (!programObject->isLinked())
2755 {
2756 return error(GL_INVALID_OPERATION, -1);
2757 }
2758
2759 return programObject->getUniformLocation(name);
2760 }
2761 }
2762 catch(std::bad_alloc&)
2763 {
2764 return error(GL_OUT_OF_MEMORY, -1);
2765 }
2766
2767 return -1;
2768}
2769
2770void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2771{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002772 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002773
2774 try
2775 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002776 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002777
daniel@transgaming.come0078962010-04-15 20:45:08 +00002778 if (context)
2779 {
2780 if (index >= gl::MAX_VERTEX_ATTRIBS)
2781 {
2782 return error(GL_INVALID_VALUE);
2783 }
2784
2785 switch (pname)
2786 {
2787 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2788 *params = (GLfloat)(context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2789 break;
2790 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2791 *params = (GLfloat)context->vertexAttribute[index].mSize;
2792 break;
2793 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2794 *params = (GLfloat)context->vertexAttribute[index].mStride;
2795 break;
2796 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2797 *params = (GLfloat)context->vertexAttribute[index].mType;
2798 break;
2799 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2800 *params = (GLfloat)(context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2801 break;
2802 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2803 *params = (GLfloat)context->vertexAttribute[index].mBoundBuffer;
2804 break;
2805 case GL_CURRENT_VERTEX_ATTRIB:
2806 for (int i = 0; i < 4; ++i)
2807 {
2808 params[i] = context->vertexAttribute[index].mCurrentValue[i];
2809 }
2810 break;
2811 default: return error(GL_INVALID_ENUM);
2812 }
2813 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002814 }
2815 catch(std::bad_alloc&)
2816 {
2817 return error(GL_OUT_OF_MEMORY);
2818 }
2819}
2820
2821void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2822{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002823 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002824
2825 try
2826 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002827 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002828
daniel@transgaming.come0078962010-04-15 20:45:08 +00002829 if (context)
2830 {
2831 if (index >= gl::MAX_VERTEX_ATTRIBS)
2832 {
2833 return error(GL_INVALID_VALUE);
2834 }
2835
2836 switch (pname)
2837 {
2838 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
2839 *params = (context->vertexAttribute[index].mEnabled ? GL_TRUE : GL_FALSE);
2840 break;
2841 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
2842 *params = context->vertexAttribute[index].mSize;
2843 break;
2844 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
2845 *params = context->vertexAttribute[index].mStride;
2846 break;
2847 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
2848 *params = context->vertexAttribute[index].mType;
2849 break;
2850 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
2851 *params = (context->vertexAttribute[index].mNormalized ? GL_TRUE : GL_FALSE);
2852 break;
2853 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2854 *params = context->vertexAttribute[index].mBoundBuffer;
2855 break;
2856 case GL_CURRENT_VERTEX_ATTRIB:
2857 for (int i = 0; i < 4; ++i)
2858 {
2859 float currentValue = context->vertexAttribute[index].mCurrentValue[i];
2860 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
2861 }
2862 break;
2863 default: return error(GL_INVALID_ENUM);
2864 }
2865 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002866 }
2867 catch(std::bad_alloc&)
2868 {
2869 return error(GL_OUT_OF_MEMORY);
2870 }
2871}
2872
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002873void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002874{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002875 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002876
2877 try
2878 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002879 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002880
daniel@transgaming.come0078962010-04-15 20:45:08 +00002881 if (context)
2882 {
2883 if (index >= gl::MAX_VERTEX_ATTRIBS)
2884 {
2885 return error(GL_INVALID_VALUE);
2886 }
2887
2888 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
2889 {
2890 return error(GL_INVALID_ENUM);
2891 }
2892
2893 *pointer = const_cast<GLvoid*>(context->vertexAttribute[index].mPointer);
2894 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002895 }
2896 catch(std::bad_alloc&)
2897 {
2898 return error(GL_OUT_OF_MEMORY);
2899 }
2900}
2901
2902void __stdcall glHint(GLenum target, GLenum mode)
2903{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002904 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002905
2906 try
2907 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002908 switch (target)
2909 {
2910 case GL_GENERATE_MIPMAP_HINT:
2911 switch (mode)
2912 {
2913 case GL_FASTEST:
2914 case GL_NICEST:
2915 case GL_DONT_CARE:
2916 break;
2917 default:
2918 return error(GL_INVALID_ENUM);
2919 }
2920 break;
2921 default:
2922 return error(GL_INVALID_ENUM);
2923 }
2924
2925 gl::Context *context = gl::getContext();
2926 if (context)
2927 {
2928 if (target == GL_GENERATE_MIPMAP_HINT)
2929 context->generateMipmapHint = mode;
2930 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002931 }
2932 catch(std::bad_alloc&)
2933 {
2934 return error(GL_OUT_OF_MEMORY);
2935 }
2936}
2937
2938GLboolean __stdcall glIsBuffer(GLuint buffer)
2939{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002940 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002941
2942 try
2943 {
2944 gl::Context *context = gl::getContext();
2945
2946 if (context && buffer)
2947 {
2948 gl::Buffer *bufferObject = context->getBuffer(buffer);
2949
2950 if (bufferObject)
2951 {
2952 return GL_TRUE;
2953 }
2954 }
2955 }
2956 catch(std::bad_alloc&)
2957 {
2958 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2959 }
2960
2961 return GL_FALSE;
2962}
2963
2964GLboolean __stdcall glIsEnabled(GLenum cap)
2965{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002966 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002967
2968 try
2969 {
2970 gl::Context *context = gl::getContext();
2971
2972 if (context)
2973 {
2974 switch (cap)
2975 {
2976 case GL_CULL_FACE: return context->cullFace;
2977 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
2978 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
2979 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
2980 case GL_SCISSOR_TEST: return context->scissorTest;
2981 case GL_STENCIL_TEST: return context->stencilTest;
2982 case GL_DEPTH_TEST: return context->depthTest;
2983 case GL_BLEND: return context->blend;
2984 case GL_DITHER: return context->dither;
2985 default:
2986 return error(GL_INVALID_ENUM, false);
2987 }
2988 }
2989 }
2990 catch(std::bad_alloc&)
2991 {
2992 return error(GL_OUT_OF_MEMORY, false);
2993 }
2994
2995 return false;
2996}
2997
2998GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
2999{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003000 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003001
3002 try
3003 {
3004 gl::Context *context = gl::getContext();
3005
3006 if (context && framebuffer)
3007 {
3008 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3009
3010 if (framebufferObject)
3011 {
3012 return GL_TRUE;
3013 }
3014 }
3015 }
3016 catch(std::bad_alloc&)
3017 {
3018 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3019 }
3020
3021 return GL_FALSE;
3022}
3023
3024GLboolean __stdcall glIsProgram(GLuint program)
3025{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003026 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003027
3028 try
3029 {
3030 gl::Context *context = gl::getContext();
3031
3032 if (context && program)
3033 {
3034 gl::Program *programObject = context->getProgram(program);
3035
3036 if (programObject)
3037 {
3038 return GL_TRUE;
3039 }
3040 }
3041 }
3042 catch(std::bad_alloc&)
3043 {
3044 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3045 }
3046
3047 return GL_FALSE;
3048}
3049
3050GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3051{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003052 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003053
3054 try
3055 {
3056 gl::Context *context = gl::getContext();
3057
3058 if (context && renderbuffer)
3059 {
3060 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3061
3062 if (renderbufferObject)
3063 {
3064 return GL_TRUE;
3065 }
3066 }
3067 }
3068 catch(std::bad_alloc&)
3069 {
3070 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3071 }
3072
3073 return GL_FALSE;
3074}
3075
3076GLboolean __stdcall glIsShader(GLuint shader)
3077{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003078 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003079
3080 try
3081 {
3082 gl::Context *context = gl::getContext();
3083
3084 if (context && shader)
3085 {
3086 gl::Shader *shaderObject = context->getShader(shader);
3087
3088 if (shaderObject)
3089 {
3090 return GL_TRUE;
3091 }
3092 }
3093 }
3094 catch(std::bad_alloc&)
3095 {
3096 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3097 }
3098
3099 return GL_FALSE;
3100}
3101
3102GLboolean __stdcall glIsTexture(GLuint texture)
3103{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003104 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003105
3106 try
3107 {
3108 gl::Context *context = gl::getContext();
3109
3110 if (context && texture)
3111 {
3112 gl::Texture *textureObject = context->getTexture(texture);
3113
3114 if (textureObject)
3115 {
3116 return GL_TRUE;
3117 }
3118 }
3119 }
3120 catch(std::bad_alloc&)
3121 {
3122 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3123 }
3124
3125 return GL_FALSE;
3126}
3127
3128void __stdcall glLineWidth(GLfloat width)
3129{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003130 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003131
3132 try
3133 {
3134 if (width <= 0.0f)
3135 {
3136 return error(GL_INVALID_VALUE);
3137 }
3138
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003139 gl::Context *context = gl::getContext();
3140
3141 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003142 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003143 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003144 }
3145 }
3146 catch(std::bad_alloc&)
3147 {
3148 return error(GL_OUT_OF_MEMORY);
3149 }
3150}
3151
3152void __stdcall glLinkProgram(GLuint program)
3153{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003154 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003155
3156 try
3157 {
3158 gl::Context *context = gl::getContext();
3159
3160 if (context)
3161 {
3162 gl::Program *programObject = context->getProgram(program);
3163
3164 if (!programObject)
3165 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003166 if (context->getShader(program))
3167 {
3168 return error(GL_INVALID_OPERATION);
3169 }
3170 else
3171 {
3172 return error(GL_INVALID_VALUE);
3173 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003174 }
3175
3176 programObject->link();
3177 }
3178 }
3179 catch(std::bad_alloc&)
3180 {
3181 return error(GL_OUT_OF_MEMORY);
3182 }
3183}
3184
3185void __stdcall glPixelStorei(GLenum pname, GLint param)
3186{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003187 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003188
3189 try
3190 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003191 gl::Context *context = gl::getContext();
3192
3193 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003194 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003195 switch (pname)
3196 {
3197 case GL_UNPACK_ALIGNMENT:
3198 if (param != 1 && param != 2 && param != 4 && param != 8)
3199 {
3200 return error(GL_INVALID_VALUE);
3201 }
3202
3203 context->unpackAlignment = param;
3204 break;
3205
3206 case GL_PACK_ALIGNMENT:
3207 if (param != 1 && param != 2 && param != 4 && param != 8)
3208 {
3209 return error(GL_INVALID_VALUE);
3210 }
3211
3212 context->packAlignment = param;
3213 break;
3214
3215 default:
3216 return error(GL_INVALID_ENUM);
3217 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003218 }
3219 }
3220 catch(std::bad_alloc&)
3221 {
3222 return error(GL_OUT_OF_MEMORY);
3223 }
3224}
3225
3226void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3227{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003228 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003229
3230 try
3231 {
3232 if (factor != 0.0f || units != 0.0f)
3233 {
3234 UNIMPLEMENTED(); // FIXME
3235 }
3236 }
3237 catch(std::bad_alloc&)
3238 {
3239 return error(GL_OUT_OF_MEMORY);
3240 }
3241}
3242
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003243void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003244{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003245 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003246 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003247 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003248
3249 try
3250 {
3251 if (width < 0 || height < 0)
3252 {
3253 return error(GL_INVALID_VALUE);
3254 }
3255
3256 switch (format)
3257 {
3258 case GL_RGBA:
3259 switch (type)
3260 {
3261 case GL_UNSIGNED_BYTE:
3262 break;
3263 default:
3264 return error(GL_INVALID_OPERATION);
3265 }
3266 break;
3267 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3268 switch (type)
3269 {
3270 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3271 break;
3272 default:
3273 return error(GL_INVALID_OPERATION);
3274 }
3275 break;
3276 default:
3277 return error(GL_INVALID_OPERATION);
3278 }
3279
3280 gl::Context *context = gl::getContext();
3281
3282 if (context)
3283 {
3284 context->readPixels(x, y, width, height, format, type, pixels);
3285 }
3286 }
3287 catch(std::bad_alloc&)
3288 {
3289 return error(GL_OUT_OF_MEMORY);
3290 }
3291}
3292
3293void __stdcall glReleaseShaderCompiler(void)
3294{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003295 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003296
3297 try
3298 {
3299 gl::Shader::releaseCompiler();
3300 }
3301 catch(std::bad_alloc&)
3302 {
3303 return error(GL_OUT_OF_MEMORY);
3304 }
3305}
3306
3307void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3308{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003309 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3310 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003311
3312 try
3313 {
3314 switch (target)
3315 {
3316 case GL_RENDERBUFFER:
3317 break;
3318 default:
3319 return error(GL_INVALID_ENUM);
3320 }
3321
3322 switch (internalformat)
3323 {
3324 case GL_DEPTH_COMPONENT16:
3325 case GL_RGBA4:
3326 case GL_RGB5_A1:
3327 case GL_RGB565:
3328 case GL_STENCIL_INDEX8:
3329 break;
3330 default:
3331 return error(GL_INVALID_ENUM);
3332 }
3333
3334 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3335 {
3336 return error(GL_INVALID_VALUE);
3337 }
3338
3339 gl::Context *context = gl::getContext();
3340
3341 if (context)
3342 {
3343 if (context->framebuffer == 0 || context->renderbuffer == 0)
3344 {
3345 return error(GL_INVALID_OPERATION);
3346 }
3347
3348 switch (internalformat)
3349 {
3350 case GL_DEPTH_COMPONENT16:
3351 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3352 break;
3353 case GL_RGBA4:
3354 case GL_RGB5_A1:
3355 case GL_RGB565:
3356 UNIMPLEMENTED(); // FIXME
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003357 // context->setRenderbuffer(new Colorbuffer(renderTarget));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003358 break;
3359 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003360 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003361 break;
3362 default:
3363 return error(GL_INVALID_ENUM);
3364 }
3365 }
3366 }
3367 catch(std::bad_alloc&)
3368 {
3369 return error(GL_OUT_OF_MEMORY);
3370 }
3371}
3372
3373void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3374{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003375 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003376
3377 try
3378 {
3379 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003380
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003381 if (context)
3382 {
3383 context->sampleCoverageValue = gl::clamp01(value);
3384 context->sampleCoverageInvert = invert;
3385 }
3386 }
3387 catch(std::bad_alloc&)
3388 {
3389 return error(GL_OUT_OF_MEMORY);
3390 }
3391}
3392
3393void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3394{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003395 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 +00003396
3397 try
3398 {
3399 if (width < 0 || height < 0)
3400 {
3401 return error(GL_INVALID_VALUE);
3402 }
3403
3404 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003405
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003406 if (context)
3407 {
3408 context->scissorX = x;
3409 context->scissorY = y;
3410 context->scissorWidth = width;
3411 context->scissorHeight = height;
3412 }
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 glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003421{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003422 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003423 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003424 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003425
3426 try
3427 {
3428 if (n < 0 || length < 0)
3429 {
3430 return error(GL_INVALID_VALUE);
3431 }
3432
3433 UNIMPLEMENTED(); // FIXME
3434 }
3435 catch(std::bad_alloc&)
3436 {
3437 return error(GL_OUT_OF_MEMORY);
3438 }
3439}
3440
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003441void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003442{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003443 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 +00003444 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003445
3446 try
3447 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003448 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003449 {
3450 return error(GL_INVALID_VALUE);
3451 }
3452
3453 gl::Context *context = gl::getContext();
3454
3455 if (context)
3456 {
3457 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003458
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003459 if (!shaderObject)
3460 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003461 if (context->getProgram(shader))
3462 {
3463 return error(GL_INVALID_OPERATION);
3464 }
3465 else
3466 {
3467 return error(GL_INVALID_VALUE);
3468 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003469 }
3470
3471 shaderObject->setSource(count, string, length);
3472 }
3473 }
3474 catch(std::bad_alloc&)
3475 {
3476 return error(GL_OUT_OF_MEMORY);
3477 }
3478}
3479
3480void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3481{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003482 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003483}
3484
3485void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3486{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003487 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 +00003488
3489 try
3490 {
3491 switch (face)
3492 {
3493 case GL_FRONT:
3494 case GL_BACK:
3495 case GL_FRONT_AND_BACK:
3496 break;
3497 default:
3498 return error(GL_INVALID_ENUM);
3499 }
3500
3501 switch (func)
3502 {
3503 case GL_NEVER:
3504 case GL_ALWAYS:
3505 case GL_LESS:
3506 case GL_LEQUAL:
3507 case GL_EQUAL:
3508 case GL_GEQUAL:
3509 case GL_GREATER:
3510 case GL_NOTEQUAL:
3511 break;
3512 default:
3513 return error(GL_INVALID_ENUM);
3514 }
3515
3516 gl::Context *context = gl::getContext();
3517
3518 if (context)
3519 {
3520 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3521 {
3522 context->stencilFunc = func;
3523 context->stencilRef = ref;
3524 context->stencilMask = mask;
3525 }
3526
3527 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3528 {
3529 context->stencilBackFunc = func;
3530 context->stencilBackRef = ref;
3531 context->stencilBackMask = mask;
3532 }
3533 }
3534 }
3535 catch(std::bad_alloc&)
3536 {
3537 return error(GL_OUT_OF_MEMORY);
3538 }
3539}
3540
3541void __stdcall glStencilMask(GLuint mask)
3542{
3543 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3544}
3545
3546void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3547{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003548 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003549
3550 try
3551 {
3552 switch (face)
3553 {
3554 case GL_FRONT:
3555 case GL_BACK:
3556 case GL_FRONT_AND_BACK:
3557 break;
3558 default:
3559 return error(GL_INVALID_ENUM);
3560 }
3561
3562 gl::Context *context = gl::getContext();
3563
3564 if (context)
3565 {
3566 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3567 {
3568 context->stencilWritemask = mask;
3569 }
3570
3571 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3572 {
3573 context->stencilBackWritemask = mask;
3574 }
3575 }
3576 }
3577 catch(std::bad_alloc&)
3578 {
3579 return error(GL_OUT_OF_MEMORY);
3580 }
3581}
3582
3583void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3584{
3585 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3586}
3587
3588void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3589{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003590 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3591 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003592
3593 try
3594 {
3595 switch (face)
3596 {
3597 case GL_FRONT:
3598 case GL_BACK:
3599 case GL_FRONT_AND_BACK:
3600 break;
3601 default:
3602 return error(GL_INVALID_ENUM);
3603 }
3604
3605 switch (fail)
3606 {
3607 case GL_ZERO:
3608 case GL_KEEP:
3609 case GL_REPLACE:
3610 case GL_INCR:
3611 case GL_DECR:
3612 case GL_INVERT:
3613 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003614 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003615 break;
3616 default:
3617 return error(GL_INVALID_ENUM);
3618 }
3619
3620 switch (zfail)
3621 {
3622 case GL_ZERO:
3623 case GL_KEEP:
3624 case GL_REPLACE:
3625 case GL_INCR:
3626 case GL_DECR:
3627 case GL_INVERT:
3628 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003629 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003630 break;
3631 default:
3632 return error(GL_INVALID_ENUM);
3633 }
3634
3635 switch (zpass)
3636 {
3637 case GL_ZERO:
3638 case GL_KEEP:
3639 case GL_REPLACE:
3640 case GL_INCR:
3641 case GL_DECR:
3642 case GL_INVERT:
3643 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003644 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003645 break;
3646 default:
3647 return error(GL_INVALID_ENUM);
3648 }
3649
3650 gl::Context *context = gl::getContext();
3651
3652 if (context)
3653 {
3654 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3655 {
3656 context->stencilFail = fail;
3657 context->stencilPassDepthFail = zfail;
3658 context->stencilPassDepthPass = zpass;
3659 }
3660
3661 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3662 {
3663 context->stencilBackFail = fail;
3664 context->stencilBackPassDepthFail = zfail;
3665 context->stencilBackPassDepthPass = zpass;
3666 }
3667 }
3668 }
3669 catch(std::bad_alloc&)
3670 {
3671 return error(GL_OUT_OF_MEMORY);
3672 }
3673}
3674
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003675void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3676 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003677{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003678 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 +00003679 "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 +00003680 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003681
3682 try
3683 {
3684 if (level < 0 || width < 0 || height < 0)
3685 {
3686 return error(GL_INVALID_VALUE);
3687 }
3688
3689 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3690 {
3691 return error(GL_INVALID_VALUE);
3692 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003693
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003694 switch (target)
3695 {
3696 case GL_TEXTURE_2D:
3697 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3698 {
3699 return error(GL_INVALID_VALUE);
3700 }
3701 break;
3702 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3703 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3704 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3705 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3706 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3707 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003708 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003709 {
3710 return error(GL_INVALID_VALUE);
3711 }
3712
3713 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3714 {
3715 return error(GL_INVALID_VALUE);
3716 }
3717 break;
3718 default:
3719 return error(GL_INVALID_ENUM);
3720 }
3721
3722 if (internalformat != format)
3723 {
3724 return error(GL_INVALID_OPERATION);
3725 }
3726
3727 switch (internalformat)
3728 {
3729 case GL_ALPHA:
3730 case GL_LUMINANCE:
3731 case GL_LUMINANCE_ALPHA:
3732 switch (type)
3733 {
3734 case GL_UNSIGNED_BYTE:
3735 break;
3736 default:
3737 return error(GL_INVALID_ENUM);
3738 }
3739 break;
3740 case GL_RGB:
3741 switch (type)
3742 {
3743 case GL_UNSIGNED_BYTE:
3744 case GL_UNSIGNED_SHORT_5_6_5:
3745 break;
3746 default:
3747 return error(GL_INVALID_ENUM);
3748 }
3749 break;
3750 case GL_RGBA:
3751 switch (type)
3752 {
3753 case GL_UNSIGNED_BYTE:
3754 case GL_UNSIGNED_SHORT_4_4_4_4:
3755 case GL_UNSIGNED_SHORT_5_5_5_1:
3756 break;
3757 default:
3758 return error(GL_INVALID_ENUM);
3759 }
3760 break;
3761 default:
3762 return error(GL_INVALID_VALUE);
3763 }
3764
3765 if (border != 0)
3766 {
3767 return error(GL_INVALID_VALUE);
3768 }
3769
3770 gl::Context *context = gl::getContext();
3771
3772 if (context)
3773 {
3774 if (target == GL_TEXTURE_2D)
3775 {
3776 gl::Texture2D *texture = context->getTexture2D();
3777
3778 if (!texture)
3779 {
3780 return error(GL_INVALID_OPERATION);
3781 }
3782
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003783 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003784 }
3785 else
3786 {
3787 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3788
3789 if (!texture)
3790 {
3791 return error(GL_INVALID_OPERATION);
3792 }
3793
3794 switch (target)
3795 {
3796 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003797 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003798 break;
3799 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003800 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003801 break;
3802 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003803 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003804 break;
3805 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003806 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003807 break;
3808 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003809 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003810 break;
3811 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003812 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003813 break;
3814 default: UNREACHABLE();
3815 }
3816 }
3817 }
3818 }
3819 catch(std::bad_alloc&)
3820 {
3821 return error(GL_OUT_OF_MEMORY);
3822 }
3823}
3824
3825void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3826{
3827 glTexParameteri(target, pname, (GLint)param);
3828}
3829
3830void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3831{
3832 glTexParameteri(target, pname, (GLint)*params);
3833}
3834
3835void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3836{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003837 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003838
3839 try
3840 {
3841 gl::Context *context = gl::getContext();
3842
3843 if (context)
3844 {
3845 gl::Texture *texture;
3846
3847 switch (target)
3848 {
3849 case GL_TEXTURE_2D:
3850 texture = context->getTexture2D();
3851 break;
3852 case GL_TEXTURE_CUBE_MAP:
3853 texture = context->getTextureCubeMap();
3854 break;
3855 default:
3856 return error(GL_INVALID_ENUM);
3857 }
3858
3859 switch (pname)
3860 {
3861 case GL_TEXTURE_WRAP_S:
3862 if (!texture->setWrapS((GLenum)param))
3863 {
3864 return error(GL_INVALID_ENUM);
3865 }
3866 break;
3867 case GL_TEXTURE_WRAP_T:
3868 if (!texture->setWrapT((GLenum)param))
3869 {
3870 return error(GL_INVALID_ENUM);
3871 }
3872 break;
3873 case GL_TEXTURE_MIN_FILTER:
3874 if (!texture->setMinFilter((GLenum)param))
3875 {
3876 return error(GL_INVALID_ENUM);
3877 }
3878 break;
3879 case GL_TEXTURE_MAG_FILTER:
3880 if (!texture->setMagFilter((GLenum)param))
3881 {
3882 return error(GL_INVALID_ENUM);
3883 }
3884 break;
3885 default:
3886 return error(GL_INVALID_ENUM);
3887 }
3888 }
3889 }
3890 catch(std::bad_alloc&)
3891 {
3892 return error(GL_OUT_OF_MEMORY);
3893 }
3894}
3895
3896void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3897{
3898 glTexParameteri(target, pname, *params);
3899}
3900
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003901void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3902 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003903{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003904 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3905 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003906 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003907 target, level, xoffset, yoffset, width, height, format, type, pixels);
3908
3909 try
3910 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003911 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
3912 {
3913 return error(GL_INVALID_ENUM);
3914 }
3915
3916 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003917 {
3918 return error(GL_INVALID_VALUE);
3919 }
3920
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003921 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
3922 {
3923 return error(GL_INVALID_VALUE);
3924 }
3925
3926 if (!es2dx::CheckTextureFormatType(format, type))
3927 {
3928 return error(GL_INVALID_ENUM);
3929 }
3930
3931 if (width == 0 || height == 0 || pixels == NULL)
3932 {
3933 return;
3934 }
3935
3936 gl::Context *context = gl::getContext();
3937
3938 if (context)
3939 {
3940 if (target == GL_TEXTURE_2D)
3941 {
3942 gl::Texture2D *texture = context->getTexture2D();
3943
3944 if (!texture)
3945 {
3946 return error(GL_INVALID_OPERATION);
3947 }
3948
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003949 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003950 }
3951 else if (es2dx::IsCubemapTextureTarget(target))
3952 {
3953 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3954
3955 if (!texture)
3956 {
3957 return error(GL_INVALID_OPERATION);
3958 }
3959
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003960 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003961 }
3962 else
3963 {
3964 UNREACHABLE();
3965 }
3966 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003967 }
3968 catch(std::bad_alloc&)
3969 {
3970 return error(GL_OUT_OF_MEMORY);
3971 }
3972}
3973
3974void __stdcall glUniform1f(GLint location, GLfloat x)
3975{
3976 glUniform1fv(location, 1, &x);
3977}
3978
3979void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
3980{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003981 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003982
3983 try
3984 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003985 if (count < 0)
3986 {
3987 return error(GL_INVALID_VALUE);
3988 }
3989
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003990 if (location == -1)
3991 {
3992 return;
3993 }
3994
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003995 gl::Context *context = gl::getContext();
3996
3997 if (context)
3998 {
3999 gl::Program *program = context->getCurrentProgram();
4000
4001 if (!program)
4002 {
4003 return error(GL_INVALID_OPERATION);
4004 }
4005
4006 if (!program->setUniform1fv(location, count, v))
4007 {
4008 return error(GL_INVALID_OPERATION);
4009 }
4010 }
4011 }
4012 catch(std::bad_alloc&)
4013 {
4014 return error(GL_OUT_OF_MEMORY);
4015 }
4016}
4017
4018void __stdcall glUniform1i(GLint location, GLint x)
4019{
4020 glUniform1iv(location, 1, &x);
4021}
4022
4023void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4024{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004025 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004026
4027 try
4028 {
4029 if (count < 0)
4030 {
4031 return error(GL_INVALID_VALUE);
4032 }
4033
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004034 if (location == -1)
4035 {
4036 return;
4037 }
4038
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004039 gl::Context *context = gl::getContext();
4040
4041 if (context)
4042 {
4043 gl::Program *program = context->getCurrentProgram();
4044
4045 if (!program)
4046 {
4047 return error(GL_INVALID_OPERATION);
4048 }
4049
4050 if (!program->setUniform1iv(location, count, v))
4051 {
4052 return error(GL_INVALID_OPERATION);
4053 }
4054 }
4055 }
4056 catch(std::bad_alloc&)
4057 {
4058 return error(GL_OUT_OF_MEMORY);
4059 }
4060}
4061
4062void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4063{
4064 GLfloat xy[2] = {x, y};
4065
4066 glUniform2fv(location, 1, (GLfloat*)&xy);
4067}
4068
4069void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4070{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004071 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004072
4073 try
4074 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004075 if (count < 0)
4076 {
4077 return error(GL_INVALID_VALUE);
4078 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004079
4080 if (location == -1)
4081 {
4082 return;
4083 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004084
4085 gl::Context *context = gl::getContext();
4086
4087 if (context)
4088 {
4089 gl::Program *program = context->getCurrentProgram();
4090
4091 if (!program)
4092 {
4093 return error(GL_INVALID_OPERATION);
4094 }
4095
4096 if (!program->setUniform2fv(location, count, v))
4097 {
4098 return error(GL_INVALID_OPERATION);
4099 }
4100 }
4101 }
4102 catch(std::bad_alloc&)
4103 {
4104 return error(GL_OUT_OF_MEMORY);
4105 }
4106}
4107
4108void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4109{
4110 GLint xy[4] = {x, y};
4111
4112 glUniform2iv(location, 1, (GLint*)&xy);
4113}
4114
4115void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4116{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004117 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004118
4119 try
4120 {
4121 if (count < 0)
4122 {
4123 return error(GL_INVALID_VALUE);
4124 }
4125
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004126 if (location == -1)
4127 {
4128 return;
4129 }
4130
4131 gl::Context *context = gl::getContext();
4132
4133 if (context)
4134 {
4135 gl::Program *program = context->getCurrentProgram();
4136
4137 if (!program)
4138 {
4139 return error(GL_INVALID_OPERATION);
4140 }
4141
4142 if (!program->setUniform2iv(location, count, v))
4143 {
4144 return error(GL_INVALID_OPERATION);
4145 }
4146 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004147 }
4148 catch(std::bad_alloc&)
4149 {
4150 return error(GL_OUT_OF_MEMORY);
4151 }
4152}
4153
4154void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4155{
4156 GLfloat xyz[3] = {x, y, z};
4157
4158 glUniform3fv(location, 1, (GLfloat*)&xyz);
4159}
4160
4161void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4162{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004163 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004164
4165 try
4166 {
4167 if (count < 0)
4168 {
4169 return error(GL_INVALID_VALUE);
4170 }
4171
4172 if (location == -1)
4173 {
4174 return;
4175 }
4176
4177 gl::Context *context = gl::getContext();
4178
4179 if (context)
4180 {
4181 gl::Program *program = context->getCurrentProgram();
4182
4183 if (!program)
4184 {
4185 return error(GL_INVALID_OPERATION);
4186 }
4187
4188 if (!program->setUniform3fv(location, count, v))
4189 {
4190 return error(GL_INVALID_OPERATION);
4191 }
4192 }
4193 }
4194 catch(std::bad_alloc&)
4195 {
4196 return error(GL_OUT_OF_MEMORY);
4197 }
4198}
4199
4200void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4201{
4202 GLint xyz[3] = {x, y, z};
4203
4204 glUniform3iv(location, 1, (GLint*)&xyz);
4205}
4206
4207void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4208{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004209 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004210
4211 try
4212 {
4213 if (count < 0)
4214 {
4215 return error(GL_INVALID_VALUE);
4216 }
4217
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004218 if (location == -1)
4219 {
4220 return;
4221 }
4222
4223 gl::Context *context = gl::getContext();
4224
4225 if (context)
4226 {
4227 gl::Program *program = context->getCurrentProgram();
4228
4229 if (!program)
4230 {
4231 return error(GL_INVALID_OPERATION);
4232 }
4233
4234 if (!program->setUniform3iv(location, count, v))
4235 {
4236 return error(GL_INVALID_OPERATION);
4237 }
4238 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004239 }
4240 catch(std::bad_alloc&)
4241 {
4242 return error(GL_OUT_OF_MEMORY);
4243 }
4244}
4245
4246void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4247{
4248 GLfloat xyzw[4] = {x, y, z, w};
4249
4250 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4251}
4252
4253void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4254{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004255 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004256
4257 try
4258 {
4259 if (count < 0)
4260 {
4261 return error(GL_INVALID_VALUE);
4262 }
4263
4264 if (location == -1)
4265 {
4266 return;
4267 }
4268
4269 gl::Context *context = gl::getContext();
4270
4271 if (context)
4272 {
4273 gl::Program *program = context->getCurrentProgram();
4274
4275 if (!program)
4276 {
4277 return error(GL_INVALID_OPERATION);
4278 }
4279
4280 if (!program->setUniform4fv(location, count, v))
4281 {
4282 return error(GL_INVALID_OPERATION);
4283 }
4284 }
4285 }
4286 catch(std::bad_alloc&)
4287 {
4288 return error(GL_OUT_OF_MEMORY);
4289 }
4290}
4291
4292void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4293{
4294 GLint xyzw[4] = {x, y, z, w};
4295
4296 glUniform4iv(location, 1, (GLint*)&xyzw);
4297}
4298
4299void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4300{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004301 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004302
4303 try
4304 {
4305 if (count < 0)
4306 {
4307 return error(GL_INVALID_VALUE);
4308 }
4309
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004310 if (location == -1)
4311 {
4312 return;
4313 }
4314
4315 gl::Context *context = gl::getContext();
4316
4317 if (context)
4318 {
4319 gl::Program *program = context->getCurrentProgram();
4320
4321 if (!program)
4322 {
4323 return error(GL_INVALID_OPERATION);
4324 }
4325
4326 if (!program->setUniform4iv(location, count, v))
4327 {
4328 return error(GL_INVALID_OPERATION);
4329 }
4330 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004331 }
4332 catch(std::bad_alloc&)
4333 {
4334 return error(GL_OUT_OF_MEMORY);
4335 }
4336}
4337
4338void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4339{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004340 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4341 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004342
4343 try
4344 {
4345 if (count < 0 || transpose != GL_FALSE)
4346 {
4347 return error(GL_INVALID_VALUE);
4348 }
4349
4350 if (location == -1)
4351 {
4352 return;
4353 }
4354
4355 gl::Context *context = gl::getContext();
4356
4357 if (context)
4358 {
4359 gl::Program *program = context->getCurrentProgram();
4360
4361 if (!program)
4362 {
4363 return error(GL_INVALID_OPERATION);
4364 }
4365
4366 if (!program->setUniformMatrix2fv(location, count, value))
4367 {
4368 return error(GL_INVALID_OPERATION);
4369 }
4370 }
4371 }
4372 catch(std::bad_alloc&)
4373 {
4374 return error(GL_OUT_OF_MEMORY);
4375 }
4376}
4377
4378void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4379{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004380 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4381 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004382
4383 try
4384 {
4385 if (count < 0 || transpose != GL_FALSE)
4386 {
4387 return error(GL_INVALID_VALUE);
4388 }
4389
4390 if (location == -1)
4391 {
4392 return;
4393 }
4394
4395 gl::Context *context = gl::getContext();
4396
4397 if (context)
4398 {
4399 gl::Program *program = context->getCurrentProgram();
4400
4401 if (!program)
4402 {
4403 return error(GL_INVALID_OPERATION);
4404 }
4405
4406 if (!program->setUniformMatrix3fv(location, count, value))
4407 {
4408 return error(GL_INVALID_OPERATION);
4409 }
4410 }
4411 }
4412 catch(std::bad_alloc&)
4413 {
4414 return error(GL_OUT_OF_MEMORY);
4415 }
4416}
4417
4418void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4419{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004420 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4421 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004422
4423 try
4424 {
4425 if (count < 0 || transpose != GL_FALSE)
4426 {
4427 return error(GL_INVALID_VALUE);
4428 }
4429
4430 if (location == -1)
4431 {
4432 return;
4433 }
4434
4435 gl::Context *context = gl::getContext();
4436
4437 if (context)
4438 {
4439 gl::Program *program = context->getCurrentProgram();
4440
4441 if (!program)
4442 {
4443 return error(GL_INVALID_OPERATION);
4444 }
4445
4446 if (!program->setUniformMatrix4fv(location, count, value))
4447 {
4448 return error(GL_INVALID_OPERATION);
4449 }
4450 }
4451 }
4452 catch(std::bad_alloc&)
4453 {
4454 return error(GL_OUT_OF_MEMORY);
4455 }
4456}
4457
4458void __stdcall glUseProgram(GLuint program)
4459{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004460 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004461
4462 try
4463 {
4464 gl::Context *context = gl::getContext();
4465
4466 if (context)
4467 {
4468 gl::Program *programObject = context->getProgram(program);
4469
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004470 if (!programObject && program != 0)
4471 {
4472 if (context->getShader(program))
4473 {
4474 return error(GL_INVALID_OPERATION);
4475 }
4476 else
4477 {
4478 return error(GL_INVALID_VALUE);
4479 }
4480 }
4481
4482 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004483 {
4484 return error(GL_INVALID_OPERATION);
4485 }
4486
4487 context->useProgram(program);
4488 }
4489 }
4490 catch(std::bad_alloc&)
4491 {
4492 return error(GL_OUT_OF_MEMORY);
4493 }
4494}
4495
4496void __stdcall glValidateProgram(GLuint program)
4497{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004498 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004499
4500 try
4501 {
4502 UNIMPLEMENTED(); // FIXME
4503 }
4504 catch(std::bad_alloc&)
4505 {
4506 return error(GL_OUT_OF_MEMORY);
4507 }
4508}
4509
4510void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4511{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004512 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004513
4514 try
4515 {
4516 if (index >= gl::MAX_VERTEX_ATTRIBS)
4517 {
4518 return error(GL_INVALID_VALUE);
4519 }
4520
4521 UNIMPLEMENTED(); // FIXME
4522 }
4523 catch(std::bad_alloc&)
4524 {
4525 return error(GL_OUT_OF_MEMORY);
4526 }
4527}
4528
4529void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4530{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004531 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004532
4533 try
4534 {
4535 if (index >= gl::MAX_VERTEX_ATTRIBS)
4536 {
4537 return error(GL_INVALID_VALUE);
4538 }
4539
4540 UNIMPLEMENTED(); // FIXME
4541 }
4542 catch(std::bad_alloc&)
4543 {
4544 return error(GL_OUT_OF_MEMORY);
4545 }
4546}
4547
4548void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4549{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004550 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004551
4552 try
4553 {
4554 if (index >= gl::MAX_VERTEX_ATTRIBS)
4555 {
4556 return error(GL_INVALID_VALUE);
4557 }
4558
4559 UNIMPLEMENTED(); // FIXME
4560 }
4561 catch(std::bad_alloc&)
4562 {
4563 return error(GL_OUT_OF_MEMORY);
4564 }
4565}
4566
4567void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4568{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004569 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004570
4571 try
4572 {
4573 if (index >= gl::MAX_VERTEX_ATTRIBS)
4574 {
4575 return error(GL_INVALID_VALUE);
4576 }
4577
4578 UNIMPLEMENTED(); // FIXME
4579 }
4580 catch(std::bad_alloc&)
4581 {
4582 return error(GL_OUT_OF_MEMORY);
4583 }
4584}
4585
4586void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4587{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004588 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 +00004589
4590 try
4591 {
4592 if (index >= gl::MAX_VERTEX_ATTRIBS)
4593 {
4594 return error(GL_INVALID_VALUE);
4595 }
4596
4597 UNIMPLEMENTED(); // FIXME
4598 }
4599 catch(std::bad_alloc&)
4600 {
4601 return error(GL_OUT_OF_MEMORY);
4602 }
4603}
4604
4605void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4606{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004607 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004608
4609 try
4610 {
4611 if (index >= gl::MAX_VERTEX_ATTRIBS)
4612 {
4613 return error(GL_INVALID_VALUE);
4614 }
4615
4616 UNIMPLEMENTED(); // FIXME
4617 }
4618 catch(std::bad_alloc&)
4619 {
4620 return error(GL_OUT_OF_MEMORY);
4621 }
4622}
4623
4624void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4625{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004626 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 +00004627
4628 try
4629 {
4630 if (index >= gl::MAX_VERTEX_ATTRIBS)
4631 {
4632 return error(GL_INVALID_VALUE);
4633 }
4634
4635 UNIMPLEMENTED(); // FIXME
4636 }
4637 catch(std::bad_alloc&)
4638 {
4639 return error(GL_OUT_OF_MEMORY);
4640 }
4641}
4642
4643void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4644{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004645 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
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 UNIMPLEMENTED(); // FIXME
4655 }
4656 catch(std::bad_alloc&)
4657 {
4658 return error(GL_OUT_OF_MEMORY);
4659 }
4660}
4661
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004662void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004663{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004664 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004665 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004666 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004667
4668 try
4669 {
4670 if (index >= gl::MAX_VERTEX_ATTRIBS)
4671 {
4672 return error(GL_INVALID_VALUE);
4673 }
4674
4675 if (size < 1 || size > 4)
4676 {
4677 return error(GL_INVALID_VALUE);
4678 }
4679
4680 switch (type)
4681 {
4682 case GL_BYTE:
4683 case GL_UNSIGNED_BYTE:
4684 case GL_SHORT:
4685 case GL_UNSIGNED_SHORT:
4686 case GL_FIXED:
4687 case GL_FLOAT:
4688 break;
4689 default:
4690 return error(GL_INVALID_ENUM);
4691 }
4692
4693 if (stride < 0)
4694 {
4695 return error(GL_INVALID_VALUE);
4696 }
4697
4698 gl::Context *context = gl::getContext();
4699
4700 if (context)
4701 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004702 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4703 context->vertexAttribute[index].mSize = size;
4704 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004705 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004706 context->vertexAttribute[index].mStride = stride;
4707 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004708 }
4709 }
4710 catch(std::bad_alloc&)
4711 {
4712 return error(GL_OUT_OF_MEMORY);
4713 }
4714}
4715
4716void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4717{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004718 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 +00004719
4720 try
4721 {
4722 if (width < 0 || height < 0)
4723 {
4724 return error(GL_INVALID_VALUE);
4725 }
4726
4727 gl::Context *context = gl::getContext();
4728
4729 if (context)
4730 {
4731 context->viewportX = x;
4732 context->viewportY = y;
4733 context->viewportWidth = width;
4734 context->viewportHeight = height;
4735 }
4736 }
4737 catch(std::bad_alloc&)
4738 {
4739 return error(GL_OUT_OF_MEMORY);
4740 }
4741}
4742
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004743void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4744 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004745{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004746 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4747 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004748 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004749 target, level, internalformat, width, height, depth, border, format, type, pixels);
4750
4751 try
4752 {
4753 UNIMPLEMENTED(); // FIXME
4754 }
4755 catch(std::bad_alloc&)
4756 {
4757 return error(GL_OUT_OF_MEMORY);
4758 }
4759}
4760}