blob: 795f4b93abf0b8bb77ad2a8f3739a52876602e33 [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;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003494 case GL_BGRA_EXT:
3495 switch (type)
3496 {
3497 case GL_UNSIGNED_BYTE:
3498 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3499 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3500 break;
3501 default:
3502 return error(GL_INVALID_OPERATION);
3503 }
3504 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003505 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3506 switch (type)
3507 {
3508 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3509 break;
3510 default:
3511 return error(GL_INVALID_OPERATION);
3512 }
3513 break;
3514 default:
3515 return error(GL_INVALID_OPERATION);
3516 }
3517
3518 gl::Context *context = gl::getContext();
3519
3520 if (context)
3521 {
3522 context->readPixels(x, y, width, height, format, type, pixels);
3523 }
3524 }
3525 catch(std::bad_alloc&)
3526 {
3527 return error(GL_OUT_OF_MEMORY);
3528 }
3529}
3530
3531void __stdcall glReleaseShaderCompiler(void)
3532{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003533 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003534
3535 try
3536 {
3537 gl::Shader::releaseCompiler();
3538 }
3539 catch(std::bad_alloc&)
3540 {
3541 return error(GL_OUT_OF_MEMORY);
3542 }
3543}
3544
3545void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3546{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003547 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3548 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003549
3550 try
3551 {
3552 switch (target)
3553 {
3554 case GL_RENDERBUFFER:
3555 break;
3556 default:
3557 return error(GL_INVALID_ENUM);
3558 }
3559
3560 switch (internalformat)
3561 {
3562 case GL_DEPTH_COMPONENT16:
3563 case GL_RGBA4:
3564 case GL_RGB5_A1:
3565 case GL_RGB565:
3566 case GL_STENCIL_INDEX8:
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003567 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003568 break;
3569 default:
3570 return error(GL_INVALID_ENUM);
3571 }
3572
3573 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3574 {
3575 return error(GL_INVALID_VALUE);
3576 }
3577
3578 gl::Context *context = gl::getContext();
3579
3580 if (context)
3581 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003582 GLuint handle = context->getRenderbufferHandle();
3583 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003584 {
3585 return error(GL_INVALID_OPERATION);
3586 }
3587
3588 switch (internalformat)
3589 {
3590 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003591 context->setRenderbufferStorage(new gl::Depthbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003592 break;
3593 case GL_RGBA4:
3594 case GL_RGB5_A1:
3595 case GL_RGB565:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003596 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003597 break;
3598 case GL_STENCIL_INDEX8:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003599 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003600 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003601 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003602 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003603 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003604 default:
3605 return error(GL_INVALID_ENUM);
3606 }
3607 }
3608 }
3609 catch(std::bad_alloc&)
3610 {
3611 return error(GL_OUT_OF_MEMORY);
3612 }
3613}
3614
3615void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3616{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003617 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003618
3619 try
3620 {
3621 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003622
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003623 if (context)
3624 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00003625 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003626 }
3627 }
3628 catch(std::bad_alloc&)
3629 {
3630 return error(GL_OUT_OF_MEMORY);
3631 }
3632}
3633
3634void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3635{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003636 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 +00003637
3638 try
3639 {
3640 if (width < 0 || height < 0)
3641 {
3642 return error(GL_INVALID_VALUE);
3643 }
3644
3645 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003646
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003647 if (context)
3648 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003649 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003650 }
3651 }
3652 catch(std::bad_alloc&)
3653 {
3654 return error(GL_OUT_OF_MEMORY);
3655 }
3656}
3657
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003658void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003659{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003660 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003661 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003662 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003663
3664 try
3665 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00003666 // No binary shader formats are supported.
3667 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003668 }
3669 catch(std::bad_alloc&)
3670 {
3671 return error(GL_OUT_OF_MEMORY);
3672 }
3673}
3674
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003675void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003676{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003677 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 +00003678 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003679
3680 try
3681 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003682 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003683 {
3684 return error(GL_INVALID_VALUE);
3685 }
3686
3687 gl::Context *context = gl::getContext();
3688
3689 if (context)
3690 {
3691 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003692
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003693 if (!shaderObject)
3694 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003695 if (context->getProgram(shader))
3696 {
3697 return error(GL_INVALID_OPERATION);
3698 }
3699 else
3700 {
3701 return error(GL_INVALID_VALUE);
3702 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003703 }
3704
3705 shaderObject->setSource(count, string, length);
3706 }
3707 }
3708 catch(std::bad_alloc&)
3709 {
3710 return error(GL_OUT_OF_MEMORY);
3711 }
3712}
3713
3714void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3715{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003716 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003717}
3718
3719void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3720{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003721 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 +00003722
3723 try
3724 {
3725 switch (face)
3726 {
3727 case GL_FRONT:
3728 case GL_BACK:
3729 case GL_FRONT_AND_BACK:
3730 break;
3731 default:
3732 return error(GL_INVALID_ENUM);
3733 }
3734
3735 switch (func)
3736 {
3737 case GL_NEVER:
3738 case GL_ALWAYS:
3739 case GL_LESS:
3740 case GL_LEQUAL:
3741 case GL_EQUAL:
3742 case GL_GEQUAL:
3743 case GL_GREATER:
3744 case GL_NOTEQUAL:
3745 break;
3746 default:
3747 return error(GL_INVALID_ENUM);
3748 }
3749
3750 gl::Context *context = gl::getContext();
3751
3752 if (context)
3753 {
3754 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3755 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003756 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003757 }
3758
3759 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3760 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003761 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003762 }
3763 }
3764 }
3765 catch(std::bad_alloc&)
3766 {
3767 return error(GL_OUT_OF_MEMORY);
3768 }
3769}
3770
3771void __stdcall glStencilMask(GLuint mask)
3772{
3773 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3774}
3775
3776void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3777{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003778 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003779
3780 try
3781 {
3782 switch (face)
3783 {
3784 case GL_FRONT:
3785 case GL_BACK:
3786 case GL_FRONT_AND_BACK:
3787 break;
3788 default:
3789 return error(GL_INVALID_ENUM);
3790 }
3791
3792 gl::Context *context = gl::getContext();
3793
3794 if (context)
3795 {
3796 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3797 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003798 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003799 }
3800
3801 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3802 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003803 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003804 }
3805 }
3806 }
3807 catch(std::bad_alloc&)
3808 {
3809 return error(GL_OUT_OF_MEMORY);
3810 }
3811}
3812
3813void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3814{
3815 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3816}
3817
3818void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3819{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003820 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3821 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003822
3823 try
3824 {
3825 switch (face)
3826 {
3827 case GL_FRONT:
3828 case GL_BACK:
3829 case GL_FRONT_AND_BACK:
3830 break;
3831 default:
3832 return error(GL_INVALID_ENUM);
3833 }
3834
3835 switch (fail)
3836 {
3837 case GL_ZERO:
3838 case GL_KEEP:
3839 case GL_REPLACE:
3840 case GL_INCR:
3841 case GL_DECR:
3842 case GL_INVERT:
3843 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003844 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003845 break;
3846 default:
3847 return error(GL_INVALID_ENUM);
3848 }
3849
3850 switch (zfail)
3851 {
3852 case GL_ZERO:
3853 case GL_KEEP:
3854 case GL_REPLACE:
3855 case GL_INCR:
3856 case GL_DECR:
3857 case GL_INVERT:
3858 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003859 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003860 break;
3861 default:
3862 return error(GL_INVALID_ENUM);
3863 }
3864
3865 switch (zpass)
3866 {
3867 case GL_ZERO:
3868 case GL_KEEP:
3869 case GL_REPLACE:
3870 case GL_INCR:
3871 case GL_DECR:
3872 case GL_INVERT:
3873 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003874 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003875 break;
3876 default:
3877 return error(GL_INVALID_ENUM);
3878 }
3879
3880 gl::Context *context = gl::getContext();
3881
3882 if (context)
3883 {
3884 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3885 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003886 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003887 }
3888
3889 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3890 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003891 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003892 }
3893 }
3894 }
3895 catch(std::bad_alloc&)
3896 {
3897 return error(GL_OUT_OF_MEMORY);
3898 }
3899}
3900
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003901void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3902 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003903{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003904 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003905 "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 +00003906 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003907
3908 try
3909 {
3910 if (level < 0 || width < 0 || height < 0)
3911 {
3912 return error(GL_INVALID_VALUE);
3913 }
3914
3915 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3916 {
3917 return error(GL_INVALID_VALUE);
3918 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003919
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003920 switch (target)
3921 {
3922 case GL_TEXTURE_2D:
3923 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3924 {
3925 return error(GL_INVALID_VALUE);
3926 }
3927 break;
3928 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3929 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3930 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3931 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3932 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3933 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003934 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003935 {
3936 return error(GL_INVALID_VALUE);
3937 }
3938
3939 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3940 {
3941 return error(GL_INVALID_VALUE);
3942 }
3943 break;
3944 default:
3945 return error(GL_INVALID_ENUM);
3946 }
3947
3948 if (internalformat != format)
3949 {
3950 return error(GL_INVALID_OPERATION);
3951 }
3952
3953 switch (internalformat)
3954 {
3955 case GL_ALPHA:
3956 case GL_LUMINANCE:
3957 case GL_LUMINANCE_ALPHA:
3958 switch (type)
3959 {
3960 case GL_UNSIGNED_BYTE:
3961 break;
3962 default:
3963 return error(GL_INVALID_ENUM);
3964 }
3965 break;
3966 case GL_RGB:
3967 switch (type)
3968 {
3969 case GL_UNSIGNED_BYTE:
3970 case GL_UNSIGNED_SHORT_5_6_5:
3971 break;
3972 default:
3973 return error(GL_INVALID_ENUM);
3974 }
3975 break;
3976 case GL_RGBA:
3977 switch (type)
3978 {
3979 case GL_UNSIGNED_BYTE:
3980 case GL_UNSIGNED_SHORT_4_4_4_4:
3981 case GL_UNSIGNED_SHORT_5_5_5_1:
3982 break;
3983 default:
3984 return error(GL_INVALID_ENUM);
3985 }
3986 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003987 case GL_BGRA_EXT:
3988 switch (type)
3989 {
3990 case GL_UNSIGNED_BYTE:
3991 break;
3992 default:
3993 return error(GL_INVALID_ENUM);
3994 }
3995 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003996 default:
3997 return error(GL_INVALID_VALUE);
3998 }
3999
4000 if (border != 0)
4001 {
4002 return error(GL_INVALID_VALUE);
4003 }
4004
4005 gl::Context *context = gl::getContext();
4006
4007 if (context)
4008 {
4009 if (target == GL_TEXTURE_2D)
4010 {
4011 gl::Texture2D *texture = context->getTexture2D();
4012
4013 if (!texture)
4014 {
4015 return error(GL_INVALID_OPERATION);
4016 }
4017
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004018 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004019 }
4020 else
4021 {
4022 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4023
4024 if (!texture)
4025 {
4026 return error(GL_INVALID_OPERATION);
4027 }
4028
4029 switch (target)
4030 {
4031 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004032 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004033 break;
4034 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004035 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004036 break;
4037 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004038 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004039 break;
4040 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004041 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004042 break;
4043 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004044 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004045 break;
4046 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004047 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004048 break;
4049 default: UNREACHABLE();
4050 }
4051 }
4052 }
4053 }
4054 catch(std::bad_alloc&)
4055 {
4056 return error(GL_OUT_OF_MEMORY);
4057 }
4058}
4059
4060void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4061{
4062 glTexParameteri(target, pname, (GLint)param);
4063}
4064
4065void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4066{
4067 glTexParameteri(target, pname, (GLint)*params);
4068}
4069
4070void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4071{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004072 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004073
4074 try
4075 {
4076 gl::Context *context = gl::getContext();
4077
4078 if (context)
4079 {
4080 gl::Texture *texture;
4081
4082 switch (target)
4083 {
4084 case GL_TEXTURE_2D:
4085 texture = context->getTexture2D();
4086 break;
4087 case GL_TEXTURE_CUBE_MAP:
4088 texture = context->getTextureCubeMap();
4089 break;
4090 default:
4091 return error(GL_INVALID_ENUM);
4092 }
4093
4094 switch (pname)
4095 {
4096 case GL_TEXTURE_WRAP_S:
4097 if (!texture->setWrapS((GLenum)param))
4098 {
4099 return error(GL_INVALID_ENUM);
4100 }
4101 break;
4102 case GL_TEXTURE_WRAP_T:
4103 if (!texture->setWrapT((GLenum)param))
4104 {
4105 return error(GL_INVALID_ENUM);
4106 }
4107 break;
4108 case GL_TEXTURE_MIN_FILTER:
4109 if (!texture->setMinFilter((GLenum)param))
4110 {
4111 return error(GL_INVALID_ENUM);
4112 }
4113 break;
4114 case GL_TEXTURE_MAG_FILTER:
4115 if (!texture->setMagFilter((GLenum)param))
4116 {
4117 return error(GL_INVALID_ENUM);
4118 }
4119 break;
4120 default:
4121 return error(GL_INVALID_ENUM);
4122 }
4123 }
4124 }
4125 catch(std::bad_alloc&)
4126 {
4127 return error(GL_OUT_OF_MEMORY);
4128 }
4129}
4130
4131void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4132{
4133 glTexParameteri(target, pname, *params);
4134}
4135
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004136void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4137 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004138{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004139 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4140 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004141 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004142 target, level, xoffset, yoffset, width, height, format, type, pixels);
4143
4144 try
4145 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004146 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004147 {
4148 return error(GL_INVALID_ENUM);
4149 }
4150
4151 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004152 {
4153 return error(GL_INVALID_VALUE);
4154 }
4155
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004156 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4157 {
4158 return error(GL_INVALID_VALUE);
4159 }
4160
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004161 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004162 {
4163 return error(GL_INVALID_ENUM);
4164 }
4165
4166 if (width == 0 || height == 0 || pixels == NULL)
4167 {
4168 return;
4169 }
4170
4171 gl::Context *context = gl::getContext();
4172
4173 if (context)
4174 {
4175 if (target == GL_TEXTURE_2D)
4176 {
4177 gl::Texture2D *texture = context->getTexture2D();
4178
4179 if (!texture)
4180 {
4181 return error(GL_INVALID_OPERATION);
4182 }
4183
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004184 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004185 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004186 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004187 {
4188 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4189
4190 if (!texture)
4191 {
4192 return error(GL_INVALID_OPERATION);
4193 }
4194
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004195 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004196 }
4197 else
4198 {
4199 UNREACHABLE();
4200 }
4201 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004202 }
4203 catch(std::bad_alloc&)
4204 {
4205 return error(GL_OUT_OF_MEMORY);
4206 }
4207}
4208
4209void __stdcall glUniform1f(GLint location, GLfloat x)
4210{
4211 glUniform1fv(location, 1, &x);
4212}
4213
4214void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4215{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004216 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004217
4218 try
4219 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004220 if (count < 0)
4221 {
4222 return error(GL_INVALID_VALUE);
4223 }
4224
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004225 if (location == -1)
4226 {
4227 return;
4228 }
4229
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004230 gl::Context *context = gl::getContext();
4231
4232 if (context)
4233 {
4234 gl::Program *program = context->getCurrentProgram();
4235
4236 if (!program)
4237 {
4238 return error(GL_INVALID_OPERATION);
4239 }
4240
4241 if (!program->setUniform1fv(location, count, v))
4242 {
4243 return error(GL_INVALID_OPERATION);
4244 }
4245 }
4246 }
4247 catch(std::bad_alloc&)
4248 {
4249 return error(GL_OUT_OF_MEMORY);
4250 }
4251}
4252
4253void __stdcall glUniform1i(GLint location, GLint x)
4254{
4255 glUniform1iv(location, 1, &x);
4256}
4257
4258void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4259{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004260 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004261
4262 try
4263 {
4264 if (count < 0)
4265 {
4266 return error(GL_INVALID_VALUE);
4267 }
4268
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004269 if (location == -1)
4270 {
4271 return;
4272 }
4273
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004274 gl::Context *context = gl::getContext();
4275
4276 if (context)
4277 {
4278 gl::Program *program = context->getCurrentProgram();
4279
4280 if (!program)
4281 {
4282 return error(GL_INVALID_OPERATION);
4283 }
4284
4285 if (!program->setUniform1iv(location, count, v))
4286 {
4287 return error(GL_INVALID_OPERATION);
4288 }
4289 }
4290 }
4291 catch(std::bad_alloc&)
4292 {
4293 return error(GL_OUT_OF_MEMORY);
4294 }
4295}
4296
4297void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4298{
4299 GLfloat xy[2] = {x, y};
4300
4301 glUniform2fv(location, 1, (GLfloat*)&xy);
4302}
4303
4304void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4305{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004306 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004307
4308 try
4309 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004310 if (count < 0)
4311 {
4312 return error(GL_INVALID_VALUE);
4313 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004314
4315 if (location == -1)
4316 {
4317 return;
4318 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004319
4320 gl::Context *context = gl::getContext();
4321
4322 if (context)
4323 {
4324 gl::Program *program = context->getCurrentProgram();
4325
4326 if (!program)
4327 {
4328 return error(GL_INVALID_OPERATION);
4329 }
4330
4331 if (!program->setUniform2fv(location, count, v))
4332 {
4333 return error(GL_INVALID_OPERATION);
4334 }
4335 }
4336 }
4337 catch(std::bad_alloc&)
4338 {
4339 return error(GL_OUT_OF_MEMORY);
4340 }
4341}
4342
4343void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4344{
4345 GLint xy[4] = {x, y};
4346
4347 glUniform2iv(location, 1, (GLint*)&xy);
4348}
4349
4350void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4351{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004352 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004353
4354 try
4355 {
4356 if (count < 0)
4357 {
4358 return error(GL_INVALID_VALUE);
4359 }
4360
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004361 if (location == -1)
4362 {
4363 return;
4364 }
4365
4366 gl::Context *context = gl::getContext();
4367
4368 if (context)
4369 {
4370 gl::Program *program = context->getCurrentProgram();
4371
4372 if (!program)
4373 {
4374 return error(GL_INVALID_OPERATION);
4375 }
4376
4377 if (!program->setUniform2iv(location, count, v))
4378 {
4379 return error(GL_INVALID_OPERATION);
4380 }
4381 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004382 }
4383 catch(std::bad_alloc&)
4384 {
4385 return error(GL_OUT_OF_MEMORY);
4386 }
4387}
4388
4389void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4390{
4391 GLfloat xyz[3] = {x, y, z};
4392
4393 glUniform3fv(location, 1, (GLfloat*)&xyz);
4394}
4395
4396void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4397{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004398 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004399
4400 try
4401 {
4402 if (count < 0)
4403 {
4404 return error(GL_INVALID_VALUE);
4405 }
4406
4407 if (location == -1)
4408 {
4409 return;
4410 }
4411
4412 gl::Context *context = gl::getContext();
4413
4414 if (context)
4415 {
4416 gl::Program *program = context->getCurrentProgram();
4417
4418 if (!program)
4419 {
4420 return error(GL_INVALID_OPERATION);
4421 }
4422
4423 if (!program->setUniform3fv(location, count, v))
4424 {
4425 return error(GL_INVALID_OPERATION);
4426 }
4427 }
4428 }
4429 catch(std::bad_alloc&)
4430 {
4431 return error(GL_OUT_OF_MEMORY);
4432 }
4433}
4434
4435void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4436{
4437 GLint xyz[3] = {x, y, z};
4438
4439 glUniform3iv(location, 1, (GLint*)&xyz);
4440}
4441
4442void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4443{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004444 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004445
4446 try
4447 {
4448 if (count < 0)
4449 {
4450 return error(GL_INVALID_VALUE);
4451 }
4452
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004453 if (location == -1)
4454 {
4455 return;
4456 }
4457
4458 gl::Context *context = gl::getContext();
4459
4460 if (context)
4461 {
4462 gl::Program *program = context->getCurrentProgram();
4463
4464 if (!program)
4465 {
4466 return error(GL_INVALID_OPERATION);
4467 }
4468
4469 if (!program->setUniform3iv(location, count, v))
4470 {
4471 return error(GL_INVALID_OPERATION);
4472 }
4473 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004474 }
4475 catch(std::bad_alloc&)
4476 {
4477 return error(GL_OUT_OF_MEMORY);
4478 }
4479}
4480
4481void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4482{
4483 GLfloat xyzw[4] = {x, y, z, w};
4484
4485 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4486}
4487
4488void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4489{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004490 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004491
4492 try
4493 {
4494 if (count < 0)
4495 {
4496 return error(GL_INVALID_VALUE);
4497 }
4498
4499 if (location == -1)
4500 {
4501 return;
4502 }
4503
4504 gl::Context *context = gl::getContext();
4505
4506 if (context)
4507 {
4508 gl::Program *program = context->getCurrentProgram();
4509
4510 if (!program)
4511 {
4512 return error(GL_INVALID_OPERATION);
4513 }
4514
4515 if (!program->setUniform4fv(location, count, v))
4516 {
4517 return error(GL_INVALID_OPERATION);
4518 }
4519 }
4520 }
4521 catch(std::bad_alloc&)
4522 {
4523 return error(GL_OUT_OF_MEMORY);
4524 }
4525}
4526
4527void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4528{
4529 GLint xyzw[4] = {x, y, z, w};
4530
4531 glUniform4iv(location, 1, (GLint*)&xyzw);
4532}
4533
4534void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4535{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004536 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004537
4538 try
4539 {
4540 if (count < 0)
4541 {
4542 return error(GL_INVALID_VALUE);
4543 }
4544
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004545 if (location == -1)
4546 {
4547 return;
4548 }
4549
4550 gl::Context *context = gl::getContext();
4551
4552 if (context)
4553 {
4554 gl::Program *program = context->getCurrentProgram();
4555
4556 if (!program)
4557 {
4558 return error(GL_INVALID_OPERATION);
4559 }
4560
4561 if (!program->setUniform4iv(location, count, v))
4562 {
4563 return error(GL_INVALID_OPERATION);
4564 }
4565 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004566 }
4567 catch(std::bad_alloc&)
4568 {
4569 return error(GL_OUT_OF_MEMORY);
4570 }
4571}
4572
4573void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4574{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004575 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4576 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004577
4578 try
4579 {
4580 if (count < 0 || transpose != GL_FALSE)
4581 {
4582 return error(GL_INVALID_VALUE);
4583 }
4584
4585 if (location == -1)
4586 {
4587 return;
4588 }
4589
4590 gl::Context *context = gl::getContext();
4591
4592 if (context)
4593 {
4594 gl::Program *program = context->getCurrentProgram();
4595
4596 if (!program)
4597 {
4598 return error(GL_INVALID_OPERATION);
4599 }
4600
4601 if (!program->setUniformMatrix2fv(location, count, value))
4602 {
4603 return error(GL_INVALID_OPERATION);
4604 }
4605 }
4606 }
4607 catch(std::bad_alloc&)
4608 {
4609 return error(GL_OUT_OF_MEMORY);
4610 }
4611}
4612
4613void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4614{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004615 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4616 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004617
4618 try
4619 {
4620 if (count < 0 || transpose != GL_FALSE)
4621 {
4622 return error(GL_INVALID_VALUE);
4623 }
4624
4625 if (location == -1)
4626 {
4627 return;
4628 }
4629
4630 gl::Context *context = gl::getContext();
4631
4632 if (context)
4633 {
4634 gl::Program *program = context->getCurrentProgram();
4635
4636 if (!program)
4637 {
4638 return error(GL_INVALID_OPERATION);
4639 }
4640
4641 if (!program->setUniformMatrix3fv(location, count, value))
4642 {
4643 return error(GL_INVALID_OPERATION);
4644 }
4645 }
4646 }
4647 catch(std::bad_alloc&)
4648 {
4649 return error(GL_OUT_OF_MEMORY);
4650 }
4651}
4652
4653void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4654{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004655 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4656 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004657
4658 try
4659 {
4660 if (count < 0 || transpose != GL_FALSE)
4661 {
4662 return error(GL_INVALID_VALUE);
4663 }
4664
4665 if (location == -1)
4666 {
4667 return;
4668 }
4669
4670 gl::Context *context = gl::getContext();
4671
4672 if (context)
4673 {
4674 gl::Program *program = context->getCurrentProgram();
4675
4676 if (!program)
4677 {
4678 return error(GL_INVALID_OPERATION);
4679 }
4680
4681 if (!program->setUniformMatrix4fv(location, count, value))
4682 {
4683 return error(GL_INVALID_OPERATION);
4684 }
4685 }
4686 }
4687 catch(std::bad_alloc&)
4688 {
4689 return error(GL_OUT_OF_MEMORY);
4690 }
4691}
4692
4693void __stdcall glUseProgram(GLuint program)
4694{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004695 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004696
4697 try
4698 {
4699 gl::Context *context = gl::getContext();
4700
4701 if (context)
4702 {
4703 gl::Program *programObject = context->getProgram(program);
4704
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004705 if (!programObject && program != 0)
4706 {
4707 if (context->getShader(program))
4708 {
4709 return error(GL_INVALID_OPERATION);
4710 }
4711 else
4712 {
4713 return error(GL_INVALID_VALUE);
4714 }
4715 }
4716
4717 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004718 {
4719 return error(GL_INVALID_OPERATION);
4720 }
4721
4722 context->useProgram(program);
4723 }
4724 }
4725 catch(std::bad_alloc&)
4726 {
4727 return error(GL_OUT_OF_MEMORY);
4728 }
4729}
4730
4731void __stdcall glValidateProgram(GLuint program)
4732{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004733 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004734
4735 try
4736 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00004737 gl::Context *context = gl::getContext();
4738
4739 if (context)
4740 {
4741 gl::Program *programObject = context->getProgram(program);
4742
4743 if (!programObject)
4744 {
4745 if (context->getShader(program))
4746 {
4747 return error(GL_INVALID_OPERATION);
4748 }
4749 else
4750 {
4751 return error(GL_INVALID_VALUE);
4752 }
4753 }
4754
4755 programObject->validate();
4756 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004757 }
4758 catch(std::bad_alloc&)
4759 {
4760 return error(GL_OUT_OF_MEMORY);
4761 }
4762}
4763
4764void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4765{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004766 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004767
4768 try
4769 {
4770 if (index >= gl::MAX_VERTEX_ATTRIBS)
4771 {
4772 return error(GL_INVALID_VALUE);
4773 }
4774
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004775 gl::Context *context = gl::getContext();
4776
4777 if (context)
4778 {
4779 GLfloat vals[4] = { x, 0, 0, 1 };
4780 context->setVertexAttrib(index, vals);
4781 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004782 }
4783 catch(std::bad_alloc&)
4784 {
4785 return error(GL_OUT_OF_MEMORY);
4786 }
4787}
4788
4789void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4790{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004791 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004792
4793 try
4794 {
4795 if (index >= gl::MAX_VERTEX_ATTRIBS)
4796 {
4797 return error(GL_INVALID_VALUE);
4798 }
4799
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004800 gl::Context *context = gl::getContext();
4801
4802 if (context)
4803 {
4804 GLfloat vals[4] = { values[0], 0, 0, 1 };
4805 context->setVertexAttrib(index, vals);
4806 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004807 }
4808 catch(std::bad_alloc&)
4809 {
4810 return error(GL_OUT_OF_MEMORY);
4811 }
4812}
4813
4814void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4815{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004816 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004817
4818 try
4819 {
4820 if (index >= gl::MAX_VERTEX_ATTRIBS)
4821 {
4822 return error(GL_INVALID_VALUE);
4823 }
4824
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004825 gl::Context *context = gl::getContext();
4826
4827 if (context)
4828 {
4829 GLfloat vals[4] = { x, y, 0, 1 };
4830 context->setVertexAttrib(index, vals);
4831 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004832 }
4833 catch(std::bad_alloc&)
4834 {
4835 return error(GL_OUT_OF_MEMORY);
4836 }
4837}
4838
4839void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4840{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004841 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004842
4843 try
4844 {
4845 if (index >= gl::MAX_VERTEX_ATTRIBS)
4846 {
4847 return error(GL_INVALID_VALUE);
4848 }
4849
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004850 gl::Context *context = gl::getContext();
4851
4852 if (context)
4853 {
4854 GLfloat vals[4] = { values[0], values[1], 0, 1 };
4855 context->setVertexAttrib(index, vals);
4856 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004857 }
4858 catch(std::bad_alloc&)
4859 {
4860 return error(GL_OUT_OF_MEMORY);
4861 }
4862}
4863
4864void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4865{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004866 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 +00004867
4868 try
4869 {
4870 if (index >= gl::MAX_VERTEX_ATTRIBS)
4871 {
4872 return error(GL_INVALID_VALUE);
4873 }
4874
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004875 gl::Context *context = gl::getContext();
4876
4877 if (context)
4878 {
4879 GLfloat vals[4] = { x, y, z, 1 };
4880 context->setVertexAttrib(index, vals);
4881 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004882 }
4883 catch(std::bad_alloc&)
4884 {
4885 return error(GL_OUT_OF_MEMORY);
4886 }
4887}
4888
4889void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4890{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004891 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004892
4893 try
4894 {
4895 if (index >= gl::MAX_VERTEX_ATTRIBS)
4896 {
4897 return error(GL_INVALID_VALUE);
4898 }
4899
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004900 gl::Context *context = gl::getContext();
4901
4902 if (context)
4903 {
4904 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
4905 context->setVertexAttrib(index, vals);
4906 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004907 }
4908 catch(std::bad_alloc&)
4909 {
4910 return error(GL_OUT_OF_MEMORY);
4911 }
4912}
4913
4914void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4915{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004916 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 +00004917
4918 try
4919 {
4920 if (index >= gl::MAX_VERTEX_ATTRIBS)
4921 {
4922 return error(GL_INVALID_VALUE);
4923 }
4924
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004925 gl::Context *context = gl::getContext();
4926
4927 if (context)
4928 {
4929 GLfloat vals[4] = { x, y, z, w };
4930 context->setVertexAttrib(index, vals);
4931 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004932 }
4933 catch(std::bad_alloc&)
4934 {
4935 return error(GL_OUT_OF_MEMORY);
4936 }
4937}
4938
4939void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4940{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004941 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004942
4943 try
4944 {
4945 if (index >= gl::MAX_VERTEX_ATTRIBS)
4946 {
4947 return error(GL_INVALID_VALUE);
4948 }
4949
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004950 gl::Context *context = gl::getContext();
4951
4952 if (context)
4953 {
4954 context->setVertexAttrib(index, values);
4955 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004956 }
4957 catch(std::bad_alloc&)
4958 {
4959 return error(GL_OUT_OF_MEMORY);
4960 }
4961}
4962
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004963void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004964{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004965 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004966 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004967 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004968
4969 try
4970 {
4971 if (index >= gl::MAX_VERTEX_ATTRIBS)
4972 {
4973 return error(GL_INVALID_VALUE);
4974 }
4975
4976 if (size < 1 || size > 4)
4977 {
4978 return error(GL_INVALID_VALUE);
4979 }
4980
4981 switch (type)
4982 {
4983 case GL_BYTE:
4984 case GL_UNSIGNED_BYTE:
4985 case GL_SHORT:
4986 case GL_UNSIGNED_SHORT:
4987 case GL_FIXED:
4988 case GL_FLOAT:
4989 break;
4990 default:
4991 return error(GL_INVALID_ENUM);
4992 }
4993
4994 if (stride < 0)
4995 {
4996 return error(GL_INVALID_VALUE);
4997 }
4998
4999 gl::Context *context = gl::getContext();
5000
5001 if (context)
5002 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005003 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005004 }
5005 }
5006 catch(std::bad_alloc&)
5007 {
5008 return error(GL_OUT_OF_MEMORY);
5009 }
5010}
5011
5012void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5013{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005014 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 +00005015
5016 try
5017 {
5018 if (width < 0 || height < 0)
5019 {
5020 return error(GL_INVALID_VALUE);
5021 }
5022
5023 gl::Context *context = gl::getContext();
5024
5025 if (context)
5026 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005027 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005028 }
5029 }
5030 catch(std::bad_alloc&)
5031 {
5032 return error(GL_OUT_OF_MEMORY);
5033 }
5034}
5035
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005036void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5037 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005038{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005039 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5040 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005041 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005042 target, level, internalformat, width, height, depth, border, format, type, pixels);
5043
5044 try
5045 {
5046 UNIMPLEMENTED(); // FIXME
5047 }
5048 catch(std::bad_alloc&)
5049 {
5050 return error(GL_OUT_OF_MEMORY);
5051 }
5052}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005053
5054__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5055{
5056 struct Extension
5057 {
5058 const char *name;
5059 __eglMustCastToProperFunctionPointerType address;
5060 };
5061
5062 static const Extension glExtensions[] =
5063 {
5064 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
5065 };
5066
5067 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5068 {
5069 if (strcmp(procname, glExtensions[ext].name) == 0)
5070 {
5071 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5072 }
5073 }
5074
5075 return NULL;
5076}
5077
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005078}