blob: d3930411655e8c9d6902d8251989254fad349ad4 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000017
18#include "libGLESv2/main.h"
19#include "libGLESv2/mathutil.h"
20#include "libGLESv2/utilities.h"
21#include "libGLESv2/Buffer.h"
22#include "libGLESv2/Context.h"
23#include "libGLESv2/Framebuffer.h"
24#include "libGLESv2/Program.h"
25#include "libGLESv2/Renderbuffer.h"
26#include "libGLESv2/Shader.h"
27#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000028
29extern "C"
30{
31
32void __stdcall glActiveTexture(GLenum texture)
33{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000034 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035
36 try
37 {
38 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
39 {
40 return error(GL_INVALID_ENUM);
41 }
42
43 gl::Context *context = gl::getContext();
44
45 if (context)
46 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +000047 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000048 }
49 }
50 catch(std::bad_alloc&)
51 {
52 return error(GL_OUT_OF_MEMORY);
53 }
54}
55
56void __stdcall glAttachShader(GLuint program, GLuint shader)
57{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000058 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000059
60 try
61 {
62 gl::Context *context = gl::getContext();
63
64 if (context)
65 {
66 gl::Program *programObject = context->getProgram(program);
67 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000068
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000069 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000071 if (context->getShader(program))
72 {
73 return error(GL_INVALID_OPERATION);
74 }
75 else
76 {
77 return error(GL_INVALID_VALUE);
78 }
79 }
80
81 if (!shaderObject)
82 {
83 if (context->getProgram(shader))
84 {
85 return error(GL_INVALID_OPERATION);
86 }
87 else
88 {
89 return error(GL_INVALID_VALUE);
90 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000091 }
92
93 if (!programObject->attachShader(shaderObject))
94 {
95 return error(GL_INVALID_OPERATION);
96 }
97 }
98 }
99 catch(std::bad_alloc&)
100 {
101 return error(GL_OUT_OF_MEMORY);
102 }
103}
104
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000105void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000106{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000107 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108
109 try
110 {
111 if (index >= gl::MAX_VERTEX_ATTRIBS)
112 {
113 return error(GL_INVALID_VALUE);
114 }
115
116 gl::Context *context = gl::getContext();
117
118 if (context)
119 {
120 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000121
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000122 if (!programObject)
123 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000124 if (context->getShader(program))
125 {
126 return error(GL_INVALID_OPERATION);
127 }
128 else
129 {
130 return error(GL_INVALID_VALUE);
131 }
132 }
133
134 if (strncmp(name, "gl_", 3) == 0)
135 {
136 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137 }
138
139 programObject->bindAttributeLocation(index, name);
140 }
141 }
142 catch(std::bad_alloc&)
143 {
144 return error(GL_OUT_OF_MEMORY);
145 }
146}
147
148void __stdcall glBindBuffer(GLenum target, GLuint buffer)
149{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000150 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000151
152 try
153 {
154 gl::Context *context = gl::getContext();
155
156 if (context)
157 {
158 switch (target)
159 {
160 case GL_ARRAY_BUFFER:
161 context->bindArrayBuffer(buffer);
162 return;
163 case GL_ELEMENT_ARRAY_BUFFER:
164 context->bindElementArrayBuffer(buffer);
165 return;
166 default:
167 return error(GL_INVALID_ENUM);
168 }
169 }
170 }
171 catch(std::bad_alloc&)
172 {
173 return error(GL_OUT_OF_MEMORY);
174 }
175}
176
177void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
178{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000179 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000180
181 try
182 {
183 if (target != GL_FRAMEBUFFER)
184 {
185 return error(GL_INVALID_ENUM);
186 }
187
188 gl::Context *context = gl::getContext();
189
190 if (context)
191 {
192 context->bindFramebuffer(framebuffer);
193 }
194 }
195 catch(std::bad_alloc&)
196 {
197 return error(GL_OUT_OF_MEMORY);
198 }
199}
200
201void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
202{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000203 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204
205 try
206 {
207 if (target != GL_RENDERBUFFER)
208 {
209 return error(GL_INVALID_ENUM);
210 }
211
212 gl::Context *context = gl::getContext();
213
214 if (context)
215 {
216 context->bindRenderbuffer(renderbuffer);
217 }
218 }
219 catch(std::bad_alloc&)
220 {
221 return error(GL_OUT_OF_MEMORY);
222 }
223}
224
225void __stdcall glBindTexture(GLenum target, GLuint texture)
226{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000227 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228
229 try
230 {
231 gl::Context *context = gl::getContext();
232
233 if (context)
234 {
235 gl::Texture *textureObject = context->getTexture(texture);
236
237 if (textureObject && textureObject->getTarget() != target && texture != 0)
238 {
239 return error(GL_INVALID_OPERATION);
240 }
241
242 switch (target)
243 {
244 case GL_TEXTURE_2D:
245 context->bindTexture2D(texture);
246 return;
247 case GL_TEXTURE_CUBE_MAP:
248 context->bindTextureCubeMap(texture);
249 return;
250 default:
251 return error(GL_INVALID_ENUM);
252 }
253 }
254 }
255 catch(std::bad_alloc&)
256 {
257 return error(GL_OUT_OF_MEMORY);
258 }
259}
260
261void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
262{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000263 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
264 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000265
266 try
267 {
268 gl::Context* context = gl::getContext();
269
270 if (context)
271 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000272 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000273 }
274 }
275 catch(std::bad_alloc&)
276 {
277 return error(GL_OUT_OF_MEMORY);
278 }
279}
280
281void __stdcall glBlendEquation(GLenum mode)
282{
283 glBlendEquationSeparate(mode, mode);
284}
285
286void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
287{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000288 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000289
290 try
291 {
292 switch (modeRGB)
293 {
294 case GL_FUNC_ADD:
295 case GL_FUNC_SUBTRACT:
296 case GL_FUNC_REVERSE_SUBTRACT:
297 break;
298 default:
299 return error(GL_INVALID_ENUM);
300 }
301
302 switch (modeAlpha)
303 {
304 case GL_FUNC_ADD:
305 case GL_FUNC_SUBTRACT:
306 case GL_FUNC_REVERSE_SUBTRACT:
307 break;
308 default:
309 return error(GL_INVALID_ENUM);
310 }
311
312 gl::Context *context = gl::getContext();
313
314 if (context)
315 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000316 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000317 }
318 }
319 catch(std::bad_alloc&)
320 {
321 return error(GL_OUT_OF_MEMORY);
322 }
323}
324
325void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
326{
327 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
328}
329
330void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
331{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000332 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
333 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000334
335 try
336 {
337 switch (srcRGB)
338 {
339 case GL_ZERO:
340 case GL_ONE:
341 case GL_SRC_COLOR:
342 case GL_ONE_MINUS_SRC_COLOR:
343 case GL_DST_COLOR:
344 case GL_ONE_MINUS_DST_COLOR:
345 case GL_SRC_ALPHA:
346 case GL_ONE_MINUS_SRC_ALPHA:
347 case GL_DST_ALPHA:
348 case GL_ONE_MINUS_DST_ALPHA:
349 case GL_CONSTANT_COLOR:
350 case GL_ONE_MINUS_CONSTANT_COLOR:
351 case GL_CONSTANT_ALPHA:
352 case GL_ONE_MINUS_CONSTANT_ALPHA:
353 case GL_SRC_ALPHA_SATURATE:
354 break;
355 default:
356 return error(GL_INVALID_ENUM);
357 }
358
359 switch (dstRGB)
360 {
361 case GL_ZERO:
362 case GL_ONE:
363 case GL_SRC_COLOR:
364 case GL_ONE_MINUS_SRC_COLOR:
365 case GL_DST_COLOR:
366 case GL_ONE_MINUS_DST_COLOR:
367 case GL_SRC_ALPHA:
368 case GL_ONE_MINUS_SRC_ALPHA:
369 case GL_DST_ALPHA:
370 case GL_ONE_MINUS_DST_ALPHA:
371 case GL_CONSTANT_COLOR:
372 case GL_ONE_MINUS_CONSTANT_COLOR:
373 case GL_CONSTANT_ALPHA:
374 case GL_ONE_MINUS_CONSTANT_ALPHA:
375 break;
376 default:
377 return error(GL_INVALID_ENUM);
378 }
379
380 switch (srcAlpha)
381 {
382 case GL_ZERO:
383 case GL_ONE:
384 case GL_SRC_COLOR:
385 case GL_ONE_MINUS_SRC_COLOR:
386 case GL_DST_COLOR:
387 case GL_ONE_MINUS_DST_COLOR:
388 case GL_SRC_ALPHA:
389 case GL_ONE_MINUS_SRC_ALPHA:
390 case GL_DST_ALPHA:
391 case GL_ONE_MINUS_DST_ALPHA:
392 case GL_CONSTANT_COLOR:
393 case GL_ONE_MINUS_CONSTANT_COLOR:
394 case GL_CONSTANT_ALPHA:
395 case GL_ONE_MINUS_CONSTANT_ALPHA:
396 case GL_SRC_ALPHA_SATURATE:
397 break;
398 default:
399 return error(GL_INVALID_ENUM);
400 }
401
402 switch (dstAlpha)
403 {
404 case GL_ZERO:
405 case GL_ONE:
406 case GL_SRC_COLOR:
407 case GL_ONE_MINUS_SRC_COLOR:
408 case GL_DST_COLOR:
409 case GL_ONE_MINUS_DST_COLOR:
410 case GL_SRC_ALPHA:
411 case GL_ONE_MINUS_SRC_ALPHA:
412 case GL_DST_ALPHA:
413 case GL_ONE_MINUS_DST_ALPHA:
414 case GL_CONSTANT_COLOR:
415 case GL_ONE_MINUS_CONSTANT_COLOR:
416 case GL_CONSTANT_ALPHA:
417 case GL_ONE_MINUS_CONSTANT_ALPHA:
418 break;
419 default:
420 return error(GL_INVALID_ENUM);
421 }
422
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000423 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
424 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
425
426 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
427 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
428
429 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000430 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000431 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
432 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000433 }
434
435 gl::Context *context = gl::getContext();
436
437 if (context)
438 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000439 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000440 }
441 }
442 catch(std::bad_alloc&)
443 {
444 return error(GL_OUT_OF_MEMORY);
445 }
446}
447
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000448void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000449{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000450 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 +0000451 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000452
453 try
454 {
455 if (size < 0)
456 {
457 return error(GL_INVALID_VALUE);
458 }
459
460 switch (usage)
461 {
462 case GL_STREAM_DRAW:
463 case GL_STATIC_DRAW:
464 case GL_DYNAMIC_DRAW:
465 break;
466 default:
467 return error(GL_INVALID_ENUM);
468 }
469
470 gl::Context *context = gl::getContext();
471
472 if (context)
473 {
474 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000475
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000476 switch (target)
477 {
478 case GL_ARRAY_BUFFER:
479 buffer = context->getArrayBuffer();
480 break;
481 case GL_ELEMENT_ARRAY_BUFFER:
482 buffer = context->getElementArrayBuffer();
483 break;
484 default:
485 return error(GL_INVALID_ENUM);
486 }
487
488 if (!buffer)
489 {
490 return error(GL_INVALID_OPERATION);
491 }
492
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000493 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000494 }
495 }
496 catch(std::bad_alloc&)
497 {
498 return error(GL_OUT_OF_MEMORY);
499 }
500}
501
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000502void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000503{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000504 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 +0000505 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000506
507 try
508 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000509 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000510 {
511 return error(GL_INVALID_VALUE);
512 }
513
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000514 if (data == NULL)
515 {
516 return;
517 }
518
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000519 gl::Context *context = gl::getContext();
520
521 if (context)
522 {
523 gl::Buffer *buffer;
524
525 switch (target)
526 {
527 case GL_ARRAY_BUFFER:
528 buffer = context->getArrayBuffer();
529 break;
530 case GL_ELEMENT_ARRAY_BUFFER:
531 buffer = context->getElementArrayBuffer();
532 break;
533 default:
534 return error(GL_INVALID_ENUM);
535 }
536
537 if (!buffer)
538 {
539 return error(GL_INVALID_OPERATION);
540 }
541
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000542 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000543 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000544 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000545 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000546
547 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000548 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000549 }
550 catch(std::bad_alloc&)
551 {
552 return error(GL_OUT_OF_MEMORY);
553 }
554}
555
556GLenum __stdcall glCheckFramebufferStatus(GLenum target)
557{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000558 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000559
560 try
561 {
562 if (target != GL_FRAMEBUFFER)
563 {
564 return error(GL_INVALID_ENUM, 0);
565 }
566
567 gl::Context *context = gl::getContext();
568
569 if (context)
570 {
571 gl::Framebuffer *framebuffer = context->getFramebuffer();
572
573 return framebuffer->completeness();
574 }
575 }
576 catch(std::bad_alloc&)
577 {
578 return error(GL_OUT_OF_MEMORY, 0);
579 }
580
581 return 0;
582}
583
584void __stdcall glClear(GLbitfield mask)
585{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000586 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000587
588 try
589 {
590 gl::Context *context = gl::getContext();
591
592 if (context)
593 {
594 context->clear(mask);
595 }
596 }
597 catch(std::bad_alloc&)
598 {
599 return error(GL_OUT_OF_MEMORY);
600 }
601}
602
603void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
604{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000605 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
606 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000607
608 try
609 {
610 gl::Context *context = gl::getContext();
611
612 if (context)
613 {
614 context->setClearColor(red, green, blue, alpha);
615 }
616 }
617 catch(std::bad_alloc&)
618 {
619 return error(GL_OUT_OF_MEMORY);
620 }
621}
622
623void __stdcall glClearDepthf(GLclampf depth)
624{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000625 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000626
627 try
628 {
629 gl::Context *context = gl::getContext();
630
631 if (context)
632 {
633 context->setClearDepth(depth);
634 }
635 }
636 catch(std::bad_alloc&)
637 {
638 return error(GL_OUT_OF_MEMORY);
639 }
640}
641
642void __stdcall glClearStencil(GLint s)
643{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000644 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000645
646 try
647 {
648 gl::Context *context = gl::getContext();
649
650 if (context)
651 {
652 context->setClearStencil(s);
653 }
654 }
655 catch(std::bad_alloc&)
656 {
657 return error(GL_OUT_OF_MEMORY);
658 }
659}
660
661void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
662{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000663 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
664 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000665
666 try
667 {
668 gl::Context *context = gl::getContext();
669
670 if (context)
671 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000672 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000673 }
674 }
675 catch(std::bad_alloc&)
676 {
677 return error(GL_OUT_OF_MEMORY);
678 }
679}
680
681void __stdcall glCompileShader(GLuint shader)
682{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000683 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000684
685 try
686 {
687 gl::Context *context = gl::getContext();
688
689 if (context)
690 {
691 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000692
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000693 if (!shaderObject)
694 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000695 if (context->getProgram(shader))
696 {
697 return error(GL_INVALID_OPERATION);
698 }
699 else
700 {
701 return error(GL_INVALID_VALUE);
702 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000703 }
704
705 shaderObject->compile();
706 }
707 }
708 catch(std::bad_alloc&)
709 {
710 return error(GL_OUT_OF_MEMORY);
711 }
712}
713
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000714void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
715 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000716{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000717 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000718 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000719 target, level, internalformat, width, height, border, imageSize, data);
720
721 try
722 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000723 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000724 {
725 return error(GL_INVALID_ENUM);
726 }
727
728 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000729 {
730 return error(GL_INVALID_VALUE);
731 }
732
daniel@transgaming.com41430492010-03-11 20:36:18 +0000733 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
734 {
735 return error(GL_INVALID_VALUE);
736 }
737
738 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000739 }
740 catch(std::bad_alloc&)
741 {
742 return error(GL_OUT_OF_MEMORY);
743 }
744}
745
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000746void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
747 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000749 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
750 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000751 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000752 target, level, xoffset, yoffset, width, height, format, imageSize, data);
753
754 try
755 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000756 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000757 {
758 return error(GL_INVALID_ENUM);
759 }
760
761 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000762 {
763 return error(GL_INVALID_VALUE);
764 }
765
daniel@transgaming.com41430492010-03-11 20:36:18 +0000766 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
767 {
768 return error(GL_INVALID_VALUE);
769 }
770
771 if (xoffset != 0 || yoffset != 0)
772 {
773 return error(GL_INVALID_OPERATION);
774 }
775
776 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000777 }
778 catch(std::bad_alloc&)
779 {
780 return error(GL_OUT_OF_MEMORY);
781 }
782}
783
784void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
785{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000786 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
787 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000788 target, level, internalformat, x, y, width, height, border);
789
790 try
791 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000792 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000793 {
794 return error(GL_INVALID_VALUE);
795 }
796
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000797 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
798 {
799 return error(GL_INVALID_VALUE);
800 }
801
802 switch (target)
803 {
804 case GL_TEXTURE_2D:
805 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
806 {
807 return error(GL_INVALID_VALUE);
808 }
809 break;
810 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
811 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
812 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
813 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
814 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
815 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +0000816 if (width != height)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000817 {
818 return error(GL_INVALID_VALUE);
819 }
820
821 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
822 {
823 return error(GL_INVALID_VALUE);
824 }
825 break;
826 default:
827 return error(GL_INVALID_ENUM);
828 }
829
830 switch (internalformat)
831 {
832 case GL_ALPHA:
833 case GL_LUMINANCE:
834 case GL_LUMINANCE_ALPHA:
835 case GL_RGB:
836 case GL_RGBA:
837 break;
838 default:
839 return error(GL_INVALID_VALUE);
840 }
841
842 if (border != 0)
843 {
844 return error(GL_INVALID_VALUE);
845 }
846
847 gl::Context *context = gl::getContext();
848
849 if (context)
850 {
daniel@transgaming.combbc57792010-07-28 19:21:05 +0000851 gl::Framebuffer *framebuffer = context->getFramebuffer();
852 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
853 {
854 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
855 }
856
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000857 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000858 if (target == GL_TEXTURE_2D)
859 {
860 gl::Texture2D *texture = context->getTexture2D();
861
862 if (!texture)
863 {
864 return error(GL_INVALID_OPERATION);
865 }
866
867 texture->copyImage(level, internalformat, x, y, width, height, source);
868 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000869 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000870 {
871 gl::TextureCubeMap *texture = context->getTextureCubeMap();
872
873 if (!texture)
874 {
875 return error(GL_INVALID_OPERATION);
876 }
877
878 texture->copyImage(target, level, internalformat, x, y, width, height, source);
879 }
880 else
881 {
882 UNREACHABLE();
883 }
884 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000885 }
886 catch(std::bad_alloc&)
887 {
888 return error(GL_OUT_OF_MEMORY);
889 }
890}
891
892void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
893{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000894 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
895 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000896 target, level, xoffset, yoffset, x, y, width, height);
897
898 try
899 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000900 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000901 {
902 return error(GL_INVALID_ENUM);
903 }
904
905 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000906 {
907 return error(GL_INVALID_VALUE);
908 }
909
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000910 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
911 {
912 return error(GL_INVALID_VALUE);
913 }
914
915 if (width == 0 || height == 0)
916 {
917 return;
918 }
919
920 gl::Context *context = gl::getContext();
921
922 if (context)
923 {
daniel@transgaming.combbc57792010-07-28 19:21:05 +0000924 gl::Framebuffer *framebuffer = context->getFramebuffer();
925 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
926 {
927 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
928 }
929
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000930 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000931 if (target == GL_TEXTURE_2D)
932 {
933 gl::Texture2D *texture = context->getTexture2D();
934
935 if (!texture)
936 {
937 return error(GL_INVALID_OPERATION);
938 }
939
940 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
941 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000942 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000943 {
944 gl::TextureCubeMap *texture = context->getTextureCubeMap();
945
946 if (!texture)
947 {
948 return error(GL_INVALID_OPERATION);
949 }
950
951 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
952 }
953 else
954 {
955 UNREACHABLE();
956 }
957 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000958 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000959
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000960 catch(std::bad_alloc&)
961 {
962 return error(GL_OUT_OF_MEMORY);
963 }
964}
965
966GLuint __stdcall glCreateProgram(void)
967{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000968 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000969
970 try
971 {
972 gl::Context *context = gl::getContext();
973
974 if (context)
975 {
976 return context->createProgram();
977 }
978 }
979 catch(std::bad_alloc&)
980 {
981 return error(GL_OUT_OF_MEMORY, 0);
982 }
983
984 return 0;
985}
986
987GLuint __stdcall glCreateShader(GLenum type)
988{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000989 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000990
991 try
992 {
993 gl::Context *context = gl::getContext();
994
995 if (context)
996 {
997 switch (type)
998 {
999 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001000 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001001 return context->createShader(type);
1002 default:
1003 return error(GL_INVALID_ENUM, 0);
1004 }
1005 }
1006 }
1007 catch(std::bad_alloc&)
1008 {
1009 return error(GL_OUT_OF_MEMORY, 0);
1010 }
1011
1012 return 0;
1013}
1014
1015void __stdcall glCullFace(GLenum mode)
1016{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001017 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001018
1019 try
1020 {
1021 switch (mode)
1022 {
1023 case GL_FRONT:
1024 case GL_BACK:
1025 case GL_FRONT_AND_BACK:
1026 {
1027 gl::Context *context = gl::getContext();
1028
1029 if (context)
1030 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001031 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001032 }
1033 }
1034 break;
1035 default:
1036 return error(GL_INVALID_ENUM);
1037 }
1038 }
1039 catch(std::bad_alloc&)
1040 {
1041 return error(GL_OUT_OF_MEMORY);
1042 }
1043}
1044
1045void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1046{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001047 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001048
1049 try
1050 {
1051 if (n < 0)
1052 {
1053 return error(GL_INVALID_VALUE);
1054 }
1055
1056 gl::Context *context = gl::getContext();
1057
1058 if (context)
1059 {
1060 for (int i = 0; i < n; i++)
1061 {
1062 context->deleteBuffer(buffers[i]);
1063 }
1064 }
1065 }
1066 catch(std::bad_alloc&)
1067 {
1068 return error(GL_OUT_OF_MEMORY);
1069 }
1070}
1071
1072void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1073{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001074 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001075
1076 try
1077 {
1078 if (n < 0)
1079 {
1080 return error(GL_INVALID_VALUE);
1081 }
1082
1083 gl::Context *context = gl::getContext();
1084
1085 if (context)
1086 {
1087 for (int i = 0; i < n; i++)
1088 {
1089 if (framebuffers[i] != 0)
1090 {
1091 context->deleteFramebuffer(framebuffers[i]);
1092 }
1093 }
1094 }
1095 }
1096 catch(std::bad_alloc&)
1097 {
1098 return error(GL_OUT_OF_MEMORY);
1099 }
1100}
1101
1102void __stdcall glDeleteProgram(GLuint program)
1103{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001104 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001105
1106 try
1107 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001108 if (program == 0)
1109 {
1110 return;
1111 }
1112
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001113 gl::Context *context = gl::getContext();
1114
1115 if (context)
1116 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001117 if (!context->getProgram(program))
1118 {
1119 if(context->getShader(program))
1120 {
1121 return error(GL_INVALID_OPERATION);
1122 }
1123 else
1124 {
1125 return error(GL_INVALID_VALUE);
1126 }
1127 }
1128
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001129 context->deleteProgram(program);
1130 }
1131 }
1132 catch(std::bad_alloc&)
1133 {
1134 return error(GL_OUT_OF_MEMORY);
1135 }
1136}
1137
1138void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1139{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001140 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001141
1142 try
1143 {
1144 if (n < 0)
1145 {
1146 return error(GL_INVALID_VALUE);
1147 }
1148
1149 gl::Context *context = gl::getContext();
1150
1151 if (context)
1152 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001153 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001154 {
1155 context->deleteRenderbuffer(renderbuffers[i]);
1156 }
1157 }
1158 }
1159 catch(std::bad_alloc&)
1160 {
1161 return error(GL_OUT_OF_MEMORY);
1162 }
1163}
1164
1165void __stdcall glDeleteShader(GLuint shader)
1166{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001167 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001168
1169 try
1170 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001171 if (shader == 0)
1172 {
1173 return;
1174 }
1175
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001176 gl::Context *context = gl::getContext();
1177
1178 if (context)
1179 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001180 if (!context->getShader(shader))
1181 {
1182 if(context->getProgram(shader))
1183 {
1184 return error(GL_INVALID_OPERATION);
1185 }
1186 else
1187 {
1188 return error(GL_INVALID_VALUE);
1189 }
1190 }
1191
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001192 context->deleteShader(shader);
1193 }
1194 }
1195 catch(std::bad_alloc&)
1196 {
1197 return error(GL_OUT_OF_MEMORY);
1198 }
1199}
1200
1201void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1202{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001203 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001204
1205 try
1206 {
1207 if (n < 0)
1208 {
1209 return error(GL_INVALID_VALUE);
1210 }
1211
1212 gl::Context *context = gl::getContext();
1213
1214 if (context)
1215 {
1216 for (int i = 0; i < n; i++)
1217 {
1218 if (textures[i] != 0)
1219 {
1220 context->deleteTexture(textures[i]);
1221 }
1222 }
1223 }
1224 }
1225 catch(std::bad_alloc&)
1226 {
1227 return error(GL_OUT_OF_MEMORY);
1228 }
1229}
1230
1231void __stdcall glDepthFunc(GLenum func)
1232{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001233 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001234
1235 try
1236 {
1237 switch (func)
1238 {
1239 case GL_NEVER:
1240 case GL_ALWAYS:
1241 case GL_LESS:
1242 case GL_LEQUAL:
1243 case GL_EQUAL:
1244 case GL_GREATER:
1245 case GL_GEQUAL:
1246 case GL_NOTEQUAL:
1247 break;
1248 default:
1249 return error(GL_INVALID_ENUM);
1250 }
1251
1252 gl::Context *context = gl::getContext();
1253
1254 if (context)
1255 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001256 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001257 }
1258 }
1259 catch(std::bad_alloc&)
1260 {
1261 return error(GL_OUT_OF_MEMORY);
1262 }
1263}
1264
1265void __stdcall glDepthMask(GLboolean flag)
1266{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001267 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001268
1269 try
1270 {
1271 gl::Context *context = gl::getContext();
1272
1273 if (context)
1274 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001275 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001276 }
1277 }
1278 catch(std::bad_alloc&)
1279 {
1280 return error(GL_OUT_OF_MEMORY);
1281 }
1282}
1283
1284void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1285{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001286 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001287
1288 try
1289 {
1290 gl::Context *context = gl::getContext();
1291
1292 if (context)
1293 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001294 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001295 }
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 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001348 }
1349 }
1350 catch(std::bad_alloc&)
1351 {
1352 return error(GL_OUT_OF_MEMORY);
1353 }
1354}
1355
1356void __stdcall glDisable(GLenum cap)
1357{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001358 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001359
1360 try
1361 {
1362 gl::Context *context = gl::getContext();
1363
1364 if (context)
1365 {
1366 switch (cap)
1367 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001368 case GL_CULL_FACE: context->setCullFace(false); break;
1369 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1370 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1371 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1372 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1373 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1374 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1375 case GL_BLEND: context->setBlend(false); break;
1376 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001377 default:
1378 return error(GL_INVALID_ENUM);
1379 }
1380 }
1381 }
1382 catch(std::bad_alloc&)
1383 {
1384 return error(GL_OUT_OF_MEMORY);
1385 }
1386}
1387
1388void __stdcall glDisableVertexAttribArray(GLuint index)
1389{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001390 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001391
1392 try
1393 {
1394 if (index >= gl::MAX_VERTEX_ATTRIBS)
1395 {
1396 return error(GL_INVALID_VALUE);
1397 }
1398
1399 gl::Context *context = gl::getContext();
1400
1401 if (context)
1402 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001403 context->setVertexAttribEnabled(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001404 }
1405 }
1406 catch(std::bad_alloc&)
1407 {
1408 return error(GL_OUT_OF_MEMORY);
1409 }
1410}
1411
1412void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1413{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001414 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001415
1416 try
1417 {
1418 if (count < 0 || first < 0)
1419 {
1420 return error(GL_INVALID_VALUE);
1421 }
1422
1423 gl::Context *context = gl::getContext();
1424
1425 if (context)
1426 {
1427 context->drawArrays(mode, first, count);
1428 }
1429 }
1430 catch(std::bad_alloc&)
1431 {
1432 return error(GL_OUT_OF_MEMORY);
1433 }
1434}
1435
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001436void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001437{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001438 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 +00001439 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001440
1441 try
1442 {
1443 if (count < 0)
1444 {
1445 return error(GL_INVALID_VALUE);
1446 }
1447
1448 switch (type)
1449 {
1450 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001451 case GL_UNSIGNED_SHORT:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00001452 case GL_UNSIGNED_INT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001453 break;
1454 default:
1455 return error(GL_INVALID_ENUM);
1456 }
1457
1458 gl::Context *context = gl::getContext();
1459
1460 if (context)
1461 {
1462 context->drawElements(mode, count, type, indices);
1463 }
1464 }
1465 catch(std::bad_alloc&)
1466 {
1467 return error(GL_OUT_OF_MEMORY);
1468 }
1469}
1470
1471void __stdcall glEnable(GLenum cap)
1472{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001473 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001474
1475 try
1476 {
1477 gl::Context *context = gl::getContext();
1478
1479 if (context)
1480 {
1481 switch (cap)
1482 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001483 case GL_CULL_FACE: context->setCullFace(true); break;
1484 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1485 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1486 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1487 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1488 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1489 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1490 case GL_BLEND: context->setBlend(true); break;
1491 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001492 default:
1493 return error(GL_INVALID_ENUM);
1494 }
1495 }
1496 }
1497 catch(std::bad_alloc&)
1498 {
1499 return error(GL_OUT_OF_MEMORY);
1500 }
1501}
1502
1503void __stdcall glEnableVertexAttribArray(GLuint index)
1504{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001505 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001506
1507 try
1508 {
1509 if (index >= gl::MAX_VERTEX_ATTRIBS)
1510 {
1511 return error(GL_INVALID_VALUE);
1512 }
1513
1514 gl::Context *context = gl::getContext();
1515
1516 if (context)
1517 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001518 context->setVertexAttribEnabled(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001519 }
1520 }
1521 catch(std::bad_alloc&)
1522 {
1523 return error(GL_OUT_OF_MEMORY);
1524 }
1525}
1526
1527void __stdcall glFinish(void)
1528{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001529 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001530
1531 try
1532 {
1533 gl::Context *context = gl::getContext();
1534
1535 if (context)
1536 {
1537 context->finish();
1538 }
1539 }
1540 catch(std::bad_alloc&)
1541 {
1542 return error(GL_OUT_OF_MEMORY);
1543 }
1544}
1545
1546void __stdcall glFlush(void)
1547{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001548 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001549
1550 try
1551 {
1552 gl::Context *context = gl::getContext();
1553
1554 if (context)
1555 {
1556 context->flush();
1557 }
1558 }
1559 catch(std::bad_alloc&)
1560 {
1561 return error(GL_OUT_OF_MEMORY);
1562 }
1563}
1564
1565void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1566{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001567 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1568 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001569
1570 try
1571 {
1572 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1573 {
1574 return error(GL_INVALID_ENUM);
1575 }
1576
1577 gl::Context *context = gl::getContext();
1578
1579 if (context)
1580 {
1581 gl::Framebuffer *framebuffer = context->getFramebuffer();
1582
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001583 if (context->getFramebufferHandle() == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001584 {
1585 return error(GL_INVALID_OPERATION);
1586 }
1587
1588 switch (attachment)
1589 {
1590 case GL_COLOR_ATTACHMENT0:
1591 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1592 break;
1593 case GL_DEPTH_ATTACHMENT:
1594 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1595 break;
1596 case GL_STENCIL_ATTACHMENT:
1597 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1598 break;
1599 default:
1600 return error(GL_INVALID_ENUM);
1601 }
1602 }
1603 }
1604 catch(std::bad_alloc&)
1605 {
1606 return error(GL_OUT_OF_MEMORY);
1607 }
1608}
1609
1610void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1611{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001612 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1613 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001614
1615 try
1616 {
1617 if (target != GL_FRAMEBUFFER)
1618 {
1619 return error(GL_INVALID_ENUM);
1620 }
1621
1622 switch (attachment)
1623 {
1624 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001625 case GL_DEPTH_ATTACHMENT:
1626 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001627 break;
1628 default:
1629 return error(GL_INVALID_ENUM);
1630 }
1631
1632 gl::Context *context = gl::getContext();
1633
1634 if (context)
1635 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001636 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001637 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001638 textarget = GL_NONE;
1639 }
1640 else
1641 {
1642 gl::Texture *tex = context->getTexture(texture);
1643
1644 if (tex == NULL)
1645 {
1646 return error(GL_INVALID_OPERATION);
1647 }
1648
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001649 switch (textarget)
1650 {
1651 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001652 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001653 {
1654 return error(GL_INVALID_OPERATION);
1655 }
1656 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001657
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001658 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001659 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001660 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001661 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001662 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001663 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001664 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1665 {
1666 return error(GL_INVALID_OPERATION);
1667 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001668 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001669
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001670 default:
1671 return error(GL_INVALID_ENUM);
1672 }
1673
1674 if (level != 0)
1675 {
1676 return error(GL_INVALID_VALUE);
1677 }
1678 }
1679
1680 gl::Framebuffer *framebuffer = context->getFramebuffer();
1681
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001682 if (context->getFramebufferHandle() == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001683 {
1684 return error(GL_INVALID_OPERATION);
1685 }
1686
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001687 switch (attachment)
1688 {
1689 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
1690 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
1691 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
1692 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001693 }
1694 }
1695 catch(std::bad_alloc&)
1696 {
1697 return error(GL_OUT_OF_MEMORY);
1698 }
1699}
1700
1701void __stdcall glFrontFace(GLenum mode)
1702{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001703 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001704
1705 try
1706 {
1707 switch (mode)
1708 {
1709 case GL_CW:
1710 case GL_CCW:
1711 {
1712 gl::Context *context = gl::getContext();
1713
1714 if (context)
1715 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001716 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001717 }
1718 }
1719 break;
1720 default:
1721 return error(GL_INVALID_ENUM);
1722 }
1723 }
1724 catch(std::bad_alloc&)
1725 {
1726 return error(GL_OUT_OF_MEMORY);
1727 }
1728}
1729
1730void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1731{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001732 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001733
1734 try
1735 {
1736 if (n < 0)
1737 {
1738 return error(GL_INVALID_VALUE);
1739 }
1740
1741 gl::Context *context = gl::getContext();
1742
1743 if (context)
1744 {
1745 for (int i = 0; i < n; i++)
1746 {
1747 buffers[i] = context->createBuffer();
1748 }
1749 }
1750 }
1751 catch(std::bad_alloc&)
1752 {
1753 return error(GL_OUT_OF_MEMORY);
1754 }
1755}
1756
1757void __stdcall glGenerateMipmap(GLenum target)
1758{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001759 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001760
1761 try
1762 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00001763 gl::Context *context = gl::getContext();
1764
1765 if (context)
1766 {
1767 gl::Texture *texture;
1768
1769 switch (target)
1770 {
1771 case GL_TEXTURE_2D:
1772 texture = context->getTexture2D();
1773 break;
1774
1775 case GL_TEXTURE_CUBE_MAP:
1776 texture = context->getTextureCubeMap();
1777 break;
1778
1779 default:
1780 return error(GL_INVALID_ENUM);
1781 }
1782
1783 texture->generateMipmaps();
1784 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001785 }
1786 catch(std::bad_alloc&)
1787 {
1788 return error(GL_OUT_OF_MEMORY);
1789 }
1790}
1791
1792void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1793{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001794 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001795
1796 try
1797 {
1798 if (n < 0)
1799 {
1800 return error(GL_INVALID_VALUE);
1801 }
1802
1803 gl::Context *context = gl::getContext();
1804
1805 if (context)
1806 {
1807 for (int i = 0; i < n; i++)
1808 {
1809 framebuffers[i] = context->createFramebuffer();
1810 }
1811 }
1812 }
1813 catch(std::bad_alloc&)
1814 {
1815 return error(GL_OUT_OF_MEMORY);
1816 }
1817}
1818
1819void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1820{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001821 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001822
1823 try
1824 {
1825 if (n < 0)
1826 {
1827 return error(GL_INVALID_VALUE);
1828 }
1829
1830 gl::Context *context = gl::getContext();
1831
1832 if (context)
1833 {
1834 for (int i = 0; i < n; i++)
1835 {
1836 renderbuffers[i] = context->createRenderbuffer();
1837 }
1838 }
1839 }
1840 catch(std::bad_alloc&)
1841 {
1842 return error(GL_OUT_OF_MEMORY);
1843 }
1844}
1845
1846void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1847{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001848 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001849
1850 try
1851 {
1852 if (n < 0)
1853 {
1854 return error(GL_INVALID_VALUE);
1855 }
1856
1857 gl::Context *context = gl::getContext();
1858
1859 if (context)
1860 {
1861 for (int i = 0; i < n; i++)
1862 {
1863 textures[i] = context->createTexture();
1864 }
1865 }
1866 }
1867 catch(std::bad_alloc&)
1868 {
1869 return error(GL_OUT_OF_MEMORY);
1870 }
1871}
1872
daniel@transgaming.com85423182010-04-22 13:35:27 +00001873void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001874{
daniel@transgaming.com85423182010-04-22 13:35:27 +00001875 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
1876 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001877 program, index, bufsize, length, size, type, name);
1878
1879 try
1880 {
1881 if (bufsize < 0)
1882 {
1883 return error(GL_INVALID_VALUE);
1884 }
1885
daniel@transgaming.com85423182010-04-22 13:35:27 +00001886 gl::Context *context = gl::getContext();
1887
1888 if (context)
1889 {
1890 gl::Program *programObject = context->getProgram(program);
1891
1892 if (!programObject)
1893 {
1894 if (context->getShader(program))
1895 {
1896 return error(GL_INVALID_OPERATION);
1897 }
1898 else
1899 {
1900 return error(GL_INVALID_VALUE);
1901 }
1902 }
1903
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001904 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00001905 {
1906 return error(GL_INVALID_VALUE);
1907 }
1908
1909 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
1910 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001911 }
1912 catch(std::bad_alloc&)
1913 {
1914 return error(GL_OUT_OF_MEMORY);
1915 }
1916}
1917
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001918void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001919{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001920 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001921 "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 +00001922 program, index, bufsize, length, size, type, name);
1923
1924 try
1925 {
1926 if (bufsize < 0)
1927 {
1928 return error(GL_INVALID_VALUE);
1929 }
1930
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001931 gl::Context *context = gl::getContext();
1932
1933 if (context)
1934 {
1935 gl::Program *programObject = context->getProgram(program);
1936
1937 if (!programObject)
1938 {
1939 if (context->getShader(program))
1940 {
1941 return error(GL_INVALID_OPERATION);
1942 }
1943 else
1944 {
1945 return error(GL_INVALID_VALUE);
1946 }
1947 }
1948
1949 if (index >= (GLuint)programObject->getActiveUniformCount())
1950 {
1951 return error(GL_INVALID_VALUE);
1952 }
1953
1954 programObject->getActiveUniform(index, bufsize, length, size, type, name);
1955 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001956 }
1957 catch(std::bad_alloc&)
1958 {
1959 return error(GL_OUT_OF_MEMORY);
1960 }
1961}
1962
1963void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1964{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001965 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1966 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001967
1968 try
1969 {
1970 if (maxcount < 0)
1971 {
1972 return error(GL_INVALID_VALUE);
1973 }
1974
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001975 gl::Context *context = gl::getContext();
1976
1977 if (context)
1978 {
1979 gl::Program *programObject = context->getProgram(program);
1980
1981 if (!programObject)
1982 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001983 if (context->getShader(program))
1984 {
1985 return error(GL_INVALID_OPERATION);
1986 }
1987 else
1988 {
1989 return error(GL_INVALID_VALUE);
1990 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001991 }
1992
1993 return programObject->getAttachedShaders(maxcount, count, shaders);
1994 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001995 }
1996 catch(std::bad_alloc&)
1997 {
1998 return error(GL_OUT_OF_MEMORY);
1999 }
2000}
2001
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002002int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002003{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002004 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002005
2006 try
2007 {
2008 gl::Context *context = gl::getContext();
2009
2010 if (context)
2011 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002012
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002013 gl::Program *programObject = context->getProgram(program);
2014
2015 if (!programObject)
2016 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002017 if (context->getShader(program))
2018 {
2019 return error(GL_INVALID_OPERATION, -1);
2020 }
2021 else
2022 {
2023 return error(GL_INVALID_VALUE, -1);
2024 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002025 }
2026
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002027 if (!programObject->isLinked())
2028 {
2029 return error(GL_INVALID_OPERATION, -1);
2030 }
2031
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002032 return programObject->getAttributeLocation(name);
2033 }
2034 }
2035 catch(std::bad_alloc&)
2036 {
2037 return error(GL_OUT_OF_MEMORY, -1);
2038 }
2039
2040 return -1;
2041}
2042
2043void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2044{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002045 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002046
2047 try
2048 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002049 gl::Context *context = gl::getContext();
2050
2051 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002052 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002053 if (!(context->getBooleanv(pname, params)))
2054 {
2055 GLenum nativeType;
2056 unsigned int numParams = 0;
2057 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2058 return error(GL_INVALID_ENUM);
2059
2060 if (numParams == 0)
2061 return; // it is known that the pname is valid, but there are no parameters to return
2062
2063 if (nativeType == GL_FLOAT)
2064 {
2065 GLfloat *floatParams = NULL;
2066 floatParams = new GLfloat[numParams];
2067
2068 context->getFloatv(pname, floatParams);
2069
2070 for (unsigned int i = 0; i < numParams; ++i)
2071 {
2072 if (floatParams[i] == 0.0f)
2073 params[i] = GL_FALSE;
2074 else
2075 params[i] = GL_TRUE;
2076 }
2077
2078 delete [] floatParams;
2079 }
2080 else if (nativeType == GL_INT)
2081 {
2082 GLint *intParams = NULL;
2083 intParams = new GLint[numParams];
2084
2085 context->getIntegerv(pname, intParams);
2086
2087 for (unsigned int i = 0; i < numParams; ++i)
2088 {
2089 if (intParams[i] == 0)
2090 params[i] = GL_FALSE;
2091 else
2092 params[i] = GL_TRUE;
2093 }
2094
2095 delete [] intParams;
2096 }
2097 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002098 }
2099 }
2100 catch(std::bad_alloc&)
2101 {
2102 return error(GL_OUT_OF_MEMORY);
2103 }
2104}
2105
2106void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2107{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002108 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 +00002109
2110 try
2111 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002112 gl::Context *context = gl::getContext();
2113
2114 if (context)
2115 {
2116 gl::Buffer *buffer;
2117
2118 switch (target)
2119 {
2120 case GL_ARRAY_BUFFER:
2121 buffer = context->getArrayBuffer();
2122 break;
2123 case GL_ELEMENT_ARRAY_BUFFER:
2124 buffer = context->getElementArrayBuffer();
2125 break;
2126 default: return error(GL_INVALID_ENUM);
2127 }
2128
2129 if (!buffer)
2130 {
2131 // A null buffer means that "0" is bound to the requested buffer target
2132 return error(GL_INVALID_OPERATION);
2133 }
2134
2135 switch (pname)
2136 {
2137 case GL_BUFFER_USAGE:
2138 *params = buffer->usage();
2139 break;
2140 case GL_BUFFER_SIZE:
2141 *params = buffer->size();
2142 break;
2143 default: return error(GL_INVALID_ENUM);
2144 }
2145 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002146 }
2147 catch(std::bad_alloc&)
2148 {
2149 return error(GL_OUT_OF_MEMORY);
2150 }
2151}
2152
2153GLenum __stdcall glGetError(void)
2154{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002155 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002156
2157 gl::Context *context = gl::getContext();
2158
2159 if (context)
2160 {
2161 return context->getError();
2162 }
2163
2164 return GL_NO_ERROR;
2165}
2166
2167void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2168{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002169 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002170
2171 try
2172 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002173 gl::Context *context = gl::getContext();
2174
2175 if (context)
2176 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002177 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002178 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002179 GLenum nativeType;
2180 unsigned int numParams = 0;
2181 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2182 return error(GL_INVALID_ENUM);
2183
2184 if (numParams == 0)
2185 return; // it is known that the pname is valid, but that there are no parameters to return.
2186
2187 if (nativeType == GL_BOOL)
2188 {
2189 GLboolean *boolParams = NULL;
2190 boolParams = new GLboolean[numParams];
2191
2192 context->getBooleanv(pname, boolParams);
2193
2194 for (unsigned int i = 0; i < numParams; ++i)
2195 {
2196 if (boolParams[i] == GL_FALSE)
2197 params[i] = 0.0f;
2198 else
2199 params[i] = 1.0f;
2200 }
2201
2202 delete [] boolParams;
2203 }
2204 else if (nativeType == GL_INT)
2205 {
2206 GLint *intParams = NULL;
2207 intParams = new GLint[numParams];
2208
2209 context->getIntegerv(pname, intParams);
2210
2211 for (unsigned int i = 0; i < numParams; ++i)
2212 {
2213 params[i] = (GLfloat)intParams[i];
2214 }
2215
2216 delete [] intParams;
2217 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002218 }
2219 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002220 }
2221 catch(std::bad_alloc&)
2222 {
2223 return error(GL_OUT_OF_MEMORY);
2224 }
2225}
2226
2227void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2228{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002229 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2230 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002231
2232 try
2233 {
2234 gl::Context *context = gl::getContext();
2235
2236 if (context)
2237 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002238 if (context->getFramebufferHandle() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002239 {
2240 return error(GL_INVALID_OPERATION);
2241 }
2242
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002243 if (target != GL_FRAMEBUFFER)
2244 {
2245 return error(GL_INVALID_ENUM);
2246 }
2247
2248 GLenum attachmentType;
2249 GLuint attachmentHandle;
2250 switch (attachment)
2251 {
2252 case GL_COLOR_ATTACHMENT0:
2253 attachmentType = context->getFramebuffer()->getColorbufferType();
2254 attachmentHandle = context->getFramebuffer()->getColorbufferHandle();
2255 break;
2256 case GL_DEPTH_ATTACHMENT:
2257 attachmentType = context->getFramebuffer()->getDepthbufferType();
2258 attachmentHandle = context->getFramebuffer()->getDepthbufferHandle();
2259 break;
2260 case GL_STENCIL_ATTACHMENT:
2261 attachmentType = context->getFramebuffer()->getStencilbufferType();
2262 attachmentHandle = context->getFramebuffer()->getStencilbufferHandle();
2263 break;
2264 default: return error(GL_INVALID_ENUM);
2265 }
2266
2267 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002268 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002269 {
2270 attachmentObjectType = attachmentType;
2271 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002272 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002273 {
2274 attachmentObjectType = GL_TEXTURE;
2275 }
2276 else UNREACHABLE();
2277
2278 switch (pname)
2279 {
2280 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2281 *params = attachmentObjectType;
2282 break;
2283 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2284 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2285 {
2286 *params = attachmentHandle;
2287 }
2288 else
2289 {
2290 return error(GL_INVALID_ENUM);
2291 }
2292 break;
2293 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2294 if (attachmentObjectType == GL_TEXTURE)
2295 {
2296 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2297 }
2298 else
2299 {
2300 return error(GL_INVALID_ENUM);
2301 }
2302 break;
2303 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2304 if (attachmentObjectType == GL_TEXTURE)
2305 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002306 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002307 {
2308 *params = attachmentType;
2309 }
2310 else
2311 {
2312 *params = 0;
2313 }
2314 }
2315 else
2316 {
2317 return error(GL_INVALID_ENUM);
2318 }
2319 break;
2320 default:
2321 return error(GL_INVALID_ENUM);
2322 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002323 }
2324 }
2325 catch(std::bad_alloc&)
2326 {
2327 return error(GL_OUT_OF_MEMORY);
2328 }
2329}
2330
2331void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2332{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002333 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002334
2335 try
2336 {
2337 gl::Context *context = gl::getContext();
2338
2339 if (context)
2340 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002341 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002342 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002343 GLenum nativeType;
2344 unsigned int numParams = 0;
2345 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2346 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002347
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002348 if (numParams == 0)
2349 return; // it is known that pname is valid, but there are no parameters to return
2350
2351 if (nativeType == GL_BOOL)
2352 {
2353 GLboolean *boolParams = NULL;
2354 boolParams = new GLboolean[numParams];
2355
2356 context->getBooleanv(pname, boolParams);
2357
2358 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002359 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002360 if (boolParams[i] == GL_FALSE)
2361 params[i] = 0;
2362 else
2363 params[i] = 1;
2364 }
2365
2366 delete [] boolParams;
2367 }
2368 else if (nativeType == GL_FLOAT)
2369 {
2370 GLfloat *floatParams = NULL;
2371 floatParams = new GLfloat[numParams];
2372
2373 context->getFloatv(pname, floatParams);
2374
2375 for (unsigned int i = 0; i < numParams; ++i)
2376 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002377 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002378 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002379 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002380 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002381 else
2382 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 +00002383 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002384
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002385 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002386 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002387 }
2388 }
2389 }
2390 catch(std::bad_alloc&)
2391 {
2392 return error(GL_OUT_OF_MEMORY);
2393 }
2394}
2395
2396void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2397{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002398 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002399
2400 try
2401 {
2402 gl::Context *context = gl::getContext();
2403
2404 if (context)
2405 {
2406 gl::Program *programObject = context->getProgram(program);
2407
2408 if (!programObject)
2409 {
2410 return error(GL_INVALID_VALUE);
2411 }
2412
2413 switch (pname)
2414 {
2415 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002416 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002417 return;
2418 case GL_LINK_STATUS:
2419 *params = programObject->isLinked();
2420 return;
2421 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002422 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002423 return;
2424 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002425 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002426 return;
2427 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002428 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002429 return;
2430 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002431 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002432 return;
2433 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002434 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002435 return;
2436 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002437 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002438 return;
2439 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002440 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002441 return;
2442 default:
2443 return error(GL_INVALID_ENUM);
2444 }
2445 }
2446 }
2447 catch(std::bad_alloc&)
2448 {
2449 return error(GL_OUT_OF_MEMORY);
2450 }
2451}
2452
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002453void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002454{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002455 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 +00002456 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002457
2458 try
2459 {
2460 if (bufsize < 0)
2461 {
2462 return error(GL_INVALID_VALUE);
2463 }
2464
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002465 gl::Context *context = gl::getContext();
2466
2467 if (context)
2468 {
2469 gl::Program *programObject = context->getProgram(program);
2470
2471 if (!programObject)
2472 {
2473 return error(GL_INVALID_VALUE);
2474 }
2475
2476 programObject->getInfoLog(bufsize, length, infolog);
2477 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002478 }
2479 catch(std::bad_alloc&)
2480 {
2481 return error(GL_OUT_OF_MEMORY);
2482 }
2483}
2484
2485void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2486{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002487 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 +00002488
2489 try
2490 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002491 gl::Context *context = gl::getContext();
2492
2493 if (context)
2494 {
2495 if (target != GL_RENDERBUFFER)
2496 {
2497 return error(GL_INVALID_ENUM);
2498 }
2499
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002500 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002501 {
2502 return error(GL_INVALID_OPERATION);
2503 }
2504
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002505 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002506
2507 switch (pname)
2508 {
2509 case GL_RENDERBUFFER_WIDTH:
2510 *params = renderbuffer->getWidth();
2511 break;
2512 case GL_RENDERBUFFER_HEIGHT:
2513 *params = renderbuffer->getHeight();
2514 break;
2515 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2516 *params = renderbuffer->getFormat();
2517 break;
2518 case GL_RENDERBUFFER_RED_SIZE:
2519 if (renderbuffer->isColorbuffer())
2520 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002521 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002522 }
2523 else
2524 {
2525 *params = 0;
2526 }
2527 break;
2528 case GL_RENDERBUFFER_GREEN_SIZE:
2529 if (renderbuffer->isColorbuffer())
2530 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002531 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002532 }
2533 else
2534 {
2535 *params = 0;
2536 }
2537 break;
2538 case GL_RENDERBUFFER_BLUE_SIZE:
2539 if (renderbuffer->isColorbuffer())
2540 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002541 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002542 }
2543 else
2544 {
2545 *params = 0;
2546 }
2547 break;
2548 case GL_RENDERBUFFER_ALPHA_SIZE:
2549 if (renderbuffer->isColorbuffer())
2550 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002551 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002552 }
2553 else
2554 {
2555 *params = 0;
2556 }
2557 break;
2558 case GL_RENDERBUFFER_DEPTH_SIZE:
2559 if (renderbuffer->isDepthbuffer())
2560 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002561 *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002562 }
2563 else
2564 {
2565 *params = 0;
2566 }
2567 break;
2568 case GL_RENDERBUFFER_STENCIL_SIZE:
2569 if (renderbuffer->isStencilbuffer())
2570 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002571 *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002572 }
2573 else
2574 {
2575 *params = 0;
2576 }
2577 break;
2578 default:
2579 return error(GL_INVALID_ENUM);
2580 }
2581 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002582 }
2583 catch(std::bad_alloc&)
2584 {
2585 return error(GL_OUT_OF_MEMORY);
2586 }
2587}
2588
2589void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2590{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002591 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002592
2593 try
2594 {
2595 gl::Context *context = gl::getContext();
2596
2597 if (context)
2598 {
2599 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002600
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002601 if (!shaderObject)
2602 {
2603 return error(GL_INVALID_VALUE);
2604 }
2605
2606 switch (pname)
2607 {
2608 case GL_SHADER_TYPE:
2609 *params = shaderObject->getType();
2610 return;
2611 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002612 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002613 return;
2614 case GL_COMPILE_STATUS:
2615 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2616 return;
2617 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002618 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002619 return;
2620 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002621 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002622 return;
2623 default:
2624 return error(GL_INVALID_ENUM);
2625 }
2626 }
2627 }
2628 catch(std::bad_alloc&)
2629 {
2630 return error(GL_OUT_OF_MEMORY);
2631 }
2632}
2633
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002634void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002635{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002636 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 +00002637 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002638
2639 try
2640 {
2641 if (bufsize < 0)
2642 {
2643 return error(GL_INVALID_VALUE);
2644 }
2645
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002646 gl::Context *context = gl::getContext();
2647
2648 if (context)
2649 {
2650 gl::Shader *shaderObject = context->getShader(shader);
2651
2652 if (!shaderObject)
2653 {
2654 return error(GL_INVALID_VALUE);
2655 }
2656
2657 shaderObject->getInfoLog(bufsize, length, infolog);
2658 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002659 }
2660 catch(std::bad_alloc&)
2661 {
2662 return error(GL_OUT_OF_MEMORY);
2663 }
2664}
2665
2666void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2667{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002668 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2669 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002670
2671 try
2672 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002673 switch (shadertype)
2674 {
2675 case GL_VERTEX_SHADER:
2676 case GL_FRAGMENT_SHADER:
2677 break;
2678 default:
2679 return error(GL_INVALID_ENUM);
2680 }
2681
2682 switch (precisiontype)
2683 {
2684 case GL_LOW_FLOAT:
2685 case GL_MEDIUM_FLOAT:
2686 case GL_HIGH_FLOAT:
2687 // Assume IEEE 754 precision
2688 range[0] = 127;
2689 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002690 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002691 break;
2692 case GL_LOW_INT:
2693 case GL_MEDIUM_INT:
2694 case GL_HIGH_INT:
2695 // Some (most) hardware only supports single-precision floating-point numbers,
2696 // which can accurately represent integers up to +/-16777216
2697 range[0] = 24;
2698 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002699 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002700 break;
2701 default:
2702 return error(GL_INVALID_ENUM);
2703 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002704 }
2705 catch(std::bad_alloc&)
2706 {
2707 return error(GL_OUT_OF_MEMORY);
2708 }
2709}
2710
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002711void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002712{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002713 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 +00002714 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002715
2716 try
2717 {
2718 if (bufsize < 0)
2719 {
2720 return error(GL_INVALID_VALUE);
2721 }
2722
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002723 gl::Context *context = gl::getContext();
2724
2725 if (context)
2726 {
2727 gl::Shader *shaderObject = context->getShader(shader);
2728
2729 if (!shaderObject)
2730 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002731 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002732 }
2733
2734 shaderObject->getSource(bufsize, length, source);
2735 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002736 }
2737 catch(std::bad_alloc&)
2738 {
2739 return error(GL_OUT_OF_MEMORY);
2740 }
2741}
2742
2743const GLubyte* __stdcall glGetString(GLenum name)
2744{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002745 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002746
2747 try
2748 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002749 gl::Context *context = gl::getContext();
2750
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002751 switch (name)
2752 {
2753 case GL_VENDOR:
2754 return (GLubyte*)"TransGaming Inc.";
2755 case GL_RENDERER:
2756 return (GLubyte*)"ANGLE";
2757 case GL_VERSION:
2758 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2759 case GL_SHADING_LANGUAGE_VERSION:
2760 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2761 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002762 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002763 default:
2764 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2765 }
2766 }
2767 catch(std::bad_alloc&)
2768 {
2769 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2770 }
2771
2772 return NULL;
2773}
2774
2775void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2776{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002777 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 +00002778
2779 try
2780 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002781 gl::Context *context = gl::getContext();
2782
2783 if (context)
2784 {
2785 gl::Texture *texture;
2786
2787 switch (target)
2788 {
2789 case GL_TEXTURE_2D:
2790 texture = context->getTexture2D();
2791 break;
2792 case GL_TEXTURE_CUBE_MAP:
2793 texture = context->getTextureCubeMap();
2794 break;
2795 default:
2796 return error(GL_INVALID_ENUM);
2797 }
2798
2799 switch (pname)
2800 {
2801 case GL_TEXTURE_MAG_FILTER:
2802 *params = (GLfloat)texture->getMagFilter();
2803 break;
2804 case GL_TEXTURE_MIN_FILTER:
2805 *params = (GLfloat)texture->getMinFilter();
2806 break;
2807 case GL_TEXTURE_WRAP_S:
2808 *params = (GLfloat)texture->getWrapS();
2809 break;
2810 case GL_TEXTURE_WRAP_T:
2811 *params = (GLfloat)texture->getWrapT();
2812 break;
2813 default:
2814 return error(GL_INVALID_ENUM);
2815 }
2816 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002817 }
2818 catch(std::bad_alloc&)
2819 {
2820 return error(GL_OUT_OF_MEMORY);
2821 }
2822}
2823
2824void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2825{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002826 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 +00002827
2828 try
2829 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002830 gl::Context *context = gl::getContext();
2831
2832 if (context)
2833 {
2834 gl::Texture *texture;
2835
2836 switch (target)
2837 {
2838 case GL_TEXTURE_2D:
2839 texture = context->getTexture2D();
2840 break;
2841 case GL_TEXTURE_CUBE_MAP:
2842 texture = context->getTextureCubeMap();
2843 break;
2844 default:
2845 return error(GL_INVALID_ENUM);
2846 }
2847
2848 switch (pname)
2849 {
2850 case GL_TEXTURE_MAG_FILTER:
2851 *params = texture->getMagFilter();
2852 break;
2853 case GL_TEXTURE_MIN_FILTER:
2854 *params = texture->getMinFilter();
2855 break;
2856 case GL_TEXTURE_WRAP_S:
2857 *params = texture->getWrapS();
2858 break;
2859 case GL_TEXTURE_WRAP_T:
2860 *params = texture->getWrapT();
2861 break;
2862 default:
2863 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
2873void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2874{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002875 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002876
2877 try
2878 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002879 gl::Context *context = gl::getContext();
2880
2881 if (context)
2882 {
2883 if (program == 0)
2884 {
2885 return error(GL_INVALID_VALUE);
2886 }
2887
2888 gl::Program *programObject = context->getProgram(program);
2889
2890 if (!programObject || !programObject->isLinked())
2891 {
2892 return error(GL_INVALID_OPERATION);
2893 }
2894
2895 if (!programObject->getUniformfv(location, params))
2896 {
2897 return error(GL_INVALID_OPERATION);
2898 }
2899 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002900 }
2901 catch(std::bad_alloc&)
2902 {
2903 return error(GL_OUT_OF_MEMORY);
2904 }
2905}
2906
2907void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2908{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002909 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002910
2911 try
2912 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002913 gl::Context *context = gl::getContext();
2914
2915 if (context)
2916 {
2917 if (program == 0)
2918 {
2919 return error(GL_INVALID_VALUE);
2920 }
2921
2922 gl::Program *programObject = context->getProgram(program);
2923
2924 if (!programObject || !programObject->isLinked())
2925 {
2926 return error(GL_INVALID_OPERATION);
2927 }
2928
2929 if (!programObject)
2930 {
2931 return error(GL_INVALID_OPERATION);
2932 }
2933
2934 if (!programObject->getUniformiv(location, params))
2935 {
2936 return error(GL_INVALID_OPERATION);
2937 }
2938 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002939 }
2940 catch(std::bad_alloc&)
2941 {
2942 return error(GL_OUT_OF_MEMORY);
2943 }
2944}
2945
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002946int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002947{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002948 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002949
2950 try
2951 {
2952 gl::Context *context = gl::getContext();
2953
2954 if (strstr(name, "gl_") == name)
2955 {
2956 return -1;
2957 }
2958
2959 if (context)
2960 {
2961 gl::Program *programObject = context->getProgram(program);
2962
2963 if (!programObject)
2964 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002965 if (context->getShader(program))
2966 {
2967 return error(GL_INVALID_OPERATION, -1);
2968 }
2969 else
2970 {
2971 return error(GL_INVALID_VALUE, -1);
2972 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002973 }
2974
2975 if (!programObject->isLinked())
2976 {
2977 return error(GL_INVALID_OPERATION, -1);
2978 }
2979
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00002980 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002981 }
2982 }
2983 catch(std::bad_alloc&)
2984 {
2985 return error(GL_OUT_OF_MEMORY, -1);
2986 }
2987
2988 return -1;
2989}
2990
2991void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2992{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002993 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002994
2995 try
2996 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002997 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002998
daniel@transgaming.come0078962010-04-15 20:45:08 +00002999 if (context)
3000 {
3001 if (index >= gl::MAX_VERTEX_ATTRIBS)
3002 {
3003 return error(GL_INVALID_VALUE);
3004 }
3005
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003006 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003007
daniel@transgaming.come0078962010-04-15 20:45:08 +00003008 switch (pname)
3009 {
3010 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003011 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003012 break;
3013 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003014 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003015 break;
3016 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003017 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003018 break;
3019 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003020 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003021 break;
3022 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003023 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003024 break;
3025 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003026 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003027 break;
3028 case GL_CURRENT_VERTEX_ATTRIB:
3029 for (int i = 0; i < 4; ++i)
3030 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003031 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003032 }
3033 break;
3034 default: return error(GL_INVALID_ENUM);
3035 }
3036 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003037 }
3038 catch(std::bad_alloc&)
3039 {
3040 return error(GL_OUT_OF_MEMORY);
3041 }
3042}
3043
3044void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3045{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003046 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003047
3048 try
3049 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003050 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003051
daniel@transgaming.come0078962010-04-15 20:45:08 +00003052 if (context)
3053 {
3054 if (index >= gl::MAX_VERTEX_ATTRIBS)
3055 {
3056 return error(GL_INVALID_VALUE);
3057 }
3058
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003059 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003060
daniel@transgaming.come0078962010-04-15 20:45:08 +00003061 switch (pname)
3062 {
3063 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003064 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003065 break;
3066 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003067 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003068 break;
3069 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003070 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003071 break;
3072 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003073 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003074 break;
3075 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003076 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003077 break;
3078 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003079 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003080 break;
3081 case GL_CURRENT_VERTEX_ATTRIB:
3082 for (int i = 0; i < 4; ++i)
3083 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003084 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003085 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3086 }
3087 break;
3088 default: return error(GL_INVALID_ENUM);
3089 }
3090 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003091 }
3092 catch(std::bad_alloc&)
3093 {
3094 return error(GL_OUT_OF_MEMORY);
3095 }
3096}
3097
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003098void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003099{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003100 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003101
3102 try
3103 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003104 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003105
daniel@transgaming.come0078962010-04-15 20:45:08 +00003106 if (context)
3107 {
3108 if (index >= gl::MAX_VERTEX_ATTRIBS)
3109 {
3110 return error(GL_INVALID_VALUE);
3111 }
3112
3113 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3114 {
3115 return error(GL_INVALID_ENUM);
3116 }
3117
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003118 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003119 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003120 }
3121 catch(std::bad_alloc&)
3122 {
3123 return error(GL_OUT_OF_MEMORY);
3124 }
3125}
3126
3127void __stdcall glHint(GLenum target, GLenum mode)
3128{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003129 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003130
3131 try
3132 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003133 switch (target)
3134 {
3135 case GL_GENERATE_MIPMAP_HINT:
3136 switch (mode)
3137 {
3138 case GL_FASTEST:
3139 case GL_NICEST:
3140 case GL_DONT_CARE:
3141 break;
3142 default:
3143 return error(GL_INVALID_ENUM);
3144 }
3145 break;
3146 default:
3147 return error(GL_INVALID_ENUM);
3148 }
3149
3150 gl::Context *context = gl::getContext();
3151 if (context)
3152 {
3153 if (target == GL_GENERATE_MIPMAP_HINT)
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003154 context->setGenerateMipmapHint(mode);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003155 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003156 }
3157 catch(std::bad_alloc&)
3158 {
3159 return error(GL_OUT_OF_MEMORY);
3160 }
3161}
3162
3163GLboolean __stdcall glIsBuffer(GLuint buffer)
3164{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003165 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003166
3167 try
3168 {
3169 gl::Context *context = gl::getContext();
3170
3171 if (context && buffer)
3172 {
3173 gl::Buffer *bufferObject = context->getBuffer(buffer);
3174
3175 if (bufferObject)
3176 {
3177 return GL_TRUE;
3178 }
3179 }
3180 }
3181 catch(std::bad_alloc&)
3182 {
3183 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3184 }
3185
3186 return GL_FALSE;
3187}
3188
3189GLboolean __stdcall glIsEnabled(GLenum cap)
3190{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003191 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003192
3193 try
3194 {
3195 gl::Context *context = gl::getContext();
3196
3197 if (context)
3198 {
3199 switch (cap)
3200 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003201 case GL_CULL_FACE: return context->isCullFaceEnabled();
3202 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3203 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3204 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3205 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3206 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3207 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3208 case GL_BLEND: return context->isBlendEnabled();
3209 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003210 default:
3211 return error(GL_INVALID_ENUM, false);
3212 }
3213 }
3214 }
3215 catch(std::bad_alloc&)
3216 {
3217 return error(GL_OUT_OF_MEMORY, false);
3218 }
3219
3220 return false;
3221}
3222
3223GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3224{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003225 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003226
3227 try
3228 {
3229 gl::Context *context = gl::getContext();
3230
3231 if (context && framebuffer)
3232 {
3233 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3234
3235 if (framebufferObject)
3236 {
3237 return GL_TRUE;
3238 }
3239 }
3240 }
3241 catch(std::bad_alloc&)
3242 {
3243 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3244 }
3245
3246 return GL_FALSE;
3247}
3248
3249GLboolean __stdcall glIsProgram(GLuint program)
3250{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003251 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003252
3253 try
3254 {
3255 gl::Context *context = gl::getContext();
3256
3257 if (context && program)
3258 {
3259 gl::Program *programObject = context->getProgram(program);
3260
3261 if (programObject)
3262 {
3263 return GL_TRUE;
3264 }
3265 }
3266 }
3267 catch(std::bad_alloc&)
3268 {
3269 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3270 }
3271
3272 return GL_FALSE;
3273}
3274
3275GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3276{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003277 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003278
3279 try
3280 {
3281 gl::Context *context = gl::getContext();
3282
3283 if (context && renderbuffer)
3284 {
3285 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3286
3287 if (renderbufferObject)
3288 {
3289 return GL_TRUE;
3290 }
3291 }
3292 }
3293 catch(std::bad_alloc&)
3294 {
3295 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3296 }
3297
3298 return GL_FALSE;
3299}
3300
3301GLboolean __stdcall glIsShader(GLuint shader)
3302{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003303 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003304
3305 try
3306 {
3307 gl::Context *context = gl::getContext();
3308
3309 if (context && shader)
3310 {
3311 gl::Shader *shaderObject = context->getShader(shader);
3312
3313 if (shaderObject)
3314 {
3315 return GL_TRUE;
3316 }
3317 }
3318 }
3319 catch(std::bad_alloc&)
3320 {
3321 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3322 }
3323
3324 return GL_FALSE;
3325}
3326
3327GLboolean __stdcall glIsTexture(GLuint texture)
3328{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003329 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003330
3331 try
3332 {
3333 gl::Context *context = gl::getContext();
3334
3335 if (context && texture)
3336 {
3337 gl::Texture *textureObject = context->getTexture(texture);
3338
3339 if (textureObject)
3340 {
3341 return GL_TRUE;
3342 }
3343 }
3344 }
3345 catch(std::bad_alloc&)
3346 {
3347 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3348 }
3349
3350 return GL_FALSE;
3351}
3352
3353void __stdcall glLineWidth(GLfloat width)
3354{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003355 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003356
3357 try
3358 {
3359 if (width <= 0.0f)
3360 {
3361 return error(GL_INVALID_VALUE);
3362 }
3363
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003364 gl::Context *context = gl::getContext();
3365
3366 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003367 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003368 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003369 }
3370 }
3371 catch(std::bad_alloc&)
3372 {
3373 return error(GL_OUT_OF_MEMORY);
3374 }
3375}
3376
3377void __stdcall glLinkProgram(GLuint program)
3378{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003379 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003380
3381 try
3382 {
3383 gl::Context *context = gl::getContext();
3384
3385 if (context)
3386 {
3387 gl::Program *programObject = context->getProgram(program);
3388
3389 if (!programObject)
3390 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003391 if (context->getShader(program))
3392 {
3393 return error(GL_INVALID_OPERATION);
3394 }
3395 else
3396 {
3397 return error(GL_INVALID_VALUE);
3398 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003399 }
3400
3401 programObject->link();
3402 }
3403 }
3404 catch(std::bad_alloc&)
3405 {
3406 return error(GL_OUT_OF_MEMORY);
3407 }
3408}
3409
3410void __stdcall glPixelStorei(GLenum pname, GLint param)
3411{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003412 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003413
3414 try
3415 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003416 gl::Context *context = gl::getContext();
3417
3418 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003419 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003420 switch (pname)
3421 {
3422 case GL_UNPACK_ALIGNMENT:
3423 if (param != 1 && param != 2 && param != 4 && param != 8)
3424 {
3425 return error(GL_INVALID_VALUE);
3426 }
3427
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003428 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003429 break;
3430
3431 case GL_PACK_ALIGNMENT:
3432 if (param != 1 && param != 2 && param != 4 && param != 8)
3433 {
3434 return error(GL_INVALID_VALUE);
3435 }
3436
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003437 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003438 break;
3439
3440 default:
3441 return error(GL_INVALID_ENUM);
3442 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003443 }
3444 }
3445 catch(std::bad_alloc&)
3446 {
3447 return error(GL_OUT_OF_MEMORY);
3448 }
3449}
3450
3451void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3452{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003453 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003454
3455 try
3456 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003457 gl::Context *context = gl::getContext();
3458
3459 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003460 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003461 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003462 }
3463 }
3464 catch(std::bad_alloc&)
3465 {
3466 return error(GL_OUT_OF_MEMORY);
3467 }
3468}
3469
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003470void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003471{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003472 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003473 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003474 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003475
3476 try
3477 {
3478 if (width < 0 || height < 0)
3479 {
3480 return error(GL_INVALID_VALUE);
3481 }
3482
3483 switch (format)
3484 {
3485 case GL_RGBA:
3486 switch (type)
3487 {
3488 case GL_UNSIGNED_BYTE:
3489 break;
3490 default:
3491 return error(GL_INVALID_OPERATION);
3492 }
3493 break;
3494 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3495 switch (type)
3496 {
3497 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3498 break;
3499 default:
3500 return error(GL_INVALID_OPERATION);
3501 }
3502 break;
3503 default:
3504 return error(GL_INVALID_OPERATION);
3505 }
3506
3507 gl::Context *context = gl::getContext();
3508
3509 if (context)
3510 {
3511 context->readPixels(x, y, width, height, format, type, pixels);
3512 }
3513 }
3514 catch(std::bad_alloc&)
3515 {
3516 return error(GL_OUT_OF_MEMORY);
3517 }
3518}
3519
3520void __stdcall glReleaseShaderCompiler(void)
3521{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003522 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003523
3524 try
3525 {
3526 gl::Shader::releaseCompiler();
3527 }
3528 catch(std::bad_alloc&)
3529 {
3530 return error(GL_OUT_OF_MEMORY);
3531 }
3532}
3533
3534void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3535{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003536 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3537 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003538
3539 try
3540 {
3541 switch (target)
3542 {
3543 case GL_RENDERBUFFER:
3544 break;
3545 default:
3546 return error(GL_INVALID_ENUM);
3547 }
3548
3549 switch (internalformat)
3550 {
3551 case GL_DEPTH_COMPONENT16:
3552 case GL_RGBA4:
3553 case GL_RGB5_A1:
3554 case GL_RGB565:
3555 case GL_STENCIL_INDEX8:
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003556 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003557 break;
3558 default:
3559 return error(GL_INVALID_ENUM);
3560 }
3561
3562 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3563 {
3564 return error(GL_INVALID_VALUE);
3565 }
3566
3567 gl::Context *context = gl::getContext();
3568
3569 if (context)
3570 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003571 GLuint handle = context->getRenderbufferHandle();
3572 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003573 {
3574 return error(GL_INVALID_OPERATION);
3575 }
3576
3577 switch (internalformat)
3578 {
3579 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003580 context->setRenderbufferStorage(new gl::Depthbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003581 break;
3582 case GL_RGBA4:
3583 case GL_RGB5_A1:
3584 case GL_RGB565:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003585 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003586 break;
3587 case GL_STENCIL_INDEX8:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003588 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003589 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003590 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003591 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003592 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003593 default:
3594 return error(GL_INVALID_ENUM);
3595 }
3596 }
3597 }
3598 catch(std::bad_alloc&)
3599 {
3600 return error(GL_OUT_OF_MEMORY);
3601 }
3602}
3603
3604void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3605{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003606 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003607
3608 try
3609 {
3610 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003611
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003612 if (context)
3613 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00003614 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003615 }
3616 }
3617 catch(std::bad_alloc&)
3618 {
3619 return error(GL_OUT_OF_MEMORY);
3620 }
3621}
3622
3623void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3624{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003625 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 +00003626
3627 try
3628 {
3629 if (width < 0 || height < 0)
3630 {
3631 return error(GL_INVALID_VALUE);
3632 }
3633
3634 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003635
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003636 if (context)
3637 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003638 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003639 }
3640 }
3641 catch(std::bad_alloc&)
3642 {
3643 return error(GL_OUT_OF_MEMORY);
3644 }
3645}
3646
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003647void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003648{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003649 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003650 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003651 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003652
3653 try
3654 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00003655 // No binary shader formats are supported.
3656 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003657 }
3658 catch(std::bad_alloc&)
3659 {
3660 return error(GL_OUT_OF_MEMORY);
3661 }
3662}
3663
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003664void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003665{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003666 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 +00003667 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003668
3669 try
3670 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003671 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003672 {
3673 return error(GL_INVALID_VALUE);
3674 }
3675
3676 gl::Context *context = gl::getContext();
3677
3678 if (context)
3679 {
3680 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003681
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003682 if (!shaderObject)
3683 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003684 if (context->getProgram(shader))
3685 {
3686 return error(GL_INVALID_OPERATION);
3687 }
3688 else
3689 {
3690 return error(GL_INVALID_VALUE);
3691 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003692 }
3693
3694 shaderObject->setSource(count, string, length);
3695 }
3696 }
3697 catch(std::bad_alloc&)
3698 {
3699 return error(GL_OUT_OF_MEMORY);
3700 }
3701}
3702
3703void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3704{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003705 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003706}
3707
3708void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3709{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003710 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 +00003711
3712 try
3713 {
3714 switch (face)
3715 {
3716 case GL_FRONT:
3717 case GL_BACK:
3718 case GL_FRONT_AND_BACK:
3719 break;
3720 default:
3721 return error(GL_INVALID_ENUM);
3722 }
3723
3724 switch (func)
3725 {
3726 case GL_NEVER:
3727 case GL_ALWAYS:
3728 case GL_LESS:
3729 case GL_LEQUAL:
3730 case GL_EQUAL:
3731 case GL_GEQUAL:
3732 case GL_GREATER:
3733 case GL_NOTEQUAL:
3734 break;
3735 default:
3736 return error(GL_INVALID_ENUM);
3737 }
3738
3739 gl::Context *context = gl::getContext();
3740
3741 if (context)
3742 {
3743 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3744 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003745 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003746 }
3747
3748 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3749 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003750 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003751 }
3752 }
3753 }
3754 catch(std::bad_alloc&)
3755 {
3756 return error(GL_OUT_OF_MEMORY);
3757 }
3758}
3759
3760void __stdcall glStencilMask(GLuint mask)
3761{
3762 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3763}
3764
3765void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3766{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003767 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003768
3769 try
3770 {
3771 switch (face)
3772 {
3773 case GL_FRONT:
3774 case GL_BACK:
3775 case GL_FRONT_AND_BACK:
3776 break;
3777 default:
3778 return error(GL_INVALID_ENUM);
3779 }
3780
3781 gl::Context *context = gl::getContext();
3782
3783 if (context)
3784 {
3785 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3786 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003787 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003788 }
3789
3790 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3791 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003792 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003793 }
3794 }
3795 }
3796 catch(std::bad_alloc&)
3797 {
3798 return error(GL_OUT_OF_MEMORY);
3799 }
3800}
3801
3802void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3803{
3804 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3805}
3806
3807void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3808{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003809 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3810 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003811
3812 try
3813 {
3814 switch (face)
3815 {
3816 case GL_FRONT:
3817 case GL_BACK:
3818 case GL_FRONT_AND_BACK:
3819 break;
3820 default:
3821 return error(GL_INVALID_ENUM);
3822 }
3823
3824 switch (fail)
3825 {
3826 case GL_ZERO:
3827 case GL_KEEP:
3828 case GL_REPLACE:
3829 case GL_INCR:
3830 case GL_DECR:
3831 case GL_INVERT:
3832 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003833 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003834 break;
3835 default:
3836 return error(GL_INVALID_ENUM);
3837 }
3838
3839 switch (zfail)
3840 {
3841 case GL_ZERO:
3842 case GL_KEEP:
3843 case GL_REPLACE:
3844 case GL_INCR:
3845 case GL_DECR:
3846 case GL_INVERT:
3847 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003848 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003849 break;
3850 default:
3851 return error(GL_INVALID_ENUM);
3852 }
3853
3854 switch (zpass)
3855 {
3856 case GL_ZERO:
3857 case GL_KEEP:
3858 case GL_REPLACE:
3859 case GL_INCR:
3860 case GL_DECR:
3861 case GL_INVERT:
3862 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003863 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003864 break;
3865 default:
3866 return error(GL_INVALID_ENUM);
3867 }
3868
3869 gl::Context *context = gl::getContext();
3870
3871 if (context)
3872 {
3873 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3874 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003875 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003876 }
3877
3878 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3879 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003880 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003881 }
3882 }
3883 }
3884 catch(std::bad_alloc&)
3885 {
3886 return error(GL_OUT_OF_MEMORY);
3887 }
3888}
3889
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003890void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3891 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003892{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003893 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 +00003894 "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 +00003895 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003896
3897 try
3898 {
3899 if (level < 0 || width < 0 || height < 0)
3900 {
3901 return error(GL_INVALID_VALUE);
3902 }
3903
3904 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3905 {
3906 return error(GL_INVALID_VALUE);
3907 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003908
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003909 switch (target)
3910 {
3911 case GL_TEXTURE_2D:
3912 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3913 {
3914 return error(GL_INVALID_VALUE);
3915 }
3916 break;
3917 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3918 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3919 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3920 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3921 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3922 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003923 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003924 {
3925 return error(GL_INVALID_VALUE);
3926 }
3927
3928 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3929 {
3930 return error(GL_INVALID_VALUE);
3931 }
3932 break;
3933 default:
3934 return error(GL_INVALID_ENUM);
3935 }
3936
3937 if (internalformat != format)
3938 {
3939 return error(GL_INVALID_OPERATION);
3940 }
3941
3942 switch (internalformat)
3943 {
3944 case GL_ALPHA:
3945 case GL_LUMINANCE:
3946 case GL_LUMINANCE_ALPHA:
3947 switch (type)
3948 {
3949 case GL_UNSIGNED_BYTE:
3950 break;
3951 default:
3952 return error(GL_INVALID_ENUM);
3953 }
3954 break;
3955 case GL_RGB:
3956 switch (type)
3957 {
3958 case GL_UNSIGNED_BYTE:
3959 case GL_UNSIGNED_SHORT_5_6_5:
3960 break;
3961 default:
3962 return error(GL_INVALID_ENUM);
3963 }
3964 break;
3965 case GL_RGBA:
3966 switch (type)
3967 {
3968 case GL_UNSIGNED_BYTE:
3969 case GL_UNSIGNED_SHORT_4_4_4_4:
3970 case GL_UNSIGNED_SHORT_5_5_5_1:
3971 break;
3972 default:
3973 return error(GL_INVALID_ENUM);
3974 }
3975 break;
3976 default:
3977 return error(GL_INVALID_VALUE);
3978 }
3979
3980 if (border != 0)
3981 {
3982 return error(GL_INVALID_VALUE);
3983 }
3984
3985 gl::Context *context = gl::getContext();
3986
3987 if (context)
3988 {
3989 if (target == GL_TEXTURE_2D)
3990 {
3991 gl::Texture2D *texture = context->getTexture2D();
3992
3993 if (!texture)
3994 {
3995 return error(GL_INVALID_OPERATION);
3996 }
3997
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003998 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003999 }
4000 else
4001 {
4002 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4003
4004 if (!texture)
4005 {
4006 return error(GL_INVALID_OPERATION);
4007 }
4008
4009 switch (target)
4010 {
4011 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004012 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004013 break;
4014 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004015 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004016 break;
4017 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004018 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004019 break;
4020 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004021 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004022 break;
4023 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004024 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004025 break;
4026 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004027 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004028 break;
4029 default: UNREACHABLE();
4030 }
4031 }
4032 }
4033 }
4034 catch(std::bad_alloc&)
4035 {
4036 return error(GL_OUT_OF_MEMORY);
4037 }
4038}
4039
4040void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4041{
4042 glTexParameteri(target, pname, (GLint)param);
4043}
4044
4045void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4046{
4047 glTexParameteri(target, pname, (GLint)*params);
4048}
4049
4050void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4051{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004052 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004053
4054 try
4055 {
4056 gl::Context *context = gl::getContext();
4057
4058 if (context)
4059 {
4060 gl::Texture *texture;
4061
4062 switch (target)
4063 {
4064 case GL_TEXTURE_2D:
4065 texture = context->getTexture2D();
4066 break;
4067 case GL_TEXTURE_CUBE_MAP:
4068 texture = context->getTextureCubeMap();
4069 break;
4070 default:
4071 return error(GL_INVALID_ENUM);
4072 }
4073
4074 switch (pname)
4075 {
4076 case GL_TEXTURE_WRAP_S:
4077 if (!texture->setWrapS((GLenum)param))
4078 {
4079 return error(GL_INVALID_ENUM);
4080 }
4081 break;
4082 case GL_TEXTURE_WRAP_T:
4083 if (!texture->setWrapT((GLenum)param))
4084 {
4085 return error(GL_INVALID_ENUM);
4086 }
4087 break;
4088 case GL_TEXTURE_MIN_FILTER:
4089 if (!texture->setMinFilter((GLenum)param))
4090 {
4091 return error(GL_INVALID_ENUM);
4092 }
4093 break;
4094 case GL_TEXTURE_MAG_FILTER:
4095 if (!texture->setMagFilter((GLenum)param))
4096 {
4097 return error(GL_INVALID_ENUM);
4098 }
4099 break;
4100 default:
4101 return error(GL_INVALID_ENUM);
4102 }
4103 }
4104 }
4105 catch(std::bad_alloc&)
4106 {
4107 return error(GL_OUT_OF_MEMORY);
4108 }
4109}
4110
4111void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4112{
4113 glTexParameteri(target, pname, *params);
4114}
4115
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004116void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4117 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004118{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004119 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4120 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004121 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004122 target, level, xoffset, yoffset, width, height, format, type, pixels);
4123
4124 try
4125 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004126 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004127 {
4128 return error(GL_INVALID_ENUM);
4129 }
4130
4131 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004132 {
4133 return error(GL_INVALID_VALUE);
4134 }
4135
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004136 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4137 {
4138 return error(GL_INVALID_VALUE);
4139 }
4140
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004141 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004142 {
4143 return error(GL_INVALID_ENUM);
4144 }
4145
4146 if (width == 0 || height == 0 || pixels == NULL)
4147 {
4148 return;
4149 }
4150
4151 gl::Context *context = gl::getContext();
4152
4153 if (context)
4154 {
4155 if (target == GL_TEXTURE_2D)
4156 {
4157 gl::Texture2D *texture = context->getTexture2D();
4158
4159 if (!texture)
4160 {
4161 return error(GL_INVALID_OPERATION);
4162 }
4163
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004164 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004165 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004166 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004167 {
4168 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4169
4170 if (!texture)
4171 {
4172 return error(GL_INVALID_OPERATION);
4173 }
4174
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004175 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004176 }
4177 else
4178 {
4179 UNREACHABLE();
4180 }
4181 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004182 }
4183 catch(std::bad_alloc&)
4184 {
4185 return error(GL_OUT_OF_MEMORY);
4186 }
4187}
4188
4189void __stdcall glUniform1f(GLint location, GLfloat x)
4190{
4191 glUniform1fv(location, 1, &x);
4192}
4193
4194void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4195{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004196 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004197
4198 try
4199 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004200 if (count < 0)
4201 {
4202 return error(GL_INVALID_VALUE);
4203 }
4204
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004205 if (location == -1)
4206 {
4207 return;
4208 }
4209
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004210 gl::Context *context = gl::getContext();
4211
4212 if (context)
4213 {
4214 gl::Program *program = context->getCurrentProgram();
4215
4216 if (!program)
4217 {
4218 return error(GL_INVALID_OPERATION);
4219 }
4220
4221 if (!program->setUniform1fv(location, count, v))
4222 {
4223 return error(GL_INVALID_OPERATION);
4224 }
4225 }
4226 }
4227 catch(std::bad_alloc&)
4228 {
4229 return error(GL_OUT_OF_MEMORY);
4230 }
4231}
4232
4233void __stdcall glUniform1i(GLint location, GLint x)
4234{
4235 glUniform1iv(location, 1, &x);
4236}
4237
4238void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4239{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004240 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004241
4242 try
4243 {
4244 if (count < 0)
4245 {
4246 return error(GL_INVALID_VALUE);
4247 }
4248
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004249 if (location == -1)
4250 {
4251 return;
4252 }
4253
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004254 gl::Context *context = gl::getContext();
4255
4256 if (context)
4257 {
4258 gl::Program *program = context->getCurrentProgram();
4259
4260 if (!program)
4261 {
4262 return error(GL_INVALID_OPERATION);
4263 }
4264
4265 if (!program->setUniform1iv(location, count, v))
4266 {
4267 return error(GL_INVALID_OPERATION);
4268 }
4269 }
4270 }
4271 catch(std::bad_alloc&)
4272 {
4273 return error(GL_OUT_OF_MEMORY);
4274 }
4275}
4276
4277void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4278{
4279 GLfloat xy[2] = {x, y};
4280
4281 glUniform2fv(location, 1, (GLfloat*)&xy);
4282}
4283
4284void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4285{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004286 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004287
4288 try
4289 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004290 if (count < 0)
4291 {
4292 return error(GL_INVALID_VALUE);
4293 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004294
4295 if (location == -1)
4296 {
4297 return;
4298 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004299
4300 gl::Context *context = gl::getContext();
4301
4302 if (context)
4303 {
4304 gl::Program *program = context->getCurrentProgram();
4305
4306 if (!program)
4307 {
4308 return error(GL_INVALID_OPERATION);
4309 }
4310
4311 if (!program->setUniform2fv(location, count, v))
4312 {
4313 return error(GL_INVALID_OPERATION);
4314 }
4315 }
4316 }
4317 catch(std::bad_alloc&)
4318 {
4319 return error(GL_OUT_OF_MEMORY);
4320 }
4321}
4322
4323void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4324{
4325 GLint xy[4] = {x, y};
4326
4327 glUniform2iv(location, 1, (GLint*)&xy);
4328}
4329
4330void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4331{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004332 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004333
4334 try
4335 {
4336 if (count < 0)
4337 {
4338 return error(GL_INVALID_VALUE);
4339 }
4340
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004341 if (location == -1)
4342 {
4343 return;
4344 }
4345
4346 gl::Context *context = gl::getContext();
4347
4348 if (context)
4349 {
4350 gl::Program *program = context->getCurrentProgram();
4351
4352 if (!program)
4353 {
4354 return error(GL_INVALID_OPERATION);
4355 }
4356
4357 if (!program->setUniform2iv(location, count, v))
4358 {
4359 return error(GL_INVALID_OPERATION);
4360 }
4361 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004362 }
4363 catch(std::bad_alloc&)
4364 {
4365 return error(GL_OUT_OF_MEMORY);
4366 }
4367}
4368
4369void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4370{
4371 GLfloat xyz[3] = {x, y, z};
4372
4373 glUniform3fv(location, 1, (GLfloat*)&xyz);
4374}
4375
4376void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4377{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004378 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004379
4380 try
4381 {
4382 if (count < 0)
4383 {
4384 return error(GL_INVALID_VALUE);
4385 }
4386
4387 if (location == -1)
4388 {
4389 return;
4390 }
4391
4392 gl::Context *context = gl::getContext();
4393
4394 if (context)
4395 {
4396 gl::Program *program = context->getCurrentProgram();
4397
4398 if (!program)
4399 {
4400 return error(GL_INVALID_OPERATION);
4401 }
4402
4403 if (!program->setUniform3fv(location, count, v))
4404 {
4405 return error(GL_INVALID_OPERATION);
4406 }
4407 }
4408 }
4409 catch(std::bad_alloc&)
4410 {
4411 return error(GL_OUT_OF_MEMORY);
4412 }
4413}
4414
4415void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4416{
4417 GLint xyz[3] = {x, y, z};
4418
4419 glUniform3iv(location, 1, (GLint*)&xyz);
4420}
4421
4422void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4423{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004424 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004425
4426 try
4427 {
4428 if (count < 0)
4429 {
4430 return error(GL_INVALID_VALUE);
4431 }
4432
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004433 if (location == -1)
4434 {
4435 return;
4436 }
4437
4438 gl::Context *context = gl::getContext();
4439
4440 if (context)
4441 {
4442 gl::Program *program = context->getCurrentProgram();
4443
4444 if (!program)
4445 {
4446 return error(GL_INVALID_OPERATION);
4447 }
4448
4449 if (!program->setUniform3iv(location, count, v))
4450 {
4451 return error(GL_INVALID_OPERATION);
4452 }
4453 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004454 }
4455 catch(std::bad_alloc&)
4456 {
4457 return error(GL_OUT_OF_MEMORY);
4458 }
4459}
4460
4461void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4462{
4463 GLfloat xyzw[4] = {x, y, z, w};
4464
4465 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4466}
4467
4468void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4469{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004470 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004471
4472 try
4473 {
4474 if (count < 0)
4475 {
4476 return error(GL_INVALID_VALUE);
4477 }
4478
4479 if (location == -1)
4480 {
4481 return;
4482 }
4483
4484 gl::Context *context = gl::getContext();
4485
4486 if (context)
4487 {
4488 gl::Program *program = context->getCurrentProgram();
4489
4490 if (!program)
4491 {
4492 return error(GL_INVALID_OPERATION);
4493 }
4494
4495 if (!program->setUniform4fv(location, count, v))
4496 {
4497 return error(GL_INVALID_OPERATION);
4498 }
4499 }
4500 }
4501 catch(std::bad_alloc&)
4502 {
4503 return error(GL_OUT_OF_MEMORY);
4504 }
4505}
4506
4507void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4508{
4509 GLint xyzw[4] = {x, y, z, w};
4510
4511 glUniform4iv(location, 1, (GLint*)&xyzw);
4512}
4513
4514void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4515{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004516 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004517
4518 try
4519 {
4520 if (count < 0)
4521 {
4522 return error(GL_INVALID_VALUE);
4523 }
4524
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004525 if (location == -1)
4526 {
4527 return;
4528 }
4529
4530 gl::Context *context = gl::getContext();
4531
4532 if (context)
4533 {
4534 gl::Program *program = context->getCurrentProgram();
4535
4536 if (!program)
4537 {
4538 return error(GL_INVALID_OPERATION);
4539 }
4540
4541 if (!program->setUniform4iv(location, count, v))
4542 {
4543 return error(GL_INVALID_OPERATION);
4544 }
4545 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004546 }
4547 catch(std::bad_alloc&)
4548 {
4549 return error(GL_OUT_OF_MEMORY);
4550 }
4551}
4552
4553void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4554{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004555 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4556 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004557
4558 try
4559 {
4560 if (count < 0 || transpose != GL_FALSE)
4561 {
4562 return error(GL_INVALID_VALUE);
4563 }
4564
4565 if (location == -1)
4566 {
4567 return;
4568 }
4569
4570 gl::Context *context = gl::getContext();
4571
4572 if (context)
4573 {
4574 gl::Program *program = context->getCurrentProgram();
4575
4576 if (!program)
4577 {
4578 return error(GL_INVALID_OPERATION);
4579 }
4580
4581 if (!program->setUniformMatrix2fv(location, count, value))
4582 {
4583 return error(GL_INVALID_OPERATION);
4584 }
4585 }
4586 }
4587 catch(std::bad_alloc&)
4588 {
4589 return error(GL_OUT_OF_MEMORY);
4590 }
4591}
4592
4593void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4594{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004595 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4596 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004597
4598 try
4599 {
4600 if (count < 0 || transpose != GL_FALSE)
4601 {
4602 return error(GL_INVALID_VALUE);
4603 }
4604
4605 if (location == -1)
4606 {
4607 return;
4608 }
4609
4610 gl::Context *context = gl::getContext();
4611
4612 if (context)
4613 {
4614 gl::Program *program = context->getCurrentProgram();
4615
4616 if (!program)
4617 {
4618 return error(GL_INVALID_OPERATION);
4619 }
4620
4621 if (!program->setUniformMatrix3fv(location, count, value))
4622 {
4623 return error(GL_INVALID_OPERATION);
4624 }
4625 }
4626 }
4627 catch(std::bad_alloc&)
4628 {
4629 return error(GL_OUT_OF_MEMORY);
4630 }
4631}
4632
4633void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4634{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004635 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4636 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004637
4638 try
4639 {
4640 if (count < 0 || transpose != GL_FALSE)
4641 {
4642 return error(GL_INVALID_VALUE);
4643 }
4644
4645 if (location == -1)
4646 {
4647 return;
4648 }
4649
4650 gl::Context *context = gl::getContext();
4651
4652 if (context)
4653 {
4654 gl::Program *program = context->getCurrentProgram();
4655
4656 if (!program)
4657 {
4658 return error(GL_INVALID_OPERATION);
4659 }
4660
4661 if (!program->setUniformMatrix4fv(location, count, value))
4662 {
4663 return error(GL_INVALID_OPERATION);
4664 }
4665 }
4666 }
4667 catch(std::bad_alloc&)
4668 {
4669 return error(GL_OUT_OF_MEMORY);
4670 }
4671}
4672
4673void __stdcall glUseProgram(GLuint program)
4674{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004675 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004676
4677 try
4678 {
4679 gl::Context *context = gl::getContext();
4680
4681 if (context)
4682 {
4683 gl::Program *programObject = context->getProgram(program);
4684
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004685 if (!programObject && program != 0)
4686 {
4687 if (context->getShader(program))
4688 {
4689 return error(GL_INVALID_OPERATION);
4690 }
4691 else
4692 {
4693 return error(GL_INVALID_VALUE);
4694 }
4695 }
4696
4697 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004698 {
4699 return error(GL_INVALID_OPERATION);
4700 }
4701
4702 context->useProgram(program);
4703 }
4704 }
4705 catch(std::bad_alloc&)
4706 {
4707 return error(GL_OUT_OF_MEMORY);
4708 }
4709}
4710
4711void __stdcall glValidateProgram(GLuint program)
4712{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004713 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004714
4715 try
4716 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00004717 gl::Context *context = gl::getContext();
4718
4719 if (context)
4720 {
4721 gl::Program *programObject = context->getProgram(program);
4722
4723 if (!programObject)
4724 {
4725 if (context->getShader(program))
4726 {
4727 return error(GL_INVALID_OPERATION);
4728 }
4729 else
4730 {
4731 return error(GL_INVALID_VALUE);
4732 }
4733 }
4734
4735 programObject->validate();
4736 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004737 }
4738 catch(std::bad_alloc&)
4739 {
4740 return error(GL_OUT_OF_MEMORY);
4741 }
4742}
4743
4744void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4745{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004746 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004747
4748 try
4749 {
4750 if (index >= gl::MAX_VERTEX_ATTRIBS)
4751 {
4752 return error(GL_INVALID_VALUE);
4753 }
4754
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004755 gl::Context *context = gl::getContext();
4756
4757 if (context)
4758 {
4759 GLfloat vals[4] = { x, 0, 0, 1 };
4760 context->setVertexAttrib(index, vals);
4761 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004762 }
4763 catch(std::bad_alloc&)
4764 {
4765 return error(GL_OUT_OF_MEMORY);
4766 }
4767}
4768
4769void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4770{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004771 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004772
4773 try
4774 {
4775 if (index >= gl::MAX_VERTEX_ATTRIBS)
4776 {
4777 return error(GL_INVALID_VALUE);
4778 }
4779
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004780 gl::Context *context = gl::getContext();
4781
4782 if (context)
4783 {
4784 GLfloat vals[4] = { values[0], 0, 0, 1 };
4785 context->setVertexAttrib(index, vals);
4786 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004787 }
4788 catch(std::bad_alloc&)
4789 {
4790 return error(GL_OUT_OF_MEMORY);
4791 }
4792}
4793
4794void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4795{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004796 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004797
4798 try
4799 {
4800 if (index >= gl::MAX_VERTEX_ATTRIBS)
4801 {
4802 return error(GL_INVALID_VALUE);
4803 }
4804
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004805 gl::Context *context = gl::getContext();
4806
4807 if (context)
4808 {
4809 GLfloat vals[4] = { x, y, 0, 1 };
4810 context->setVertexAttrib(index, vals);
4811 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004812 }
4813 catch(std::bad_alloc&)
4814 {
4815 return error(GL_OUT_OF_MEMORY);
4816 }
4817}
4818
4819void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4820{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004821 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004822
4823 try
4824 {
4825 if (index >= gl::MAX_VERTEX_ATTRIBS)
4826 {
4827 return error(GL_INVALID_VALUE);
4828 }
4829
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004830 gl::Context *context = gl::getContext();
4831
4832 if (context)
4833 {
4834 GLfloat vals[4] = { values[0], values[1], 0, 1 };
4835 context->setVertexAttrib(index, vals);
4836 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004837 }
4838 catch(std::bad_alloc&)
4839 {
4840 return error(GL_OUT_OF_MEMORY);
4841 }
4842}
4843
4844void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4845{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004846 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 +00004847
4848 try
4849 {
4850 if (index >= gl::MAX_VERTEX_ATTRIBS)
4851 {
4852 return error(GL_INVALID_VALUE);
4853 }
4854
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004855 gl::Context *context = gl::getContext();
4856
4857 if (context)
4858 {
4859 GLfloat vals[4] = { x, y, z, 1 };
4860 context->setVertexAttrib(index, vals);
4861 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004862 }
4863 catch(std::bad_alloc&)
4864 {
4865 return error(GL_OUT_OF_MEMORY);
4866 }
4867}
4868
4869void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4870{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004871 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004872
4873 try
4874 {
4875 if (index >= gl::MAX_VERTEX_ATTRIBS)
4876 {
4877 return error(GL_INVALID_VALUE);
4878 }
4879
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004880 gl::Context *context = gl::getContext();
4881
4882 if (context)
4883 {
4884 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
4885 context->setVertexAttrib(index, vals);
4886 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004887 }
4888 catch(std::bad_alloc&)
4889 {
4890 return error(GL_OUT_OF_MEMORY);
4891 }
4892}
4893
4894void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4895{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004896 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 +00004897
4898 try
4899 {
4900 if (index >= gl::MAX_VERTEX_ATTRIBS)
4901 {
4902 return error(GL_INVALID_VALUE);
4903 }
4904
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004905 gl::Context *context = gl::getContext();
4906
4907 if (context)
4908 {
4909 GLfloat vals[4] = { x, y, z, w };
4910 context->setVertexAttrib(index, vals);
4911 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004912 }
4913 catch(std::bad_alloc&)
4914 {
4915 return error(GL_OUT_OF_MEMORY);
4916 }
4917}
4918
4919void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4920{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004921 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004922
4923 try
4924 {
4925 if (index >= gl::MAX_VERTEX_ATTRIBS)
4926 {
4927 return error(GL_INVALID_VALUE);
4928 }
4929
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004930 gl::Context *context = gl::getContext();
4931
4932 if (context)
4933 {
4934 context->setVertexAttrib(index, values);
4935 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004936 }
4937 catch(std::bad_alloc&)
4938 {
4939 return error(GL_OUT_OF_MEMORY);
4940 }
4941}
4942
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004943void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004944{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004945 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004946 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004947 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004948
4949 try
4950 {
4951 if (index >= gl::MAX_VERTEX_ATTRIBS)
4952 {
4953 return error(GL_INVALID_VALUE);
4954 }
4955
4956 if (size < 1 || size > 4)
4957 {
4958 return error(GL_INVALID_VALUE);
4959 }
4960
4961 switch (type)
4962 {
4963 case GL_BYTE:
4964 case GL_UNSIGNED_BYTE:
4965 case GL_SHORT:
4966 case GL_UNSIGNED_SHORT:
4967 case GL_FIXED:
4968 case GL_FLOAT:
4969 break;
4970 default:
4971 return error(GL_INVALID_ENUM);
4972 }
4973
4974 if (stride < 0)
4975 {
4976 return error(GL_INVALID_VALUE);
4977 }
4978
4979 gl::Context *context = gl::getContext();
4980
4981 if (context)
4982 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004983 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004984 }
4985 }
4986 catch(std::bad_alloc&)
4987 {
4988 return error(GL_OUT_OF_MEMORY);
4989 }
4990}
4991
4992void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4993{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004994 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 +00004995
4996 try
4997 {
4998 if (width < 0 || height < 0)
4999 {
5000 return error(GL_INVALID_VALUE);
5001 }
5002
5003 gl::Context *context = gl::getContext();
5004
5005 if (context)
5006 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005007 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005008 }
5009 }
5010 catch(std::bad_alloc&)
5011 {
5012 return error(GL_OUT_OF_MEMORY);
5013 }
5014}
5015
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005016void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5017 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005018{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005019 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5020 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005021 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005022 target, level, internalformat, width, height, depth, border, format, type, pixels);
5023
5024 try
5025 {
5026 UNIMPLEMENTED(); // FIXME
5027 }
5028 catch(std::bad_alloc&)
5029 {
5030 return error(GL_OUT_OF_MEMORY);
5031 }
5032}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005033
5034__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5035{
5036 struct Extension
5037 {
5038 const char *name;
5039 __eglMustCastToProperFunctionPointerType address;
5040 };
5041
5042 static const Extension glExtensions[] =
5043 {
5044 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
5045 };
5046
5047 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5048 {
5049 if (strcmp(procname, glExtensions[ext].name) == 0)
5050 {
5051 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5052 }
5053 }
5054
5055 return NULL;
5056}
5057
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005058}