blob: c3c7a2f5afb9c0e6686fbe833ac38ec82da24474 [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 {
509 if (size < 0)
510 {
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
542 GLenum err = buffer->bufferSubData(data, size, offset);
543
544 if (err != GL_NO_ERROR)
545 {
546 return error(err);
547 }
548 }
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.com428d1582010-05-04 03:35:25 +0000672 context->setColorMask(red != GL_FALSE, green != GL_FALSE, blue != GL_FALSE, alpha != GL_FALSE);
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 {
851 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
852
853 if (target == GL_TEXTURE_2D)
854 {
855 gl::Texture2D *texture = context->getTexture2D();
856
857 if (!texture)
858 {
859 return error(GL_INVALID_OPERATION);
860 }
861
862 texture->copyImage(level, internalformat, x, y, width, height, source);
863 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000864 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000865 {
866 gl::TextureCubeMap *texture = context->getTextureCubeMap();
867
868 if (!texture)
869 {
870 return error(GL_INVALID_OPERATION);
871 }
872
873 texture->copyImage(target, level, internalformat, x, y, width, height, source);
874 }
875 else
876 {
877 UNREACHABLE();
878 }
879 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000880 }
881 catch(std::bad_alloc&)
882 {
883 return error(GL_OUT_OF_MEMORY);
884 }
885}
886
887void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
888{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000889 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
890 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000891 target, level, xoffset, yoffset, x, y, width, height);
892
893 try
894 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000895 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000896 {
897 return error(GL_INVALID_ENUM);
898 }
899
900 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000901 {
902 return error(GL_INVALID_VALUE);
903 }
904
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000905 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
906 {
907 return error(GL_INVALID_VALUE);
908 }
909
910 if (width == 0 || height == 0)
911 {
912 return;
913 }
914
915 gl::Context *context = gl::getContext();
916
917 if (context)
918 {
919 gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
920
921 if (target == GL_TEXTURE_2D)
922 {
923 gl::Texture2D *texture = context->getTexture2D();
924
925 if (!texture)
926 {
927 return error(GL_INVALID_OPERATION);
928 }
929
930 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
931 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000932 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000933 {
934 gl::TextureCubeMap *texture = context->getTextureCubeMap();
935
936 if (!texture)
937 {
938 return error(GL_INVALID_OPERATION);
939 }
940
941 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
942 }
943 else
944 {
945 UNREACHABLE();
946 }
947 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000948 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000949
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000950 catch(std::bad_alloc&)
951 {
952 return error(GL_OUT_OF_MEMORY);
953 }
954}
955
956GLuint __stdcall glCreateProgram(void)
957{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000958 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000959
960 try
961 {
962 gl::Context *context = gl::getContext();
963
964 if (context)
965 {
966 return context->createProgram();
967 }
968 }
969 catch(std::bad_alloc&)
970 {
971 return error(GL_OUT_OF_MEMORY, 0);
972 }
973
974 return 0;
975}
976
977GLuint __stdcall glCreateShader(GLenum type)
978{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000979 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000980
981 try
982 {
983 gl::Context *context = gl::getContext();
984
985 if (context)
986 {
987 switch (type)
988 {
989 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000990 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000991 return context->createShader(type);
992 default:
993 return error(GL_INVALID_ENUM, 0);
994 }
995 }
996 }
997 catch(std::bad_alloc&)
998 {
999 return error(GL_OUT_OF_MEMORY, 0);
1000 }
1001
1002 return 0;
1003}
1004
1005void __stdcall glCullFace(GLenum mode)
1006{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001007 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001008
1009 try
1010 {
1011 switch (mode)
1012 {
1013 case GL_FRONT:
1014 case GL_BACK:
1015 case GL_FRONT_AND_BACK:
1016 {
1017 gl::Context *context = gl::getContext();
1018
1019 if (context)
1020 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001021 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001022 }
1023 }
1024 break;
1025 default:
1026 return error(GL_INVALID_ENUM);
1027 }
1028 }
1029 catch(std::bad_alloc&)
1030 {
1031 return error(GL_OUT_OF_MEMORY);
1032 }
1033}
1034
1035void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1036{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001037 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001038
1039 try
1040 {
1041 if (n < 0)
1042 {
1043 return error(GL_INVALID_VALUE);
1044 }
1045
1046 gl::Context *context = gl::getContext();
1047
1048 if (context)
1049 {
1050 for (int i = 0; i < n; i++)
1051 {
1052 context->deleteBuffer(buffers[i]);
1053 }
1054 }
1055 }
1056 catch(std::bad_alloc&)
1057 {
1058 return error(GL_OUT_OF_MEMORY);
1059 }
1060}
1061
1062void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1063{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001064 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001065
1066 try
1067 {
1068 if (n < 0)
1069 {
1070 return error(GL_INVALID_VALUE);
1071 }
1072
1073 gl::Context *context = gl::getContext();
1074
1075 if (context)
1076 {
1077 for (int i = 0; i < n; i++)
1078 {
1079 if (framebuffers[i] != 0)
1080 {
1081 context->deleteFramebuffer(framebuffers[i]);
1082 }
1083 }
1084 }
1085 }
1086 catch(std::bad_alloc&)
1087 {
1088 return error(GL_OUT_OF_MEMORY);
1089 }
1090}
1091
1092void __stdcall glDeleteProgram(GLuint program)
1093{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001094 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001095
1096 try
1097 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001098 if (program == 0)
1099 {
1100 return;
1101 }
1102
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001103 gl::Context *context = gl::getContext();
1104
1105 if (context)
1106 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001107 if (!context->getProgram(program))
1108 {
1109 if(context->getShader(program))
1110 {
1111 return error(GL_INVALID_OPERATION);
1112 }
1113 else
1114 {
1115 return error(GL_INVALID_VALUE);
1116 }
1117 }
1118
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001119 context->deleteProgram(program);
1120 }
1121 }
1122 catch(std::bad_alloc&)
1123 {
1124 return error(GL_OUT_OF_MEMORY);
1125 }
1126}
1127
1128void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1129{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001130 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001131
1132 try
1133 {
1134 if (n < 0)
1135 {
1136 return error(GL_INVALID_VALUE);
1137 }
1138
1139 gl::Context *context = gl::getContext();
1140
1141 if (context)
1142 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001143 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001144 {
1145 context->deleteRenderbuffer(renderbuffers[i]);
1146 }
1147 }
1148 }
1149 catch(std::bad_alloc&)
1150 {
1151 return error(GL_OUT_OF_MEMORY);
1152 }
1153}
1154
1155void __stdcall glDeleteShader(GLuint shader)
1156{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001157 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001158
1159 try
1160 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001161 if (shader == 0)
1162 {
1163 return;
1164 }
1165
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001166 gl::Context *context = gl::getContext();
1167
1168 if (context)
1169 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001170 if (!context->getShader(shader))
1171 {
1172 if(context->getProgram(shader))
1173 {
1174 return error(GL_INVALID_OPERATION);
1175 }
1176 else
1177 {
1178 return error(GL_INVALID_VALUE);
1179 }
1180 }
1181
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001182 context->deleteShader(shader);
1183 }
1184 }
1185 catch(std::bad_alloc&)
1186 {
1187 return error(GL_OUT_OF_MEMORY);
1188 }
1189}
1190
1191void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1192{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001193 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001194
1195 try
1196 {
1197 if (n < 0)
1198 {
1199 return error(GL_INVALID_VALUE);
1200 }
1201
1202 gl::Context *context = gl::getContext();
1203
1204 if (context)
1205 {
1206 for (int i = 0; i < n; i++)
1207 {
1208 if (textures[i] != 0)
1209 {
1210 context->deleteTexture(textures[i]);
1211 }
1212 }
1213 }
1214 }
1215 catch(std::bad_alloc&)
1216 {
1217 return error(GL_OUT_OF_MEMORY);
1218 }
1219}
1220
1221void __stdcall glDepthFunc(GLenum func)
1222{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001223 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001224
1225 try
1226 {
1227 switch (func)
1228 {
1229 case GL_NEVER:
1230 case GL_ALWAYS:
1231 case GL_LESS:
1232 case GL_LEQUAL:
1233 case GL_EQUAL:
1234 case GL_GREATER:
1235 case GL_GEQUAL:
1236 case GL_NOTEQUAL:
1237 break;
1238 default:
1239 return error(GL_INVALID_ENUM);
1240 }
1241
1242 gl::Context *context = gl::getContext();
1243
1244 if (context)
1245 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001246 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001247 }
1248 }
1249 catch(std::bad_alloc&)
1250 {
1251 return error(GL_OUT_OF_MEMORY);
1252 }
1253}
1254
1255void __stdcall glDepthMask(GLboolean flag)
1256{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001257 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001258
1259 try
1260 {
1261 gl::Context *context = gl::getContext();
1262
1263 if (context)
1264 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001265 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001266 }
1267 }
1268 catch(std::bad_alloc&)
1269 {
1270 return error(GL_OUT_OF_MEMORY);
1271 }
1272}
1273
1274void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1275{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001276 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001277
1278 try
1279 {
1280 gl::Context *context = gl::getContext();
1281
1282 if (context)
1283 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001284 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001285 }
1286 }
1287 catch(std::bad_alloc&)
1288 {
1289 return error(GL_OUT_OF_MEMORY);
1290 }
1291}
1292
1293void __stdcall glDetachShader(GLuint program, GLuint shader)
1294{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001295 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001296
1297 try
1298 {
1299 gl::Context *context = gl::getContext();
1300
1301 if (context)
1302 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001303
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001304 gl::Program *programObject = context->getProgram(program);
1305 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001306
1307 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001308 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001309 gl::Shader *shaderByProgramHandle;
1310 shaderByProgramHandle = context->getShader(program);
1311 if (!shaderByProgramHandle)
1312 {
1313 return error(GL_INVALID_VALUE);
1314 }
1315 else
1316 {
1317 return error(GL_INVALID_OPERATION);
1318 }
1319 }
1320
1321 if (!shaderObject)
1322 {
1323 gl::Program *programByShaderHandle = context->getProgram(shader);
1324 if (!programByShaderHandle)
1325 {
1326 return error(GL_INVALID_VALUE);
1327 }
1328 else
1329 {
1330 return error(GL_INVALID_OPERATION);
1331 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001332 }
1333
1334 if (!programObject->detachShader(shaderObject))
1335 {
1336 return error(GL_INVALID_OPERATION);
1337 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001338 }
1339 }
1340 catch(std::bad_alloc&)
1341 {
1342 return error(GL_OUT_OF_MEMORY);
1343 }
1344}
1345
1346void __stdcall glDisable(GLenum cap)
1347{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001348 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001349
1350 try
1351 {
1352 gl::Context *context = gl::getContext();
1353
1354 if (context)
1355 {
1356 switch (cap)
1357 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001358 case GL_CULL_FACE: context->setCullFace(false); break;
1359 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1360 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1361 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1362 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1363 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1364 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1365 case GL_BLEND: context->setBlend(false); break;
1366 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001367 default:
1368 return error(GL_INVALID_ENUM);
1369 }
1370 }
1371 }
1372 catch(std::bad_alloc&)
1373 {
1374 return error(GL_OUT_OF_MEMORY);
1375 }
1376}
1377
1378void __stdcall glDisableVertexAttribArray(GLuint index)
1379{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001380 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001381
1382 try
1383 {
1384 if (index >= gl::MAX_VERTEX_ATTRIBS)
1385 {
1386 return error(GL_INVALID_VALUE);
1387 }
1388
1389 gl::Context *context = gl::getContext();
1390
1391 if (context)
1392 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001393 context->setVertexAttribEnabled(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001394 }
1395 }
1396 catch(std::bad_alloc&)
1397 {
1398 return error(GL_OUT_OF_MEMORY);
1399 }
1400}
1401
1402void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1403{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001404 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001405
1406 try
1407 {
1408 if (count < 0 || first < 0)
1409 {
1410 return error(GL_INVALID_VALUE);
1411 }
1412
1413 gl::Context *context = gl::getContext();
1414
1415 if (context)
1416 {
1417 context->drawArrays(mode, first, count);
1418 }
1419 }
1420 catch(std::bad_alloc&)
1421 {
1422 return error(GL_OUT_OF_MEMORY);
1423 }
1424}
1425
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001426void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001427{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001428 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 +00001429 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001430
1431 try
1432 {
1433 if (count < 0)
1434 {
1435 return error(GL_INVALID_VALUE);
1436 }
1437
1438 switch (type)
1439 {
1440 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001441 case GL_UNSIGNED_SHORT:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00001442 case GL_UNSIGNED_INT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001443 break;
1444 default:
1445 return error(GL_INVALID_ENUM);
1446 }
1447
1448 gl::Context *context = gl::getContext();
1449
1450 if (context)
1451 {
1452 context->drawElements(mode, count, type, indices);
1453 }
1454 }
1455 catch(std::bad_alloc&)
1456 {
1457 return error(GL_OUT_OF_MEMORY);
1458 }
1459}
1460
1461void __stdcall glEnable(GLenum cap)
1462{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001463 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001464
1465 try
1466 {
1467 gl::Context *context = gl::getContext();
1468
1469 if (context)
1470 {
1471 switch (cap)
1472 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001473 case GL_CULL_FACE: context->setCullFace(true); break;
1474 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1475 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1476 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1477 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1478 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1479 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1480 case GL_BLEND: context->setBlend(true); break;
1481 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001482 default:
1483 return error(GL_INVALID_ENUM);
1484 }
1485 }
1486 }
1487 catch(std::bad_alloc&)
1488 {
1489 return error(GL_OUT_OF_MEMORY);
1490 }
1491}
1492
1493void __stdcall glEnableVertexAttribArray(GLuint index)
1494{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001495 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001496
1497 try
1498 {
1499 if (index >= gl::MAX_VERTEX_ATTRIBS)
1500 {
1501 return error(GL_INVALID_VALUE);
1502 }
1503
1504 gl::Context *context = gl::getContext();
1505
1506 if (context)
1507 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001508 context->setVertexAttribEnabled(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001509 }
1510 }
1511 catch(std::bad_alloc&)
1512 {
1513 return error(GL_OUT_OF_MEMORY);
1514 }
1515}
1516
1517void __stdcall glFinish(void)
1518{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001519 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001520
1521 try
1522 {
1523 gl::Context *context = gl::getContext();
1524
1525 if (context)
1526 {
1527 context->finish();
1528 }
1529 }
1530 catch(std::bad_alloc&)
1531 {
1532 return error(GL_OUT_OF_MEMORY);
1533 }
1534}
1535
1536void __stdcall glFlush(void)
1537{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001538 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001539
1540 try
1541 {
1542 gl::Context *context = gl::getContext();
1543
1544 if (context)
1545 {
1546 context->flush();
1547 }
1548 }
1549 catch(std::bad_alloc&)
1550 {
1551 return error(GL_OUT_OF_MEMORY);
1552 }
1553}
1554
1555void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1556{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001557 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1558 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001559
1560 try
1561 {
1562 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1563 {
1564 return error(GL_INVALID_ENUM);
1565 }
1566
1567 gl::Context *context = gl::getContext();
1568
1569 if (context)
1570 {
1571 gl::Framebuffer *framebuffer = context->getFramebuffer();
1572
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001573 if (context->getFramebufferHandle() == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001574 {
1575 return error(GL_INVALID_OPERATION);
1576 }
1577
1578 switch (attachment)
1579 {
1580 case GL_COLOR_ATTACHMENT0:
1581 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1582 break;
1583 case GL_DEPTH_ATTACHMENT:
1584 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1585 break;
1586 case GL_STENCIL_ATTACHMENT:
1587 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1588 break;
1589 default:
1590 return error(GL_INVALID_ENUM);
1591 }
1592 }
1593 }
1594 catch(std::bad_alloc&)
1595 {
1596 return error(GL_OUT_OF_MEMORY);
1597 }
1598}
1599
1600void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1601{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001602 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1603 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001604
1605 try
1606 {
1607 if (target != GL_FRAMEBUFFER)
1608 {
1609 return error(GL_INVALID_ENUM);
1610 }
1611
1612 switch (attachment)
1613 {
1614 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001615 case GL_DEPTH_ATTACHMENT:
1616 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001617 break;
1618 default:
1619 return error(GL_INVALID_ENUM);
1620 }
1621
1622 gl::Context *context = gl::getContext();
1623
1624 if (context)
1625 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001626 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001627 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001628 textarget = GL_NONE;
1629 }
1630 else
1631 {
1632 gl::Texture *tex = context->getTexture(texture);
1633
1634 if (tex == NULL)
1635 {
1636 return error(GL_INVALID_OPERATION);
1637 }
1638
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001639 switch (textarget)
1640 {
1641 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001642 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001643 {
1644 return error(GL_INVALID_OPERATION);
1645 }
1646 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001647
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001648 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001649 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001650 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001651 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001652 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001653 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001654 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1655 {
1656 return error(GL_INVALID_OPERATION);
1657 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001658 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001659
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001660 default:
1661 return error(GL_INVALID_ENUM);
1662 }
1663
1664 if (level != 0)
1665 {
1666 return error(GL_INVALID_VALUE);
1667 }
1668 }
1669
1670 gl::Framebuffer *framebuffer = context->getFramebuffer();
1671
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001672 if (context->getFramebufferHandle() == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001673 {
1674 return error(GL_INVALID_OPERATION);
1675 }
1676
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001677 switch (attachment)
1678 {
1679 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
1680 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
1681 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
1682 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001683 }
1684 }
1685 catch(std::bad_alloc&)
1686 {
1687 return error(GL_OUT_OF_MEMORY);
1688 }
1689}
1690
1691void __stdcall glFrontFace(GLenum mode)
1692{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001693 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001694
1695 try
1696 {
1697 switch (mode)
1698 {
1699 case GL_CW:
1700 case GL_CCW:
1701 {
1702 gl::Context *context = gl::getContext();
1703
1704 if (context)
1705 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001706 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001707 }
1708 }
1709 break;
1710 default:
1711 return error(GL_INVALID_ENUM);
1712 }
1713 }
1714 catch(std::bad_alloc&)
1715 {
1716 return error(GL_OUT_OF_MEMORY);
1717 }
1718}
1719
1720void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1721{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001722 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001723
1724 try
1725 {
1726 if (n < 0)
1727 {
1728 return error(GL_INVALID_VALUE);
1729 }
1730
1731 gl::Context *context = gl::getContext();
1732
1733 if (context)
1734 {
1735 for (int i = 0; i < n; i++)
1736 {
1737 buffers[i] = context->createBuffer();
1738 }
1739 }
1740 }
1741 catch(std::bad_alloc&)
1742 {
1743 return error(GL_OUT_OF_MEMORY);
1744 }
1745}
1746
1747void __stdcall glGenerateMipmap(GLenum target)
1748{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001749 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001750
1751 try
1752 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00001753 gl::Context *context = gl::getContext();
1754
1755 if (context)
1756 {
1757 gl::Texture *texture;
1758
1759 switch (target)
1760 {
1761 case GL_TEXTURE_2D:
1762 texture = context->getTexture2D();
1763 break;
1764
1765 case GL_TEXTURE_CUBE_MAP:
1766 texture = context->getTextureCubeMap();
1767 break;
1768
1769 default:
1770 return error(GL_INVALID_ENUM);
1771 }
1772
1773 texture->generateMipmaps();
1774 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001775 }
1776 catch(std::bad_alloc&)
1777 {
1778 return error(GL_OUT_OF_MEMORY);
1779 }
1780}
1781
1782void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1783{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001784 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001785
1786 try
1787 {
1788 if (n < 0)
1789 {
1790 return error(GL_INVALID_VALUE);
1791 }
1792
1793 gl::Context *context = gl::getContext();
1794
1795 if (context)
1796 {
1797 for (int i = 0; i < n; i++)
1798 {
1799 framebuffers[i] = context->createFramebuffer();
1800 }
1801 }
1802 }
1803 catch(std::bad_alloc&)
1804 {
1805 return error(GL_OUT_OF_MEMORY);
1806 }
1807}
1808
1809void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1810{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001811 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001812
1813 try
1814 {
1815 if (n < 0)
1816 {
1817 return error(GL_INVALID_VALUE);
1818 }
1819
1820 gl::Context *context = gl::getContext();
1821
1822 if (context)
1823 {
1824 for (int i = 0; i < n; i++)
1825 {
1826 renderbuffers[i] = context->createRenderbuffer();
1827 }
1828 }
1829 }
1830 catch(std::bad_alloc&)
1831 {
1832 return error(GL_OUT_OF_MEMORY);
1833 }
1834}
1835
1836void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1837{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001838 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001839
1840 try
1841 {
1842 if (n < 0)
1843 {
1844 return error(GL_INVALID_VALUE);
1845 }
1846
1847 gl::Context *context = gl::getContext();
1848
1849 if (context)
1850 {
1851 for (int i = 0; i < n; i++)
1852 {
1853 textures[i] = context->createTexture();
1854 }
1855 }
1856 }
1857 catch(std::bad_alloc&)
1858 {
1859 return error(GL_OUT_OF_MEMORY);
1860 }
1861}
1862
daniel@transgaming.com85423182010-04-22 13:35:27 +00001863void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001864{
daniel@transgaming.com85423182010-04-22 13:35:27 +00001865 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
1866 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001867 program, index, bufsize, length, size, type, name);
1868
1869 try
1870 {
1871 if (bufsize < 0)
1872 {
1873 return error(GL_INVALID_VALUE);
1874 }
1875
daniel@transgaming.com85423182010-04-22 13:35:27 +00001876 gl::Context *context = gl::getContext();
1877
1878 if (context)
1879 {
1880 gl::Program *programObject = context->getProgram(program);
1881
1882 if (!programObject)
1883 {
1884 if (context->getShader(program))
1885 {
1886 return error(GL_INVALID_OPERATION);
1887 }
1888 else
1889 {
1890 return error(GL_INVALID_VALUE);
1891 }
1892 }
1893
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001894 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00001895 {
1896 return error(GL_INVALID_VALUE);
1897 }
1898
1899 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
1900 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001901 }
1902 catch(std::bad_alloc&)
1903 {
1904 return error(GL_OUT_OF_MEMORY);
1905 }
1906}
1907
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001908void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001909{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001910 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001911 "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 +00001912 program, index, bufsize, length, size, type, name);
1913
1914 try
1915 {
1916 if (bufsize < 0)
1917 {
1918 return error(GL_INVALID_VALUE);
1919 }
1920
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001921 gl::Context *context = gl::getContext();
1922
1923 if (context)
1924 {
1925 gl::Program *programObject = context->getProgram(program);
1926
1927 if (!programObject)
1928 {
1929 if (context->getShader(program))
1930 {
1931 return error(GL_INVALID_OPERATION);
1932 }
1933 else
1934 {
1935 return error(GL_INVALID_VALUE);
1936 }
1937 }
1938
1939 if (index >= (GLuint)programObject->getActiveUniformCount())
1940 {
1941 return error(GL_INVALID_VALUE);
1942 }
1943
1944 programObject->getActiveUniform(index, bufsize, length, size, type, name);
1945 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001946 }
1947 catch(std::bad_alloc&)
1948 {
1949 return error(GL_OUT_OF_MEMORY);
1950 }
1951}
1952
1953void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1954{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001955 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1956 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001957
1958 try
1959 {
1960 if (maxcount < 0)
1961 {
1962 return error(GL_INVALID_VALUE);
1963 }
1964
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001965 gl::Context *context = gl::getContext();
1966
1967 if (context)
1968 {
1969 gl::Program *programObject = context->getProgram(program);
1970
1971 if (!programObject)
1972 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001973 if (context->getShader(program))
1974 {
1975 return error(GL_INVALID_OPERATION);
1976 }
1977 else
1978 {
1979 return error(GL_INVALID_VALUE);
1980 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001981 }
1982
1983 return programObject->getAttachedShaders(maxcount, count, shaders);
1984 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001985 }
1986 catch(std::bad_alloc&)
1987 {
1988 return error(GL_OUT_OF_MEMORY);
1989 }
1990}
1991
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001992int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001993{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001994 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001995
1996 try
1997 {
1998 gl::Context *context = gl::getContext();
1999
2000 if (context)
2001 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002002
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002003 gl::Program *programObject = context->getProgram(program);
2004
2005 if (!programObject)
2006 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002007 if (context->getShader(program))
2008 {
2009 return error(GL_INVALID_OPERATION, -1);
2010 }
2011 else
2012 {
2013 return error(GL_INVALID_VALUE, -1);
2014 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002015 }
2016
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002017 if (!programObject->isLinked())
2018 {
2019 return error(GL_INVALID_OPERATION, -1);
2020 }
2021
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002022 return programObject->getAttributeLocation(name);
2023 }
2024 }
2025 catch(std::bad_alloc&)
2026 {
2027 return error(GL_OUT_OF_MEMORY, -1);
2028 }
2029
2030 return -1;
2031}
2032
2033void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2034{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002035 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002036
2037 try
2038 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002039 gl::Context *context = gl::getContext();
2040
2041 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002042 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002043 if (!(context->getBooleanv(pname, params)))
2044 {
2045 GLenum nativeType;
2046 unsigned int numParams = 0;
2047 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2048 return error(GL_INVALID_ENUM);
2049
2050 if (numParams == 0)
2051 return; // it is known that the pname is valid, but there are no parameters to return
2052
2053 if (nativeType == GL_FLOAT)
2054 {
2055 GLfloat *floatParams = NULL;
2056 floatParams = new GLfloat[numParams];
2057
2058 context->getFloatv(pname, floatParams);
2059
2060 for (unsigned int i = 0; i < numParams; ++i)
2061 {
2062 if (floatParams[i] == 0.0f)
2063 params[i] = GL_FALSE;
2064 else
2065 params[i] = GL_TRUE;
2066 }
2067
2068 delete [] floatParams;
2069 }
2070 else if (nativeType == GL_INT)
2071 {
2072 GLint *intParams = NULL;
2073 intParams = new GLint[numParams];
2074
2075 context->getIntegerv(pname, intParams);
2076
2077 for (unsigned int i = 0; i < numParams; ++i)
2078 {
2079 if (intParams[i] == 0)
2080 params[i] = GL_FALSE;
2081 else
2082 params[i] = GL_TRUE;
2083 }
2084
2085 delete [] intParams;
2086 }
2087 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002088 }
2089 }
2090 catch(std::bad_alloc&)
2091 {
2092 return error(GL_OUT_OF_MEMORY);
2093 }
2094}
2095
2096void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2097{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002098 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 +00002099
2100 try
2101 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002102 gl::Context *context = gl::getContext();
2103
2104 if (context)
2105 {
2106 gl::Buffer *buffer;
2107
2108 switch (target)
2109 {
2110 case GL_ARRAY_BUFFER:
2111 buffer = context->getArrayBuffer();
2112 break;
2113 case GL_ELEMENT_ARRAY_BUFFER:
2114 buffer = context->getElementArrayBuffer();
2115 break;
2116 default: return error(GL_INVALID_ENUM);
2117 }
2118
2119 if (!buffer)
2120 {
2121 // A null buffer means that "0" is bound to the requested buffer target
2122 return error(GL_INVALID_OPERATION);
2123 }
2124
2125 switch (pname)
2126 {
2127 case GL_BUFFER_USAGE:
2128 *params = buffer->usage();
2129 break;
2130 case GL_BUFFER_SIZE:
2131 *params = buffer->size();
2132 break;
2133 default: return error(GL_INVALID_ENUM);
2134 }
2135 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002136 }
2137 catch(std::bad_alloc&)
2138 {
2139 return error(GL_OUT_OF_MEMORY);
2140 }
2141}
2142
2143GLenum __stdcall glGetError(void)
2144{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002145 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002146
2147 gl::Context *context = gl::getContext();
2148
2149 if (context)
2150 {
2151 return context->getError();
2152 }
2153
2154 return GL_NO_ERROR;
2155}
2156
2157void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2158{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002159 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002160
2161 try
2162 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002163 gl::Context *context = gl::getContext();
2164
2165 if (context)
2166 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002167 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002168 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002169 GLenum nativeType;
2170 unsigned int numParams = 0;
2171 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2172 return error(GL_INVALID_ENUM);
2173
2174 if (numParams == 0)
2175 return; // it is known that the pname is valid, but that there are no parameters to return.
2176
2177 if (nativeType == GL_BOOL)
2178 {
2179 GLboolean *boolParams = NULL;
2180 boolParams = new GLboolean[numParams];
2181
2182 context->getBooleanv(pname, boolParams);
2183
2184 for (unsigned int i = 0; i < numParams; ++i)
2185 {
2186 if (boolParams[i] == GL_FALSE)
2187 params[i] = 0.0f;
2188 else
2189 params[i] = 1.0f;
2190 }
2191
2192 delete [] boolParams;
2193 }
2194 else if (nativeType == GL_INT)
2195 {
2196 GLint *intParams = NULL;
2197 intParams = new GLint[numParams];
2198
2199 context->getIntegerv(pname, intParams);
2200
2201 for (unsigned int i = 0; i < numParams; ++i)
2202 {
2203 params[i] = (GLfloat)intParams[i];
2204 }
2205
2206 delete [] intParams;
2207 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002208 }
2209 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002210 }
2211 catch(std::bad_alloc&)
2212 {
2213 return error(GL_OUT_OF_MEMORY);
2214 }
2215}
2216
2217void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2218{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002219 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2220 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002221
2222 try
2223 {
2224 gl::Context *context = gl::getContext();
2225
2226 if (context)
2227 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002228 if (context->getFramebufferHandle() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002229 {
2230 return error(GL_INVALID_OPERATION);
2231 }
2232
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002233 if (target != GL_FRAMEBUFFER)
2234 {
2235 return error(GL_INVALID_ENUM);
2236 }
2237
2238 GLenum attachmentType;
2239 GLuint attachmentHandle;
2240 switch (attachment)
2241 {
2242 case GL_COLOR_ATTACHMENT0:
2243 attachmentType = context->getFramebuffer()->getColorbufferType();
2244 attachmentHandle = context->getFramebuffer()->getColorbufferHandle();
2245 break;
2246 case GL_DEPTH_ATTACHMENT:
2247 attachmentType = context->getFramebuffer()->getDepthbufferType();
2248 attachmentHandle = context->getFramebuffer()->getDepthbufferHandle();
2249 break;
2250 case GL_STENCIL_ATTACHMENT:
2251 attachmentType = context->getFramebuffer()->getStencilbufferType();
2252 attachmentHandle = context->getFramebuffer()->getStencilbufferHandle();
2253 break;
2254 default: return error(GL_INVALID_ENUM);
2255 }
2256
2257 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002258 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002259 {
2260 attachmentObjectType = attachmentType;
2261 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002262 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002263 {
2264 attachmentObjectType = GL_TEXTURE;
2265 }
2266 else UNREACHABLE();
2267
2268 switch (pname)
2269 {
2270 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2271 *params = attachmentObjectType;
2272 break;
2273 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2274 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2275 {
2276 *params = attachmentHandle;
2277 }
2278 else
2279 {
2280 return error(GL_INVALID_ENUM);
2281 }
2282 break;
2283 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2284 if (attachmentObjectType == GL_TEXTURE)
2285 {
2286 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2287 }
2288 else
2289 {
2290 return error(GL_INVALID_ENUM);
2291 }
2292 break;
2293 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2294 if (attachmentObjectType == GL_TEXTURE)
2295 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002296 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002297 {
2298 *params = attachmentType;
2299 }
2300 else
2301 {
2302 *params = 0;
2303 }
2304 }
2305 else
2306 {
2307 return error(GL_INVALID_ENUM);
2308 }
2309 break;
2310 default:
2311 return error(GL_INVALID_ENUM);
2312 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002313 }
2314 }
2315 catch(std::bad_alloc&)
2316 {
2317 return error(GL_OUT_OF_MEMORY);
2318 }
2319}
2320
2321void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2322{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002323 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002324
2325 try
2326 {
2327 gl::Context *context = gl::getContext();
2328
2329 if (context)
2330 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002331 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002332 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002333 GLenum nativeType;
2334 unsigned int numParams = 0;
2335 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2336 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002337
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002338 if (numParams == 0)
2339 return; // it is known that pname is valid, but there are no parameters to return
2340
2341 if (nativeType == GL_BOOL)
2342 {
2343 GLboolean *boolParams = NULL;
2344 boolParams = new GLboolean[numParams];
2345
2346 context->getBooleanv(pname, boolParams);
2347
2348 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002349 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002350 if (boolParams[i] == GL_FALSE)
2351 params[i] = 0;
2352 else
2353 params[i] = 1;
2354 }
2355
2356 delete [] boolParams;
2357 }
2358 else if (nativeType == GL_FLOAT)
2359 {
2360 GLfloat *floatParams = NULL;
2361 floatParams = new GLfloat[numParams];
2362
2363 context->getFloatv(pname, floatParams);
2364
2365 for (unsigned int i = 0; i < numParams; ++i)
2366 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002367 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 +00002368 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002369 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002370 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002371 else
2372 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 +00002373 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002374
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002375 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002376 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002377 }
2378 }
2379 }
2380 catch(std::bad_alloc&)
2381 {
2382 return error(GL_OUT_OF_MEMORY);
2383 }
2384}
2385
2386void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2387{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002388 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002389
2390 try
2391 {
2392 gl::Context *context = gl::getContext();
2393
2394 if (context)
2395 {
2396 gl::Program *programObject = context->getProgram(program);
2397
2398 if (!programObject)
2399 {
2400 return error(GL_INVALID_VALUE);
2401 }
2402
2403 switch (pname)
2404 {
2405 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002406 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002407 return;
2408 case GL_LINK_STATUS:
2409 *params = programObject->isLinked();
2410 return;
2411 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002412 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002413 return;
2414 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002415 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002416 return;
2417 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002418 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002419 return;
2420 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002421 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002422 return;
2423 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002424 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002425 return;
2426 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002427 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002428 return;
2429 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002430 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002431 return;
2432 default:
2433 return error(GL_INVALID_ENUM);
2434 }
2435 }
2436 }
2437 catch(std::bad_alloc&)
2438 {
2439 return error(GL_OUT_OF_MEMORY);
2440 }
2441}
2442
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002443void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002444{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002445 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 +00002446 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002447
2448 try
2449 {
2450 if (bufsize < 0)
2451 {
2452 return error(GL_INVALID_VALUE);
2453 }
2454
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002455 gl::Context *context = gl::getContext();
2456
2457 if (context)
2458 {
2459 gl::Program *programObject = context->getProgram(program);
2460
2461 if (!programObject)
2462 {
2463 return error(GL_INVALID_VALUE);
2464 }
2465
2466 programObject->getInfoLog(bufsize, length, infolog);
2467 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002468 }
2469 catch(std::bad_alloc&)
2470 {
2471 return error(GL_OUT_OF_MEMORY);
2472 }
2473}
2474
2475void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2476{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002477 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 +00002478
2479 try
2480 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002481 gl::Context *context = gl::getContext();
2482
2483 if (context)
2484 {
2485 if (target != GL_RENDERBUFFER)
2486 {
2487 return error(GL_INVALID_ENUM);
2488 }
2489
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002490 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002491 {
2492 return error(GL_INVALID_OPERATION);
2493 }
2494
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002495 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002496
2497 switch (pname)
2498 {
2499 case GL_RENDERBUFFER_WIDTH:
2500 *params = renderbuffer->getWidth();
2501 break;
2502 case GL_RENDERBUFFER_HEIGHT:
2503 *params = renderbuffer->getHeight();
2504 break;
2505 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2506 *params = renderbuffer->getFormat();
2507 break;
2508 case GL_RENDERBUFFER_RED_SIZE:
2509 if (renderbuffer->isColorbuffer())
2510 {
2511 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
2512 }
2513 else
2514 {
2515 *params = 0;
2516 }
2517 break;
2518 case GL_RENDERBUFFER_GREEN_SIZE:
2519 if (renderbuffer->isColorbuffer())
2520 {
2521 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
2522 }
2523 else
2524 {
2525 *params = 0;
2526 }
2527 break;
2528 case GL_RENDERBUFFER_BLUE_SIZE:
2529 if (renderbuffer->isColorbuffer())
2530 {
2531 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
2532 }
2533 else
2534 {
2535 *params = 0;
2536 }
2537 break;
2538 case GL_RENDERBUFFER_ALPHA_SIZE:
2539 if (renderbuffer->isColorbuffer())
2540 {
2541 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
2542 }
2543 else
2544 {
2545 *params = 0;
2546 }
2547 break;
2548 case GL_RENDERBUFFER_DEPTH_SIZE:
2549 if (renderbuffer->isDepthbuffer())
2550 {
2551 *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
2552 }
2553 else
2554 {
2555 *params = 0;
2556 }
2557 break;
2558 case GL_RENDERBUFFER_STENCIL_SIZE:
2559 if (renderbuffer->isStencilbuffer())
2560 {
2561 *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
2562 }
2563 else
2564 {
2565 *params = 0;
2566 }
2567 break;
2568 default:
2569 return error(GL_INVALID_ENUM);
2570 }
2571 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002572 }
2573 catch(std::bad_alloc&)
2574 {
2575 return error(GL_OUT_OF_MEMORY);
2576 }
2577}
2578
2579void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2580{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002581 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002582
2583 try
2584 {
2585 gl::Context *context = gl::getContext();
2586
2587 if (context)
2588 {
2589 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002590
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002591 if (!shaderObject)
2592 {
2593 return error(GL_INVALID_VALUE);
2594 }
2595
2596 switch (pname)
2597 {
2598 case GL_SHADER_TYPE:
2599 *params = shaderObject->getType();
2600 return;
2601 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002602 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002603 return;
2604 case GL_COMPILE_STATUS:
2605 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2606 return;
2607 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002608 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002609 return;
2610 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002611 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002612 return;
2613 default:
2614 return error(GL_INVALID_ENUM);
2615 }
2616 }
2617 }
2618 catch(std::bad_alloc&)
2619 {
2620 return error(GL_OUT_OF_MEMORY);
2621 }
2622}
2623
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002624void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002625{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002626 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 +00002627 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002628
2629 try
2630 {
2631 if (bufsize < 0)
2632 {
2633 return error(GL_INVALID_VALUE);
2634 }
2635
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002636 gl::Context *context = gl::getContext();
2637
2638 if (context)
2639 {
2640 gl::Shader *shaderObject = context->getShader(shader);
2641
2642 if (!shaderObject)
2643 {
2644 return error(GL_INVALID_VALUE);
2645 }
2646
2647 shaderObject->getInfoLog(bufsize, length, infolog);
2648 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002649 }
2650 catch(std::bad_alloc&)
2651 {
2652 return error(GL_OUT_OF_MEMORY);
2653 }
2654}
2655
2656void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2657{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002658 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2659 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002660
2661 try
2662 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002663 switch (shadertype)
2664 {
2665 case GL_VERTEX_SHADER:
2666 case GL_FRAGMENT_SHADER:
2667 break;
2668 default:
2669 return error(GL_INVALID_ENUM);
2670 }
2671
2672 switch (precisiontype)
2673 {
2674 case GL_LOW_FLOAT:
2675 case GL_MEDIUM_FLOAT:
2676 case GL_HIGH_FLOAT:
2677 // Assume IEEE 754 precision
2678 range[0] = 127;
2679 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002680 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002681 break;
2682 case GL_LOW_INT:
2683 case GL_MEDIUM_INT:
2684 case GL_HIGH_INT:
2685 // Some (most) hardware only supports single-precision floating-point numbers,
2686 // which can accurately represent integers up to +/-16777216
2687 range[0] = 24;
2688 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002689 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002690 break;
2691 default:
2692 return error(GL_INVALID_ENUM);
2693 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002694 }
2695 catch(std::bad_alloc&)
2696 {
2697 return error(GL_OUT_OF_MEMORY);
2698 }
2699}
2700
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002701void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002702{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002703 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 +00002704 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002705
2706 try
2707 {
2708 if (bufsize < 0)
2709 {
2710 return error(GL_INVALID_VALUE);
2711 }
2712
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002713 gl::Context *context = gl::getContext();
2714
2715 if (context)
2716 {
2717 gl::Shader *shaderObject = context->getShader(shader);
2718
2719 if (!shaderObject)
2720 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002721 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002722 }
2723
2724 shaderObject->getSource(bufsize, length, source);
2725 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002726 }
2727 catch(std::bad_alloc&)
2728 {
2729 return error(GL_OUT_OF_MEMORY);
2730 }
2731}
2732
2733const GLubyte* __stdcall glGetString(GLenum name)
2734{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002735 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002736
2737 try
2738 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002739 gl::Context *context = gl::getContext();
2740
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002741 switch (name)
2742 {
2743 case GL_VENDOR:
2744 return (GLubyte*)"TransGaming Inc.";
2745 case GL_RENDERER:
2746 return (GLubyte*)"ANGLE";
2747 case GL_VERSION:
2748 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2749 case GL_SHADING_LANGUAGE_VERSION:
2750 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2751 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002752 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002753 default:
2754 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2755 }
2756 }
2757 catch(std::bad_alloc&)
2758 {
2759 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2760 }
2761
2762 return NULL;
2763}
2764
2765void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2766{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002767 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 +00002768
2769 try
2770 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002771 gl::Context *context = gl::getContext();
2772
2773 if (context)
2774 {
2775 gl::Texture *texture;
2776
2777 switch (target)
2778 {
2779 case GL_TEXTURE_2D:
2780 texture = context->getTexture2D();
2781 break;
2782 case GL_TEXTURE_CUBE_MAP:
2783 texture = context->getTextureCubeMap();
2784 break;
2785 default:
2786 return error(GL_INVALID_ENUM);
2787 }
2788
2789 switch (pname)
2790 {
2791 case GL_TEXTURE_MAG_FILTER:
2792 *params = (GLfloat)texture->getMagFilter();
2793 break;
2794 case GL_TEXTURE_MIN_FILTER:
2795 *params = (GLfloat)texture->getMinFilter();
2796 break;
2797 case GL_TEXTURE_WRAP_S:
2798 *params = (GLfloat)texture->getWrapS();
2799 break;
2800 case GL_TEXTURE_WRAP_T:
2801 *params = (GLfloat)texture->getWrapT();
2802 break;
2803 default:
2804 return error(GL_INVALID_ENUM);
2805 }
2806 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002807 }
2808 catch(std::bad_alloc&)
2809 {
2810 return error(GL_OUT_OF_MEMORY);
2811 }
2812}
2813
2814void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2815{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002816 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 +00002817
2818 try
2819 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002820 gl::Context *context = gl::getContext();
2821
2822 if (context)
2823 {
2824 gl::Texture *texture;
2825
2826 switch (target)
2827 {
2828 case GL_TEXTURE_2D:
2829 texture = context->getTexture2D();
2830 break;
2831 case GL_TEXTURE_CUBE_MAP:
2832 texture = context->getTextureCubeMap();
2833 break;
2834 default:
2835 return error(GL_INVALID_ENUM);
2836 }
2837
2838 switch (pname)
2839 {
2840 case GL_TEXTURE_MAG_FILTER:
2841 *params = texture->getMagFilter();
2842 break;
2843 case GL_TEXTURE_MIN_FILTER:
2844 *params = texture->getMinFilter();
2845 break;
2846 case GL_TEXTURE_WRAP_S:
2847 *params = texture->getWrapS();
2848 break;
2849 case GL_TEXTURE_WRAP_T:
2850 *params = texture->getWrapT();
2851 break;
2852 default:
2853 return error(GL_INVALID_ENUM);
2854 }
2855 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002856 }
2857 catch(std::bad_alloc&)
2858 {
2859 return error(GL_OUT_OF_MEMORY);
2860 }
2861}
2862
2863void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2864{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002865 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002866
2867 try
2868 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002869 gl::Context *context = gl::getContext();
2870
2871 if (context)
2872 {
2873 if (program == 0)
2874 {
2875 return error(GL_INVALID_VALUE);
2876 }
2877
2878 gl::Program *programObject = context->getProgram(program);
2879
2880 if (!programObject || !programObject->isLinked())
2881 {
2882 return error(GL_INVALID_OPERATION);
2883 }
2884
2885 if (!programObject->getUniformfv(location, params))
2886 {
2887 return error(GL_INVALID_OPERATION);
2888 }
2889 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002890 }
2891 catch(std::bad_alloc&)
2892 {
2893 return error(GL_OUT_OF_MEMORY);
2894 }
2895}
2896
2897void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2898{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002899 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002900
2901 try
2902 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002903 gl::Context *context = gl::getContext();
2904
2905 if (context)
2906 {
2907 if (program == 0)
2908 {
2909 return error(GL_INVALID_VALUE);
2910 }
2911
2912 gl::Program *programObject = context->getProgram(program);
2913
2914 if (!programObject || !programObject->isLinked())
2915 {
2916 return error(GL_INVALID_OPERATION);
2917 }
2918
2919 if (!programObject)
2920 {
2921 return error(GL_INVALID_OPERATION);
2922 }
2923
2924 if (!programObject->getUniformiv(location, params))
2925 {
2926 return error(GL_INVALID_OPERATION);
2927 }
2928 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002929 }
2930 catch(std::bad_alloc&)
2931 {
2932 return error(GL_OUT_OF_MEMORY);
2933 }
2934}
2935
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002936int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002937{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002938 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002939
2940 try
2941 {
2942 gl::Context *context = gl::getContext();
2943
2944 if (strstr(name, "gl_") == name)
2945 {
2946 return -1;
2947 }
2948
2949 if (context)
2950 {
2951 gl::Program *programObject = context->getProgram(program);
2952
2953 if (!programObject)
2954 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002955 if (context->getShader(program))
2956 {
2957 return error(GL_INVALID_OPERATION, -1);
2958 }
2959 else
2960 {
2961 return error(GL_INVALID_VALUE, -1);
2962 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002963 }
2964
2965 if (!programObject->isLinked())
2966 {
2967 return error(GL_INVALID_OPERATION, -1);
2968 }
2969
2970 return programObject->getUniformLocation(name);
2971 }
2972 }
2973 catch(std::bad_alloc&)
2974 {
2975 return error(GL_OUT_OF_MEMORY, -1);
2976 }
2977
2978 return -1;
2979}
2980
2981void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2982{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002983 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002984
2985 try
2986 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002987 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002988
daniel@transgaming.come0078962010-04-15 20:45:08 +00002989 if (context)
2990 {
2991 if (index >= gl::MAX_VERTEX_ATTRIBS)
2992 {
2993 return error(GL_INVALID_VALUE);
2994 }
2995
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002996 gl::AttributeState attribState = context->getVertexAttribState(index);
2997
daniel@transgaming.come0078962010-04-15 20:45:08 +00002998 switch (pname)
2999 {
3000 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003001 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003002 break;
3003 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003004 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003005 break;
3006 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003007 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003008 break;
3009 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003010 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003011 break;
3012 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003013 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003014 break;
3015 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003016 *params = (GLfloat)attribState.mBoundBuffer;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003017 break;
3018 case GL_CURRENT_VERTEX_ATTRIB:
3019 for (int i = 0; i < 4; ++i)
3020 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003021 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003022 }
3023 break;
3024 default: return error(GL_INVALID_ENUM);
3025 }
3026 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003027 }
3028 catch(std::bad_alloc&)
3029 {
3030 return error(GL_OUT_OF_MEMORY);
3031 }
3032}
3033
3034void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3035{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003036 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003037
3038 try
3039 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003040 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003041
daniel@transgaming.come0078962010-04-15 20:45:08 +00003042 if (context)
3043 {
3044 if (index >= gl::MAX_VERTEX_ATTRIBS)
3045 {
3046 return error(GL_INVALID_VALUE);
3047 }
3048
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003049 gl::AttributeState attribState = context->getVertexAttribState(index);
3050
daniel@transgaming.come0078962010-04-15 20:45:08 +00003051 switch (pname)
3052 {
3053 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003054 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003055 break;
3056 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003057 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003058 break;
3059 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003060 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003061 break;
3062 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003063 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003064 break;
3065 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003066 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003067 break;
3068 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003069 *params = attribState.mBoundBuffer;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003070 break;
3071 case GL_CURRENT_VERTEX_ATTRIB:
3072 for (int i = 0; i < 4; ++i)
3073 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003074 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003075 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3076 }
3077 break;
3078 default: return error(GL_INVALID_ENUM);
3079 }
3080 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003081 }
3082 catch(std::bad_alloc&)
3083 {
3084 return error(GL_OUT_OF_MEMORY);
3085 }
3086}
3087
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003088void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003089{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003090 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003091
3092 try
3093 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003094 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003095
daniel@transgaming.come0078962010-04-15 20:45:08 +00003096 if (context)
3097 {
3098 if (index >= gl::MAX_VERTEX_ATTRIBS)
3099 {
3100 return error(GL_INVALID_VALUE);
3101 }
3102
3103 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3104 {
3105 return error(GL_INVALID_ENUM);
3106 }
3107
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003108 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003109 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003110 }
3111 catch(std::bad_alloc&)
3112 {
3113 return error(GL_OUT_OF_MEMORY);
3114 }
3115}
3116
3117void __stdcall glHint(GLenum target, GLenum mode)
3118{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003119 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003120
3121 try
3122 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003123 switch (target)
3124 {
3125 case GL_GENERATE_MIPMAP_HINT:
3126 switch (mode)
3127 {
3128 case GL_FASTEST:
3129 case GL_NICEST:
3130 case GL_DONT_CARE:
3131 break;
3132 default:
3133 return error(GL_INVALID_ENUM);
3134 }
3135 break;
3136 default:
3137 return error(GL_INVALID_ENUM);
3138 }
3139
3140 gl::Context *context = gl::getContext();
3141 if (context)
3142 {
3143 if (target == GL_GENERATE_MIPMAP_HINT)
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003144 context->setGenerateMipmapHint(mode);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003145 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003146 }
3147 catch(std::bad_alloc&)
3148 {
3149 return error(GL_OUT_OF_MEMORY);
3150 }
3151}
3152
3153GLboolean __stdcall glIsBuffer(GLuint buffer)
3154{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003155 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003156
3157 try
3158 {
3159 gl::Context *context = gl::getContext();
3160
3161 if (context && buffer)
3162 {
3163 gl::Buffer *bufferObject = context->getBuffer(buffer);
3164
3165 if (bufferObject)
3166 {
3167 return GL_TRUE;
3168 }
3169 }
3170 }
3171 catch(std::bad_alloc&)
3172 {
3173 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3174 }
3175
3176 return GL_FALSE;
3177}
3178
3179GLboolean __stdcall glIsEnabled(GLenum cap)
3180{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003181 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003182
3183 try
3184 {
3185 gl::Context *context = gl::getContext();
3186
3187 if (context)
3188 {
3189 switch (cap)
3190 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003191 case GL_CULL_FACE: return context->isCullFaceEnabled();
3192 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3193 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3194 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3195 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3196 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3197 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3198 case GL_BLEND: return context->isBlendEnabled();
3199 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003200 default:
3201 return error(GL_INVALID_ENUM, false);
3202 }
3203 }
3204 }
3205 catch(std::bad_alloc&)
3206 {
3207 return error(GL_OUT_OF_MEMORY, false);
3208 }
3209
3210 return false;
3211}
3212
3213GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3214{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003215 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003216
3217 try
3218 {
3219 gl::Context *context = gl::getContext();
3220
3221 if (context && framebuffer)
3222 {
3223 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3224
3225 if (framebufferObject)
3226 {
3227 return GL_TRUE;
3228 }
3229 }
3230 }
3231 catch(std::bad_alloc&)
3232 {
3233 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3234 }
3235
3236 return GL_FALSE;
3237}
3238
3239GLboolean __stdcall glIsProgram(GLuint program)
3240{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003241 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003242
3243 try
3244 {
3245 gl::Context *context = gl::getContext();
3246
3247 if (context && program)
3248 {
3249 gl::Program *programObject = context->getProgram(program);
3250
3251 if (programObject)
3252 {
3253 return GL_TRUE;
3254 }
3255 }
3256 }
3257 catch(std::bad_alloc&)
3258 {
3259 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3260 }
3261
3262 return GL_FALSE;
3263}
3264
3265GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3266{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003267 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003268
3269 try
3270 {
3271 gl::Context *context = gl::getContext();
3272
3273 if (context && renderbuffer)
3274 {
3275 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3276
3277 if (renderbufferObject)
3278 {
3279 return GL_TRUE;
3280 }
3281 }
3282 }
3283 catch(std::bad_alloc&)
3284 {
3285 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3286 }
3287
3288 return GL_FALSE;
3289}
3290
3291GLboolean __stdcall glIsShader(GLuint shader)
3292{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003293 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003294
3295 try
3296 {
3297 gl::Context *context = gl::getContext();
3298
3299 if (context && shader)
3300 {
3301 gl::Shader *shaderObject = context->getShader(shader);
3302
3303 if (shaderObject)
3304 {
3305 return GL_TRUE;
3306 }
3307 }
3308 }
3309 catch(std::bad_alloc&)
3310 {
3311 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3312 }
3313
3314 return GL_FALSE;
3315}
3316
3317GLboolean __stdcall glIsTexture(GLuint texture)
3318{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003319 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003320
3321 try
3322 {
3323 gl::Context *context = gl::getContext();
3324
3325 if (context && texture)
3326 {
3327 gl::Texture *textureObject = context->getTexture(texture);
3328
3329 if (textureObject)
3330 {
3331 return GL_TRUE;
3332 }
3333 }
3334 }
3335 catch(std::bad_alloc&)
3336 {
3337 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3338 }
3339
3340 return GL_FALSE;
3341}
3342
3343void __stdcall glLineWidth(GLfloat width)
3344{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003345 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003346
3347 try
3348 {
3349 if (width <= 0.0f)
3350 {
3351 return error(GL_INVALID_VALUE);
3352 }
3353
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003354 gl::Context *context = gl::getContext();
3355
3356 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003357 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003358 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003359 }
3360 }
3361 catch(std::bad_alloc&)
3362 {
3363 return error(GL_OUT_OF_MEMORY);
3364 }
3365}
3366
3367void __stdcall glLinkProgram(GLuint program)
3368{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003369 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003370
3371 try
3372 {
3373 gl::Context *context = gl::getContext();
3374
3375 if (context)
3376 {
3377 gl::Program *programObject = context->getProgram(program);
3378
3379 if (!programObject)
3380 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003381 if (context->getShader(program))
3382 {
3383 return error(GL_INVALID_OPERATION);
3384 }
3385 else
3386 {
3387 return error(GL_INVALID_VALUE);
3388 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003389 }
3390
3391 programObject->link();
3392 }
3393 }
3394 catch(std::bad_alloc&)
3395 {
3396 return error(GL_OUT_OF_MEMORY);
3397 }
3398}
3399
3400void __stdcall glPixelStorei(GLenum pname, GLint param)
3401{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003402 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003403
3404 try
3405 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003406 gl::Context *context = gl::getContext();
3407
3408 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003409 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003410 switch (pname)
3411 {
3412 case GL_UNPACK_ALIGNMENT:
3413 if (param != 1 && param != 2 && param != 4 && param != 8)
3414 {
3415 return error(GL_INVALID_VALUE);
3416 }
3417
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003418 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003419 break;
3420
3421 case GL_PACK_ALIGNMENT:
3422 if (param != 1 && param != 2 && param != 4 && param != 8)
3423 {
3424 return error(GL_INVALID_VALUE);
3425 }
3426
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003427 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003428 break;
3429
3430 default:
3431 return error(GL_INVALID_ENUM);
3432 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003433 }
3434 }
3435 catch(std::bad_alloc&)
3436 {
3437 return error(GL_OUT_OF_MEMORY);
3438 }
3439}
3440
3441void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3442{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003443 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003444
3445 try
3446 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003447 gl::Context *context = gl::getContext();
3448
3449 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003450 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003451 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003452 }
3453 }
3454 catch(std::bad_alloc&)
3455 {
3456 return error(GL_OUT_OF_MEMORY);
3457 }
3458}
3459
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003460void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003461{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003462 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003463 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003464 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003465
3466 try
3467 {
3468 if (width < 0 || height < 0)
3469 {
3470 return error(GL_INVALID_VALUE);
3471 }
3472
3473 switch (format)
3474 {
3475 case GL_RGBA:
3476 switch (type)
3477 {
3478 case GL_UNSIGNED_BYTE:
3479 break;
3480 default:
3481 return error(GL_INVALID_OPERATION);
3482 }
3483 break;
3484 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3485 switch (type)
3486 {
3487 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3488 break;
3489 default:
3490 return error(GL_INVALID_OPERATION);
3491 }
3492 break;
3493 default:
3494 return error(GL_INVALID_OPERATION);
3495 }
3496
3497 gl::Context *context = gl::getContext();
3498
3499 if (context)
3500 {
3501 context->readPixels(x, y, width, height, format, type, pixels);
3502 }
3503 }
3504 catch(std::bad_alloc&)
3505 {
3506 return error(GL_OUT_OF_MEMORY);
3507 }
3508}
3509
3510void __stdcall glReleaseShaderCompiler(void)
3511{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003512 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003513
3514 try
3515 {
3516 gl::Shader::releaseCompiler();
3517 }
3518 catch(std::bad_alloc&)
3519 {
3520 return error(GL_OUT_OF_MEMORY);
3521 }
3522}
3523
3524void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3525{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003526 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3527 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003528
3529 try
3530 {
3531 switch (target)
3532 {
3533 case GL_RENDERBUFFER:
3534 break;
3535 default:
3536 return error(GL_INVALID_ENUM);
3537 }
3538
3539 switch (internalformat)
3540 {
3541 case GL_DEPTH_COMPONENT16:
3542 case GL_RGBA4:
3543 case GL_RGB5_A1:
3544 case GL_RGB565:
3545 case GL_STENCIL_INDEX8:
3546 break;
3547 default:
3548 return error(GL_INVALID_ENUM);
3549 }
3550
3551 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3552 {
3553 return error(GL_INVALID_VALUE);
3554 }
3555
3556 gl::Context *context = gl::getContext();
3557
3558 if (context)
3559 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003560 if (context->getFramebufferHandle() == 0 || context->getRenderbufferHandle() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003561 {
3562 return error(GL_INVALID_OPERATION);
3563 }
3564
3565 switch (internalformat)
3566 {
3567 case GL_DEPTH_COMPONENT16:
3568 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3569 break;
3570 case GL_RGBA4:
3571 case GL_RGB5_A1:
3572 case GL_RGB565:
daniel@transgaming.com70d312a2010-04-20 18:52:38 +00003573 context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003574 break;
3575 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003576 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003577 break;
3578 default:
3579 return error(GL_INVALID_ENUM);
3580 }
3581 }
3582 }
3583 catch(std::bad_alloc&)
3584 {
3585 return error(GL_OUT_OF_MEMORY);
3586 }
3587}
3588
3589void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3590{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003591 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003592
3593 try
3594 {
3595 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003596
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003597 if (context)
3598 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003599 context->setSampleCoverageParams(gl::clamp01(value), invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003600 }
3601 }
3602 catch(std::bad_alloc&)
3603 {
3604 return error(GL_OUT_OF_MEMORY);
3605 }
3606}
3607
3608void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3609{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003610 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 +00003611
3612 try
3613 {
3614 if (width < 0 || height < 0)
3615 {
3616 return error(GL_INVALID_VALUE);
3617 }
3618
3619 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003620
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003621 if (context)
3622 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003623 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003624 }
3625 }
3626 catch(std::bad_alloc&)
3627 {
3628 return error(GL_OUT_OF_MEMORY);
3629 }
3630}
3631
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003632void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003633{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003634 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003635 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003636 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003637
3638 try
3639 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00003640 // No binary shader formats are supported.
3641 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003642 }
3643 catch(std::bad_alloc&)
3644 {
3645 return error(GL_OUT_OF_MEMORY);
3646 }
3647}
3648
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003649void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003650{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003651 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 +00003652 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003653
3654 try
3655 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003656 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003657 {
3658 return error(GL_INVALID_VALUE);
3659 }
3660
3661 gl::Context *context = gl::getContext();
3662
3663 if (context)
3664 {
3665 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003666
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003667 if (!shaderObject)
3668 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003669 if (context->getProgram(shader))
3670 {
3671 return error(GL_INVALID_OPERATION);
3672 }
3673 else
3674 {
3675 return error(GL_INVALID_VALUE);
3676 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003677 }
3678
3679 shaderObject->setSource(count, string, length);
3680 }
3681 }
3682 catch(std::bad_alloc&)
3683 {
3684 return error(GL_OUT_OF_MEMORY);
3685 }
3686}
3687
3688void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3689{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003690 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003691}
3692
3693void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3694{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003695 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 +00003696
3697 try
3698 {
3699 switch (face)
3700 {
3701 case GL_FRONT:
3702 case GL_BACK:
3703 case GL_FRONT_AND_BACK:
3704 break;
3705 default:
3706 return error(GL_INVALID_ENUM);
3707 }
3708
3709 switch (func)
3710 {
3711 case GL_NEVER:
3712 case GL_ALWAYS:
3713 case GL_LESS:
3714 case GL_LEQUAL:
3715 case GL_EQUAL:
3716 case GL_GEQUAL:
3717 case GL_GREATER:
3718 case GL_NOTEQUAL:
3719 break;
3720 default:
3721 return error(GL_INVALID_ENUM);
3722 }
3723
3724 gl::Context *context = gl::getContext();
3725
3726 if (context)
3727 {
3728 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3729 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003730 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003731 }
3732
3733 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3734 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003735 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003736 }
3737 }
3738 }
3739 catch(std::bad_alloc&)
3740 {
3741 return error(GL_OUT_OF_MEMORY);
3742 }
3743}
3744
3745void __stdcall glStencilMask(GLuint mask)
3746{
3747 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3748}
3749
3750void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3751{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003752 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003753
3754 try
3755 {
3756 switch (face)
3757 {
3758 case GL_FRONT:
3759 case GL_BACK:
3760 case GL_FRONT_AND_BACK:
3761 break;
3762 default:
3763 return error(GL_INVALID_ENUM);
3764 }
3765
3766 gl::Context *context = gl::getContext();
3767
3768 if (context)
3769 {
3770 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3771 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003772 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003773 }
3774
3775 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3776 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003777 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003778 }
3779 }
3780 }
3781 catch(std::bad_alloc&)
3782 {
3783 return error(GL_OUT_OF_MEMORY);
3784 }
3785}
3786
3787void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3788{
3789 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3790}
3791
3792void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3793{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003794 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3795 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003796
3797 try
3798 {
3799 switch (face)
3800 {
3801 case GL_FRONT:
3802 case GL_BACK:
3803 case GL_FRONT_AND_BACK:
3804 break;
3805 default:
3806 return error(GL_INVALID_ENUM);
3807 }
3808
3809 switch (fail)
3810 {
3811 case GL_ZERO:
3812 case GL_KEEP:
3813 case GL_REPLACE:
3814 case GL_INCR:
3815 case GL_DECR:
3816 case GL_INVERT:
3817 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003818 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003819 break;
3820 default:
3821 return error(GL_INVALID_ENUM);
3822 }
3823
3824 switch (zfail)
3825 {
3826 case GL_ZERO:
3827 case GL_KEEP:
3828 case GL_REPLACE:
3829 case GL_INCR:
3830 case GL_DECR:
3831 case GL_INVERT:
3832 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003833 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003834 break;
3835 default:
3836 return error(GL_INVALID_ENUM);
3837 }
3838
3839 switch (zpass)
3840 {
3841 case GL_ZERO:
3842 case GL_KEEP:
3843 case GL_REPLACE:
3844 case GL_INCR:
3845 case GL_DECR:
3846 case GL_INVERT:
3847 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003848 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003849 break;
3850 default:
3851 return error(GL_INVALID_ENUM);
3852 }
3853
3854 gl::Context *context = gl::getContext();
3855
3856 if (context)
3857 {
3858 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3859 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003860 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003861 }
3862
3863 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3864 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003865 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003866 }
3867 }
3868 }
3869 catch(std::bad_alloc&)
3870 {
3871 return error(GL_OUT_OF_MEMORY);
3872 }
3873}
3874
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003875void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3876 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003877{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003878 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 +00003879 "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 +00003880 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003881
3882 try
3883 {
3884 if (level < 0 || width < 0 || height < 0)
3885 {
3886 return error(GL_INVALID_VALUE);
3887 }
3888
3889 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3890 {
3891 return error(GL_INVALID_VALUE);
3892 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003893
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003894 switch (target)
3895 {
3896 case GL_TEXTURE_2D:
3897 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3898 {
3899 return error(GL_INVALID_VALUE);
3900 }
3901 break;
3902 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3903 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3904 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3905 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3906 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3907 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003908 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003909 {
3910 return error(GL_INVALID_VALUE);
3911 }
3912
3913 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3914 {
3915 return error(GL_INVALID_VALUE);
3916 }
3917 break;
3918 default:
3919 return error(GL_INVALID_ENUM);
3920 }
3921
3922 if (internalformat != format)
3923 {
3924 return error(GL_INVALID_OPERATION);
3925 }
3926
3927 switch (internalformat)
3928 {
3929 case GL_ALPHA:
3930 case GL_LUMINANCE:
3931 case GL_LUMINANCE_ALPHA:
3932 switch (type)
3933 {
3934 case GL_UNSIGNED_BYTE:
3935 break;
3936 default:
3937 return error(GL_INVALID_ENUM);
3938 }
3939 break;
3940 case GL_RGB:
3941 switch (type)
3942 {
3943 case GL_UNSIGNED_BYTE:
3944 case GL_UNSIGNED_SHORT_5_6_5:
3945 break;
3946 default:
3947 return error(GL_INVALID_ENUM);
3948 }
3949 break;
3950 case GL_RGBA:
3951 switch (type)
3952 {
3953 case GL_UNSIGNED_BYTE:
3954 case GL_UNSIGNED_SHORT_4_4_4_4:
3955 case GL_UNSIGNED_SHORT_5_5_5_1:
3956 break;
3957 default:
3958 return error(GL_INVALID_ENUM);
3959 }
3960 break;
3961 default:
3962 return error(GL_INVALID_VALUE);
3963 }
3964
3965 if (border != 0)
3966 {
3967 return error(GL_INVALID_VALUE);
3968 }
3969
3970 gl::Context *context = gl::getContext();
3971
3972 if (context)
3973 {
3974 if (target == GL_TEXTURE_2D)
3975 {
3976 gl::Texture2D *texture = context->getTexture2D();
3977
3978 if (!texture)
3979 {
3980 return error(GL_INVALID_OPERATION);
3981 }
3982
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003983 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003984 }
3985 else
3986 {
3987 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3988
3989 if (!texture)
3990 {
3991 return error(GL_INVALID_OPERATION);
3992 }
3993
3994 switch (target)
3995 {
3996 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003997 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003998 break;
3999 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004000 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004001 break;
4002 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004003 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004004 break;
4005 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004006 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004007 break;
4008 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004009 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004010 break;
4011 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004012 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004013 break;
4014 default: UNREACHABLE();
4015 }
4016 }
4017 }
4018 }
4019 catch(std::bad_alloc&)
4020 {
4021 return error(GL_OUT_OF_MEMORY);
4022 }
4023}
4024
4025void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4026{
4027 glTexParameteri(target, pname, (GLint)param);
4028}
4029
4030void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4031{
4032 glTexParameteri(target, pname, (GLint)*params);
4033}
4034
4035void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4036{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004037 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004038
4039 try
4040 {
4041 gl::Context *context = gl::getContext();
4042
4043 if (context)
4044 {
4045 gl::Texture *texture;
4046
4047 switch (target)
4048 {
4049 case GL_TEXTURE_2D:
4050 texture = context->getTexture2D();
4051 break;
4052 case GL_TEXTURE_CUBE_MAP:
4053 texture = context->getTextureCubeMap();
4054 break;
4055 default:
4056 return error(GL_INVALID_ENUM);
4057 }
4058
4059 switch (pname)
4060 {
4061 case GL_TEXTURE_WRAP_S:
4062 if (!texture->setWrapS((GLenum)param))
4063 {
4064 return error(GL_INVALID_ENUM);
4065 }
4066 break;
4067 case GL_TEXTURE_WRAP_T:
4068 if (!texture->setWrapT((GLenum)param))
4069 {
4070 return error(GL_INVALID_ENUM);
4071 }
4072 break;
4073 case GL_TEXTURE_MIN_FILTER:
4074 if (!texture->setMinFilter((GLenum)param))
4075 {
4076 return error(GL_INVALID_ENUM);
4077 }
4078 break;
4079 case GL_TEXTURE_MAG_FILTER:
4080 if (!texture->setMagFilter((GLenum)param))
4081 {
4082 return error(GL_INVALID_ENUM);
4083 }
4084 break;
4085 default:
4086 return error(GL_INVALID_ENUM);
4087 }
4088 }
4089 }
4090 catch(std::bad_alloc&)
4091 {
4092 return error(GL_OUT_OF_MEMORY);
4093 }
4094}
4095
4096void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4097{
4098 glTexParameteri(target, pname, *params);
4099}
4100
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004101void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4102 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004103{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004104 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4105 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004106 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004107 target, level, xoffset, yoffset, width, height, format, type, pixels);
4108
4109 try
4110 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004111 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004112 {
4113 return error(GL_INVALID_ENUM);
4114 }
4115
4116 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004117 {
4118 return error(GL_INVALID_VALUE);
4119 }
4120
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004121 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4122 {
4123 return error(GL_INVALID_VALUE);
4124 }
4125
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004126 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004127 {
4128 return error(GL_INVALID_ENUM);
4129 }
4130
4131 if (width == 0 || height == 0 || pixels == NULL)
4132 {
4133 return;
4134 }
4135
4136 gl::Context *context = gl::getContext();
4137
4138 if (context)
4139 {
4140 if (target == GL_TEXTURE_2D)
4141 {
4142 gl::Texture2D *texture = context->getTexture2D();
4143
4144 if (!texture)
4145 {
4146 return error(GL_INVALID_OPERATION);
4147 }
4148
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004149 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004150 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004151 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004152 {
4153 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4154
4155 if (!texture)
4156 {
4157 return error(GL_INVALID_OPERATION);
4158 }
4159
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004160 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004161 }
4162 else
4163 {
4164 UNREACHABLE();
4165 }
4166 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004167 }
4168 catch(std::bad_alloc&)
4169 {
4170 return error(GL_OUT_OF_MEMORY);
4171 }
4172}
4173
4174void __stdcall glUniform1f(GLint location, GLfloat x)
4175{
4176 glUniform1fv(location, 1, &x);
4177}
4178
4179void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4180{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004181 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004182
4183 try
4184 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004185 if (count < 0)
4186 {
4187 return error(GL_INVALID_VALUE);
4188 }
4189
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004190 if (location == -1)
4191 {
4192 return;
4193 }
4194
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004195 gl::Context *context = gl::getContext();
4196
4197 if (context)
4198 {
4199 gl::Program *program = context->getCurrentProgram();
4200
4201 if (!program)
4202 {
4203 return error(GL_INVALID_OPERATION);
4204 }
4205
4206 if (!program->setUniform1fv(location, count, v))
4207 {
4208 return error(GL_INVALID_OPERATION);
4209 }
4210 }
4211 }
4212 catch(std::bad_alloc&)
4213 {
4214 return error(GL_OUT_OF_MEMORY);
4215 }
4216}
4217
4218void __stdcall glUniform1i(GLint location, GLint x)
4219{
4220 glUniform1iv(location, 1, &x);
4221}
4222
4223void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4224{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004225 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004226
4227 try
4228 {
4229 if (count < 0)
4230 {
4231 return error(GL_INVALID_VALUE);
4232 }
4233
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004234 if (location == -1)
4235 {
4236 return;
4237 }
4238
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004239 gl::Context *context = gl::getContext();
4240
4241 if (context)
4242 {
4243 gl::Program *program = context->getCurrentProgram();
4244
4245 if (!program)
4246 {
4247 return error(GL_INVALID_OPERATION);
4248 }
4249
4250 if (!program->setUniform1iv(location, count, v))
4251 {
4252 return error(GL_INVALID_OPERATION);
4253 }
4254 }
4255 }
4256 catch(std::bad_alloc&)
4257 {
4258 return error(GL_OUT_OF_MEMORY);
4259 }
4260}
4261
4262void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4263{
4264 GLfloat xy[2] = {x, y};
4265
4266 glUniform2fv(location, 1, (GLfloat*)&xy);
4267}
4268
4269void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4270{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004271 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004272
4273 try
4274 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004275 if (count < 0)
4276 {
4277 return error(GL_INVALID_VALUE);
4278 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004279
4280 if (location == -1)
4281 {
4282 return;
4283 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004284
4285 gl::Context *context = gl::getContext();
4286
4287 if (context)
4288 {
4289 gl::Program *program = context->getCurrentProgram();
4290
4291 if (!program)
4292 {
4293 return error(GL_INVALID_OPERATION);
4294 }
4295
4296 if (!program->setUniform2fv(location, count, v))
4297 {
4298 return error(GL_INVALID_OPERATION);
4299 }
4300 }
4301 }
4302 catch(std::bad_alloc&)
4303 {
4304 return error(GL_OUT_OF_MEMORY);
4305 }
4306}
4307
4308void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4309{
4310 GLint xy[4] = {x, y};
4311
4312 glUniform2iv(location, 1, (GLint*)&xy);
4313}
4314
4315void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4316{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004317 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004318
4319 try
4320 {
4321 if (count < 0)
4322 {
4323 return error(GL_INVALID_VALUE);
4324 }
4325
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004326 if (location == -1)
4327 {
4328 return;
4329 }
4330
4331 gl::Context *context = gl::getContext();
4332
4333 if (context)
4334 {
4335 gl::Program *program = context->getCurrentProgram();
4336
4337 if (!program)
4338 {
4339 return error(GL_INVALID_OPERATION);
4340 }
4341
4342 if (!program->setUniform2iv(location, count, v))
4343 {
4344 return error(GL_INVALID_OPERATION);
4345 }
4346 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004347 }
4348 catch(std::bad_alloc&)
4349 {
4350 return error(GL_OUT_OF_MEMORY);
4351 }
4352}
4353
4354void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4355{
4356 GLfloat xyz[3] = {x, y, z};
4357
4358 glUniform3fv(location, 1, (GLfloat*)&xyz);
4359}
4360
4361void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4362{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004363 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004364
4365 try
4366 {
4367 if (count < 0)
4368 {
4369 return error(GL_INVALID_VALUE);
4370 }
4371
4372 if (location == -1)
4373 {
4374 return;
4375 }
4376
4377 gl::Context *context = gl::getContext();
4378
4379 if (context)
4380 {
4381 gl::Program *program = context->getCurrentProgram();
4382
4383 if (!program)
4384 {
4385 return error(GL_INVALID_OPERATION);
4386 }
4387
4388 if (!program->setUniform3fv(location, count, v))
4389 {
4390 return error(GL_INVALID_OPERATION);
4391 }
4392 }
4393 }
4394 catch(std::bad_alloc&)
4395 {
4396 return error(GL_OUT_OF_MEMORY);
4397 }
4398}
4399
4400void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4401{
4402 GLint xyz[3] = {x, y, z};
4403
4404 glUniform3iv(location, 1, (GLint*)&xyz);
4405}
4406
4407void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4408{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004409 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004410
4411 try
4412 {
4413 if (count < 0)
4414 {
4415 return error(GL_INVALID_VALUE);
4416 }
4417
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004418 if (location == -1)
4419 {
4420 return;
4421 }
4422
4423 gl::Context *context = gl::getContext();
4424
4425 if (context)
4426 {
4427 gl::Program *program = context->getCurrentProgram();
4428
4429 if (!program)
4430 {
4431 return error(GL_INVALID_OPERATION);
4432 }
4433
4434 if (!program->setUniform3iv(location, count, v))
4435 {
4436 return error(GL_INVALID_OPERATION);
4437 }
4438 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004439 }
4440 catch(std::bad_alloc&)
4441 {
4442 return error(GL_OUT_OF_MEMORY);
4443 }
4444}
4445
4446void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4447{
4448 GLfloat xyzw[4] = {x, y, z, w};
4449
4450 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4451}
4452
4453void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4454{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004455 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004456
4457 try
4458 {
4459 if (count < 0)
4460 {
4461 return error(GL_INVALID_VALUE);
4462 }
4463
4464 if (location == -1)
4465 {
4466 return;
4467 }
4468
4469 gl::Context *context = gl::getContext();
4470
4471 if (context)
4472 {
4473 gl::Program *program = context->getCurrentProgram();
4474
4475 if (!program)
4476 {
4477 return error(GL_INVALID_OPERATION);
4478 }
4479
4480 if (!program->setUniform4fv(location, count, v))
4481 {
4482 return error(GL_INVALID_OPERATION);
4483 }
4484 }
4485 }
4486 catch(std::bad_alloc&)
4487 {
4488 return error(GL_OUT_OF_MEMORY);
4489 }
4490}
4491
4492void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4493{
4494 GLint xyzw[4] = {x, y, z, w};
4495
4496 glUniform4iv(location, 1, (GLint*)&xyzw);
4497}
4498
4499void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4500{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004501 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004502
4503 try
4504 {
4505 if (count < 0)
4506 {
4507 return error(GL_INVALID_VALUE);
4508 }
4509
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004510 if (location == -1)
4511 {
4512 return;
4513 }
4514
4515 gl::Context *context = gl::getContext();
4516
4517 if (context)
4518 {
4519 gl::Program *program = context->getCurrentProgram();
4520
4521 if (!program)
4522 {
4523 return error(GL_INVALID_OPERATION);
4524 }
4525
4526 if (!program->setUniform4iv(location, count, v))
4527 {
4528 return error(GL_INVALID_OPERATION);
4529 }
4530 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004531 }
4532 catch(std::bad_alloc&)
4533 {
4534 return error(GL_OUT_OF_MEMORY);
4535 }
4536}
4537
4538void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4539{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004540 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4541 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004542
4543 try
4544 {
4545 if (count < 0 || transpose != GL_FALSE)
4546 {
4547 return error(GL_INVALID_VALUE);
4548 }
4549
4550 if (location == -1)
4551 {
4552 return;
4553 }
4554
4555 gl::Context *context = gl::getContext();
4556
4557 if (context)
4558 {
4559 gl::Program *program = context->getCurrentProgram();
4560
4561 if (!program)
4562 {
4563 return error(GL_INVALID_OPERATION);
4564 }
4565
4566 if (!program->setUniformMatrix2fv(location, count, value))
4567 {
4568 return error(GL_INVALID_OPERATION);
4569 }
4570 }
4571 }
4572 catch(std::bad_alloc&)
4573 {
4574 return error(GL_OUT_OF_MEMORY);
4575 }
4576}
4577
4578void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4579{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004580 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4581 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004582
4583 try
4584 {
4585 if (count < 0 || transpose != GL_FALSE)
4586 {
4587 return error(GL_INVALID_VALUE);
4588 }
4589
4590 if (location == -1)
4591 {
4592 return;
4593 }
4594
4595 gl::Context *context = gl::getContext();
4596
4597 if (context)
4598 {
4599 gl::Program *program = context->getCurrentProgram();
4600
4601 if (!program)
4602 {
4603 return error(GL_INVALID_OPERATION);
4604 }
4605
4606 if (!program->setUniformMatrix3fv(location, count, value))
4607 {
4608 return error(GL_INVALID_OPERATION);
4609 }
4610 }
4611 }
4612 catch(std::bad_alloc&)
4613 {
4614 return error(GL_OUT_OF_MEMORY);
4615 }
4616}
4617
4618void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4619{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004620 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4621 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004622
4623 try
4624 {
4625 if (count < 0 || transpose != GL_FALSE)
4626 {
4627 return error(GL_INVALID_VALUE);
4628 }
4629
4630 if (location == -1)
4631 {
4632 return;
4633 }
4634
4635 gl::Context *context = gl::getContext();
4636
4637 if (context)
4638 {
4639 gl::Program *program = context->getCurrentProgram();
4640
4641 if (!program)
4642 {
4643 return error(GL_INVALID_OPERATION);
4644 }
4645
4646 if (!program->setUniformMatrix4fv(location, count, value))
4647 {
4648 return error(GL_INVALID_OPERATION);
4649 }
4650 }
4651 }
4652 catch(std::bad_alloc&)
4653 {
4654 return error(GL_OUT_OF_MEMORY);
4655 }
4656}
4657
4658void __stdcall glUseProgram(GLuint program)
4659{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004660 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004661
4662 try
4663 {
4664 gl::Context *context = gl::getContext();
4665
4666 if (context)
4667 {
4668 gl::Program *programObject = context->getProgram(program);
4669
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004670 if (!programObject && program != 0)
4671 {
4672 if (context->getShader(program))
4673 {
4674 return error(GL_INVALID_OPERATION);
4675 }
4676 else
4677 {
4678 return error(GL_INVALID_VALUE);
4679 }
4680 }
4681
4682 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004683 {
4684 return error(GL_INVALID_OPERATION);
4685 }
4686
4687 context->useProgram(program);
4688 }
4689 }
4690 catch(std::bad_alloc&)
4691 {
4692 return error(GL_OUT_OF_MEMORY);
4693 }
4694}
4695
4696void __stdcall glValidateProgram(GLuint program)
4697{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004698 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004699
4700 try
4701 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00004702 gl::Context *context = gl::getContext();
4703
4704 if (context)
4705 {
4706 gl::Program *programObject = context->getProgram(program);
4707
4708 if (!programObject)
4709 {
4710 if (context->getShader(program))
4711 {
4712 return error(GL_INVALID_OPERATION);
4713 }
4714 else
4715 {
4716 return error(GL_INVALID_VALUE);
4717 }
4718 }
4719
4720 programObject->validate();
4721 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004722 }
4723 catch(std::bad_alloc&)
4724 {
4725 return error(GL_OUT_OF_MEMORY);
4726 }
4727}
4728
4729void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4730{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004731 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004732
4733 try
4734 {
4735 if (index >= gl::MAX_VERTEX_ATTRIBS)
4736 {
4737 return error(GL_INVALID_VALUE);
4738 }
4739
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004740 gl::Context *context = gl::getContext();
4741
4742 if (context)
4743 {
4744 GLfloat vals[4] = { x, 0, 0, 1 };
4745 context->setVertexAttrib(index, vals);
4746 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004747 }
4748 catch(std::bad_alloc&)
4749 {
4750 return error(GL_OUT_OF_MEMORY);
4751 }
4752}
4753
4754void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4755{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004756 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004757
4758 try
4759 {
4760 if (index >= gl::MAX_VERTEX_ATTRIBS)
4761 {
4762 return error(GL_INVALID_VALUE);
4763 }
4764
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004765 gl::Context *context = gl::getContext();
4766
4767 if (context)
4768 {
4769 GLfloat vals[4] = { values[0], 0, 0, 1 };
4770 context->setVertexAttrib(index, vals);
4771 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004772 }
4773 catch(std::bad_alloc&)
4774 {
4775 return error(GL_OUT_OF_MEMORY);
4776 }
4777}
4778
4779void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4780{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004781 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004782
4783 try
4784 {
4785 if (index >= gl::MAX_VERTEX_ATTRIBS)
4786 {
4787 return error(GL_INVALID_VALUE);
4788 }
4789
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004790 gl::Context *context = gl::getContext();
4791
4792 if (context)
4793 {
4794 GLfloat vals[4] = { x, y, 0, 1 };
4795 context->setVertexAttrib(index, vals);
4796 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004797 }
4798 catch(std::bad_alloc&)
4799 {
4800 return error(GL_OUT_OF_MEMORY);
4801 }
4802}
4803
4804void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4805{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004806 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004807
4808 try
4809 {
4810 if (index >= gl::MAX_VERTEX_ATTRIBS)
4811 {
4812 return error(GL_INVALID_VALUE);
4813 }
4814
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004815 gl::Context *context = gl::getContext();
4816
4817 if (context)
4818 {
4819 GLfloat vals[4] = { values[0], values[1], 0, 1 };
4820 context->setVertexAttrib(index, vals);
4821 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004822 }
4823 catch(std::bad_alloc&)
4824 {
4825 return error(GL_OUT_OF_MEMORY);
4826 }
4827}
4828
4829void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4830{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004831 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 +00004832
4833 try
4834 {
4835 if (index >= gl::MAX_VERTEX_ATTRIBS)
4836 {
4837 return error(GL_INVALID_VALUE);
4838 }
4839
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004840 gl::Context *context = gl::getContext();
4841
4842 if (context)
4843 {
4844 GLfloat vals[4] = { x, y, z, 1 };
4845 context->setVertexAttrib(index, vals);
4846 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004847 }
4848 catch(std::bad_alloc&)
4849 {
4850 return error(GL_OUT_OF_MEMORY);
4851 }
4852}
4853
4854void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4855{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004856 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004857
4858 try
4859 {
4860 if (index >= gl::MAX_VERTEX_ATTRIBS)
4861 {
4862 return error(GL_INVALID_VALUE);
4863 }
4864
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004865 gl::Context *context = gl::getContext();
4866
4867 if (context)
4868 {
4869 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
4870 context->setVertexAttrib(index, vals);
4871 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004872 }
4873 catch(std::bad_alloc&)
4874 {
4875 return error(GL_OUT_OF_MEMORY);
4876 }
4877}
4878
4879void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4880{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004881 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 +00004882
4883 try
4884 {
4885 if (index >= gl::MAX_VERTEX_ATTRIBS)
4886 {
4887 return error(GL_INVALID_VALUE);
4888 }
4889
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004890 gl::Context *context = gl::getContext();
4891
4892 if (context)
4893 {
4894 GLfloat vals[4] = { x, y, z, w };
4895 context->setVertexAttrib(index, vals);
4896 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004897 }
4898 catch(std::bad_alloc&)
4899 {
4900 return error(GL_OUT_OF_MEMORY);
4901 }
4902}
4903
4904void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4905{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004906 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004907
4908 try
4909 {
4910 if (index >= gl::MAX_VERTEX_ATTRIBS)
4911 {
4912 return error(GL_INVALID_VALUE);
4913 }
4914
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004915 gl::Context *context = gl::getContext();
4916
4917 if (context)
4918 {
4919 context->setVertexAttrib(index, values);
4920 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004921 }
4922 catch(std::bad_alloc&)
4923 {
4924 return error(GL_OUT_OF_MEMORY);
4925 }
4926}
4927
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004928void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004929{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004930 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004931 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004932 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004933
4934 try
4935 {
4936 if (index >= gl::MAX_VERTEX_ATTRIBS)
4937 {
4938 return error(GL_INVALID_VALUE);
4939 }
4940
4941 if (size < 1 || size > 4)
4942 {
4943 return error(GL_INVALID_VALUE);
4944 }
4945
4946 switch (type)
4947 {
4948 case GL_BYTE:
4949 case GL_UNSIGNED_BYTE:
4950 case GL_SHORT:
4951 case GL_UNSIGNED_SHORT:
4952 case GL_FIXED:
4953 case GL_FLOAT:
4954 break;
4955 default:
4956 return error(GL_INVALID_ENUM);
4957 }
4958
4959 if (stride < 0)
4960 {
4961 return error(GL_INVALID_VALUE);
4962 }
4963
4964 gl::Context *context = gl::getContext();
4965
4966 if (context)
4967 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004968 context->setVertexAttribState(index, context->getArrayBufferHandle(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004969 }
4970 }
4971 catch(std::bad_alloc&)
4972 {
4973 return error(GL_OUT_OF_MEMORY);
4974 }
4975}
4976
4977void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4978{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004979 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 +00004980
4981 try
4982 {
4983 if (width < 0 || height < 0)
4984 {
4985 return error(GL_INVALID_VALUE);
4986 }
4987
4988 gl::Context *context = gl::getContext();
4989
4990 if (context)
4991 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004992 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004993 }
4994 }
4995 catch(std::bad_alloc&)
4996 {
4997 return error(GL_OUT_OF_MEMORY);
4998 }
4999}
5000
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005001void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5002 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005003{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005004 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5005 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005006 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005007 target, level, internalformat, width, height, depth, border, format, type, pixels);
5008
5009 try
5010 {
5011 UNIMPLEMENTED(); // FIXME
5012 }
5013 catch(std::bad_alloc&)
5014 {
5015 return error(GL_OUT_OF_MEMORY);
5016 }
5017}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005018
5019__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5020{
5021 struct Extension
5022 {
5023 const char *name;
5024 __eglMustCastToProperFunctionPointerType address;
5025 };
5026
5027 static const Extension glExtensions[] =
5028 {
5029 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
5030 };
5031
5032 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5033 {
5034 if (strcmp(procname, glExtensions[ext].name) == 0)
5035 {
5036 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5037 }
5038 }
5039
5040 return NULL;
5041}
5042
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005043}