blob: e1c230079c978f2b91d1feff5acfb11df64cf89a [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000017
18#include "libGLESv2/main.h"
19#include "libGLESv2/mathutil.h"
20#include "libGLESv2/utilities.h"
21#include "libGLESv2/Buffer.h"
22#include "libGLESv2/Context.h"
23#include "libGLESv2/Framebuffer.h"
24#include "libGLESv2/Program.h"
25#include "libGLESv2/Renderbuffer.h"
26#include "libGLESv2/Shader.h"
27#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000028
29extern "C"
30{
31
32void __stdcall glActiveTexture(GLenum texture)
33{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000034 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035
36 try
37 {
38 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
39 {
40 return error(GL_INVALID_ENUM);
41 }
42
43 gl::Context *context = gl::getContext();
44
45 if (context)
46 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +000047 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000048 }
49 }
50 catch(std::bad_alloc&)
51 {
52 return error(GL_OUT_OF_MEMORY);
53 }
54}
55
56void __stdcall glAttachShader(GLuint program, GLuint shader)
57{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000058 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000059
60 try
61 {
62 gl::Context *context = gl::getContext();
63
64 if (context)
65 {
66 gl::Program *programObject = context->getProgram(program);
67 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000068
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000069 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000071 if (context->getShader(program))
72 {
73 return error(GL_INVALID_OPERATION);
74 }
75 else
76 {
77 return error(GL_INVALID_VALUE);
78 }
79 }
80
81 if (!shaderObject)
82 {
83 if (context->getProgram(shader))
84 {
85 return error(GL_INVALID_OPERATION);
86 }
87 else
88 {
89 return error(GL_INVALID_VALUE);
90 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000091 }
92
93 if (!programObject->attachShader(shaderObject))
94 {
95 return error(GL_INVALID_OPERATION);
96 }
97 }
98 }
99 catch(std::bad_alloc&)
100 {
101 return error(GL_OUT_OF_MEMORY);
102 }
103}
104
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000105void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000106{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000107 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108
109 try
110 {
111 if (index >= gl::MAX_VERTEX_ATTRIBS)
112 {
113 return error(GL_INVALID_VALUE);
114 }
115
116 gl::Context *context = gl::getContext();
117
118 if (context)
119 {
120 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000121
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000122 if (!programObject)
123 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000124 if (context->getShader(program))
125 {
126 return error(GL_INVALID_OPERATION);
127 }
128 else
129 {
130 return error(GL_INVALID_VALUE);
131 }
132 }
133
134 if (strncmp(name, "gl_", 3) == 0)
135 {
136 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137 }
138
139 programObject->bindAttributeLocation(index, name);
140 }
141 }
142 catch(std::bad_alloc&)
143 {
144 return error(GL_OUT_OF_MEMORY);
145 }
146}
147
148void __stdcall glBindBuffer(GLenum target, GLuint buffer)
149{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000150 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000151
152 try
153 {
154 gl::Context *context = gl::getContext();
155
156 if (context)
157 {
158 switch (target)
159 {
160 case GL_ARRAY_BUFFER:
161 context->bindArrayBuffer(buffer);
162 return;
163 case GL_ELEMENT_ARRAY_BUFFER:
164 context->bindElementArrayBuffer(buffer);
165 return;
166 default:
167 return error(GL_INVALID_ENUM);
168 }
169 }
170 }
171 catch(std::bad_alloc&)
172 {
173 return error(GL_OUT_OF_MEMORY);
174 }
175}
176
177void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
178{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000179 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000180
181 try
182 {
183 if (target != GL_FRAMEBUFFER)
184 {
185 return error(GL_INVALID_ENUM);
186 }
187
188 gl::Context *context = gl::getContext();
189
190 if (context)
191 {
192 context->bindFramebuffer(framebuffer);
193 }
194 }
195 catch(std::bad_alloc&)
196 {
197 return error(GL_OUT_OF_MEMORY);
198 }
199}
200
201void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
202{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000203 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204
205 try
206 {
207 if (target != GL_RENDERBUFFER)
208 {
209 return error(GL_INVALID_ENUM);
210 }
211
212 gl::Context *context = gl::getContext();
213
214 if (context)
215 {
216 context->bindRenderbuffer(renderbuffer);
217 }
218 }
219 catch(std::bad_alloc&)
220 {
221 return error(GL_OUT_OF_MEMORY);
222 }
223}
224
225void __stdcall glBindTexture(GLenum target, GLuint texture)
226{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000227 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228
229 try
230 {
231 gl::Context *context = gl::getContext();
232
233 if (context)
234 {
235 gl::Texture *textureObject = context->getTexture(texture);
236
237 if (textureObject && textureObject->getTarget() != target && texture != 0)
238 {
239 return error(GL_INVALID_OPERATION);
240 }
241
242 switch (target)
243 {
244 case GL_TEXTURE_2D:
245 context->bindTexture2D(texture);
246 return;
247 case GL_TEXTURE_CUBE_MAP:
248 context->bindTextureCubeMap(texture);
249 return;
250 default:
251 return error(GL_INVALID_ENUM);
252 }
253 }
254 }
255 catch(std::bad_alloc&)
256 {
257 return error(GL_OUT_OF_MEMORY);
258 }
259}
260
261void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
262{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000263 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
264 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000265
266 try
267 {
268 gl::Context* context = gl::getContext();
269
270 if (context)
271 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000272 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000273 }
274 }
275 catch(std::bad_alloc&)
276 {
277 return error(GL_OUT_OF_MEMORY);
278 }
279}
280
281void __stdcall glBlendEquation(GLenum mode)
282{
283 glBlendEquationSeparate(mode, mode);
284}
285
286void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
287{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000288 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000289
290 try
291 {
292 switch (modeRGB)
293 {
294 case GL_FUNC_ADD:
295 case GL_FUNC_SUBTRACT:
296 case GL_FUNC_REVERSE_SUBTRACT:
297 break;
298 default:
299 return error(GL_INVALID_ENUM);
300 }
301
302 switch (modeAlpha)
303 {
304 case GL_FUNC_ADD:
305 case GL_FUNC_SUBTRACT:
306 case GL_FUNC_REVERSE_SUBTRACT:
307 break;
308 default:
309 return error(GL_INVALID_ENUM);
310 }
311
312 gl::Context *context = gl::getContext();
313
314 if (context)
315 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000316 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000317 }
318 }
319 catch(std::bad_alloc&)
320 {
321 return error(GL_OUT_OF_MEMORY);
322 }
323}
324
325void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
326{
327 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
328}
329
330void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
331{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000332 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
333 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000334
335 try
336 {
337 switch (srcRGB)
338 {
339 case GL_ZERO:
340 case GL_ONE:
341 case GL_SRC_COLOR:
342 case GL_ONE_MINUS_SRC_COLOR:
343 case GL_DST_COLOR:
344 case GL_ONE_MINUS_DST_COLOR:
345 case GL_SRC_ALPHA:
346 case GL_ONE_MINUS_SRC_ALPHA:
347 case GL_DST_ALPHA:
348 case GL_ONE_MINUS_DST_ALPHA:
349 case GL_CONSTANT_COLOR:
350 case GL_ONE_MINUS_CONSTANT_COLOR:
351 case GL_CONSTANT_ALPHA:
352 case GL_ONE_MINUS_CONSTANT_ALPHA:
353 case GL_SRC_ALPHA_SATURATE:
354 break;
355 default:
356 return error(GL_INVALID_ENUM);
357 }
358
359 switch (dstRGB)
360 {
361 case GL_ZERO:
362 case GL_ONE:
363 case GL_SRC_COLOR:
364 case GL_ONE_MINUS_SRC_COLOR:
365 case GL_DST_COLOR:
366 case GL_ONE_MINUS_DST_COLOR:
367 case GL_SRC_ALPHA:
368 case GL_ONE_MINUS_SRC_ALPHA:
369 case GL_DST_ALPHA:
370 case GL_ONE_MINUS_DST_ALPHA:
371 case GL_CONSTANT_COLOR:
372 case GL_ONE_MINUS_CONSTANT_COLOR:
373 case GL_CONSTANT_ALPHA:
374 case GL_ONE_MINUS_CONSTANT_ALPHA:
375 break;
376 default:
377 return error(GL_INVALID_ENUM);
378 }
379
380 switch (srcAlpha)
381 {
382 case GL_ZERO:
383 case GL_ONE:
384 case GL_SRC_COLOR:
385 case GL_ONE_MINUS_SRC_COLOR:
386 case GL_DST_COLOR:
387 case GL_ONE_MINUS_DST_COLOR:
388 case GL_SRC_ALPHA:
389 case GL_ONE_MINUS_SRC_ALPHA:
390 case GL_DST_ALPHA:
391 case GL_ONE_MINUS_DST_ALPHA:
392 case GL_CONSTANT_COLOR:
393 case GL_ONE_MINUS_CONSTANT_COLOR:
394 case GL_CONSTANT_ALPHA:
395 case GL_ONE_MINUS_CONSTANT_ALPHA:
396 case GL_SRC_ALPHA_SATURATE:
397 break;
398 default:
399 return error(GL_INVALID_ENUM);
400 }
401
402 switch (dstAlpha)
403 {
404 case GL_ZERO:
405 case GL_ONE:
406 case GL_SRC_COLOR:
407 case GL_ONE_MINUS_SRC_COLOR:
408 case GL_DST_COLOR:
409 case GL_ONE_MINUS_DST_COLOR:
410 case GL_SRC_ALPHA:
411 case GL_ONE_MINUS_SRC_ALPHA:
412 case GL_DST_ALPHA:
413 case GL_ONE_MINUS_DST_ALPHA:
414 case GL_CONSTANT_COLOR:
415 case GL_ONE_MINUS_CONSTANT_COLOR:
416 case GL_CONSTANT_ALPHA:
417 case GL_ONE_MINUS_CONSTANT_ALPHA:
418 break;
419 default:
420 return error(GL_INVALID_ENUM);
421 }
422
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000423 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
424 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
425
426 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
427 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
428
429 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000430 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000431 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
432 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000433 }
434
435 gl::Context *context = gl::getContext();
436
437 if (context)
438 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000439 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000440 }
441 }
442 catch(std::bad_alloc&)
443 {
444 return error(GL_OUT_OF_MEMORY);
445 }
446}
447
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000448void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000449{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000450 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000451 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000452
453 try
454 {
455 if (size < 0)
456 {
457 return error(GL_INVALID_VALUE);
458 }
459
460 switch (usage)
461 {
462 case GL_STREAM_DRAW:
463 case GL_STATIC_DRAW:
464 case GL_DYNAMIC_DRAW:
465 break;
466 default:
467 return error(GL_INVALID_ENUM);
468 }
469
470 gl::Context *context = gl::getContext();
471
472 if (context)
473 {
474 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000475
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000476 switch (target)
477 {
478 case GL_ARRAY_BUFFER:
479 buffer = context->getArrayBuffer();
480 break;
481 case GL_ELEMENT_ARRAY_BUFFER:
482 buffer = context->getElementArrayBuffer();
483 break;
484 default:
485 return error(GL_INVALID_ENUM);
486 }
487
488 if (!buffer)
489 {
490 return error(GL_INVALID_OPERATION);
491 }
492
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000493 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000494 }
495 }
496 catch(std::bad_alloc&)
497 {
498 return error(GL_OUT_OF_MEMORY);
499 }
500}
501
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000502void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000503{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000504 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000505 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000506
507 try
508 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000509 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000510 {
511 return error(GL_INVALID_VALUE);
512 }
513
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000514 if (data == NULL)
515 {
516 return;
517 }
518
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000519 gl::Context *context = gl::getContext();
520
521 if (context)
522 {
523 gl::Buffer *buffer;
524
525 switch (target)
526 {
527 case GL_ARRAY_BUFFER:
528 buffer = context->getArrayBuffer();
529 break;
530 case GL_ELEMENT_ARRAY_BUFFER:
531 buffer = context->getElementArrayBuffer();
532 break;
533 default:
534 return error(GL_INVALID_ENUM);
535 }
536
537 if (!buffer)
538 {
539 return error(GL_INVALID_OPERATION);
540 }
541
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000542 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000543 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000544 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000545 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000546
547 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000548 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000549 }
550 catch(std::bad_alloc&)
551 {
552 return error(GL_OUT_OF_MEMORY);
553 }
554}
555
556GLenum __stdcall glCheckFramebufferStatus(GLenum target)
557{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000558 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000559
560 try
561 {
562 if (target != GL_FRAMEBUFFER)
563 {
564 return error(GL_INVALID_ENUM, 0);
565 }
566
567 gl::Context *context = gl::getContext();
568
569 if (context)
570 {
571 gl::Framebuffer *framebuffer = context->getFramebuffer();
572
573 return framebuffer->completeness();
574 }
575 }
576 catch(std::bad_alloc&)
577 {
578 return error(GL_OUT_OF_MEMORY, 0);
579 }
580
581 return 0;
582}
583
584void __stdcall glClear(GLbitfield mask)
585{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000586 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000587
588 try
589 {
590 gl::Context *context = gl::getContext();
591
592 if (context)
593 {
594 context->clear(mask);
595 }
596 }
597 catch(std::bad_alloc&)
598 {
599 return error(GL_OUT_OF_MEMORY);
600 }
601}
602
603void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
604{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000605 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
606 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000607
608 try
609 {
610 gl::Context *context = gl::getContext();
611
612 if (context)
613 {
614 context->setClearColor(red, green, blue, alpha);
615 }
616 }
617 catch(std::bad_alloc&)
618 {
619 return error(GL_OUT_OF_MEMORY);
620 }
621}
622
623void __stdcall glClearDepthf(GLclampf depth)
624{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000625 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000626
627 try
628 {
629 gl::Context *context = gl::getContext();
630
631 if (context)
632 {
633 context->setClearDepth(depth);
634 }
635 }
636 catch(std::bad_alloc&)
637 {
638 return error(GL_OUT_OF_MEMORY);
639 }
640}
641
642void __stdcall glClearStencil(GLint s)
643{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000644 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000645
646 try
647 {
648 gl::Context *context = gl::getContext();
649
650 if (context)
651 {
652 context->setClearStencil(s);
653 }
654 }
655 catch(std::bad_alloc&)
656 {
657 return error(GL_OUT_OF_MEMORY);
658 }
659}
660
661void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
662{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000663 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
664 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000665
666 try
667 {
668 gl::Context *context = gl::getContext();
669
670 if (context)
671 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000672 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000673 }
674 }
675 catch(std::bad_alloc&)
676 {
677 return error(GL_OUT_OF_MEMORY);
678 }
679}
680
681void __stdcall glCompileShader(GLuint shader)
682{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000683 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000684
685 try
686 {
687 gl::Context *context = gl::getContext();
688
689 if (context)
690 {
691 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000692
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000693 if (!shaderObject)
694 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000695 if (context->getProgram(shader))
696 {
697 return error(GL_INVALID_OPERATION);
698 }
699 else
700 {
701 return error(GL_INVALID_VALUE);
702 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000703 }
704
705 shaderObject->compile();
706 }
707 }
708 catch(std::bad_alloc&)
709 {
710 return error(GL_OUT_OF_MEMORY);
711 }
712}
713
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000714void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
715 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000716{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000717 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000718 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000719 target, level, internalformat, width, height, border, imageSize, data);
720
721 try
722 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000723 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000724 {
725 return error(GL_INVALID_ENUM);
726 }
727
728 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000729 {
730 return error(GL_INVALID_VALUE);
731 }
732
daniel@transgaming.com41430492010-03-11 20:36:18 +0000733 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
734 {
735 return error(GL_INVALID_VALUE);
736 }
737
738 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000739 }
740 catch(std::bad_alloc&)
741 {
742 return error(GL_OUT_OF_MEMORY);
743 }
744}
745
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000746void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
747 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000749 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
750 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000751 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000752 target, level, xoffset, yoffset, width, height, format, imageSize, data);
753
754 try
755 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000756 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000757 {
758 return error(GL_INVALID_ENUM);
759 }
760
761 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000762 {
763 return error(GL_INVALID_VALUE);
764 }
765
daniel@transgaming.com41430492010-03-11 20:36:18 +0000766 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
767 {
768 return error(GL_INVALID_VALUE);
769 }
770
771 if (xoffset != 0 || yoffset != 0)
772 {
773 return error(GL_INVALID_OPERATION);
774 }
775
776 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000777 }
778 catch(std::bad_alloc&)
779 {
780 return error(GL_OUT_OF_MEMORY);
781 }
782}
783
784void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
785{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000786 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
787 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000788 target, level, internalformat, x, y, width, height, border);
789
790 try
791 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000792 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000793 {
794 return error(GL_INVALID_VALUE);
795 }
796
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000797 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
798 {
799 return error(GL_INVALID_VALUE);
800 }
801
802 switch (target)
803 {
804 case GL_TEXTURE_2D:
805 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
806 {
807 return error(GL_INVALID_VALUE);
808 }
809 break;
810 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
811 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
812 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
813 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
814 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
815 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +0000816 if (width != height)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000817 {
818 return error(GL_INVALID_VALUE);
819 }
820
821 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
822 {
823 return error(GL_INVALID_VALUE);
824 }
825 break;
826 default:
827 return error(GL_INVALID_ENUM);
828 }
829
830 switch (internalformat)
831 {
832 case GL_ALPHA:
833 case GL_LUMINANCE:
834 case GL_LUMINANCE_ALPHA:
835 case GL_RGB:
836 case GL_RGBA:
837 break;
838 default:
839 return error(GL_INVALID_VALUE);
840 }
841
842 if (border != 0)
843 {
844 return error(GL_INVALID_VALUE);
845 }
846
847 gl::Context *context = gl::getContext();
848
849 if (context)
850 {
daniel@transgaming.combbc57792010-07-28 19:21:05 +0000851 gl::Framebuffer *framebuffer = context->getFramebuffer();
852 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
853 {
854 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
855 }
856
857 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000858
859 if (target == GL_TEXTURE_2D)
860 {
861 gl::Texture2D *texture = context->getTexture2D();
862
863 if (!texture)
864 {
865 return error(GL_INVALID_OPERATION);
866 }
867
868 texture->copyImage(level, internalformat, x, y, width, height, source);
869 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000870 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000871 {
872 gl::TextureCubeMap *texture = context->getTextureCubeMap();
873
874 if (!texture)
875 {
876 return error(GL_INVALID_OPERATION);
877 }
878
879 texture->copyImage(target, level, internalformat, x, y, width, height, source);
880 }
881 else
882 {
883 UNREACHABLE();
884 }
885 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000886 }
887 catch(std::bad_alloc&)
888 {
889 return error(GL_OUT_OF_MEMORY);
890 }
891}
892
893void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
894{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000895 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
896 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000897 target, level, xoffset, yoffset, x, y, width, height);
898
899 try
900 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000901 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000902 {
903 return error(GL_INVALID_ENUM);
904 }
905
906 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000907 {
908 return error(GL_INVALID_VALUE);
909 }
910
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000911 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
912 {
913 return error(GL_INVALID_VALUE);
914 }
915
916 if (width == 0 || height == 0)
917 {
918 return;
919 }
920
921 gl::Context *context = gl::getContext();
922
923 if (context)
924 {
daniel@transgaming.combbc57792010-07-28 19:21:05 +0000925 gl::Framebuffer *framebuffer = context->getFramebuffer();
926 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
927 {
928 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
929 }
930
931 gl::Renderbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000932
933 if (target == GL_TEXTURE_2D)
934 {
935 gl::Texture2D *texture = context->getTexture2D();
936
937 if (!texture)
938 {
939 return error(GL_INVALID_OPERATION);
940 }
941
942 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
943 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000944 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000945 {
946 gl::TextureCubeMap *texture = context->getTextureCubeMap();
947
948 if (!texture)
949 {
950 return error(GL_INVALID_OPERATION);
951 }
952
953 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
954 }
955 else
956 {
957 UNREACHABLE();
958 }
959 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000960 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000961
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000962 catch(std::bad_alloc&)
963 {
964 return error(GL_OUT_OF_MEMORY);
965 }
966}
967
968GLuint __stdcall glCreateProgram(void)
969{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000970 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000971
972 try
973 {
974 gl::Context *context = gl::getContext();
975
976 if (context)
977 {
978 return context->createProgram();
979 }
980 }
981 catch(std::bad_alloc&)
982 {
983 return error(GL_OUT_OF_MEMORY, 0);
984 }
985
986 return 0;
987}
988
989GLuint __stdcall glCreateShader(GLenum type)
990{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000991 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000992
993 try
994 {
995 gl::Context *context = gl::getContext();
996
997 if (context)
998 {
999 switch (type)
1000 {
1001 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001002 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001003 return context->createShader(type);
1004 default:
1005 return error(GL_INVALID_ENUM, 0);
1006 }
1007 }
1008 }
1009 catch(std::bad_alloc&)
1010 {
1011 return error(GL_OUT_OF_MEMORY, 0);
1012 }
1013
1014 return 0;
1015}
1016
1017void __stdcall glCullFace(GLenum mode)
1018{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001019 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001020
1021 try
1022 {
1023 switch (mode)
1024 {
1025 case GL_FRONT:
1026 case GL_BACK:
1027 case GL_FRONT_AND_BACK:
1028 {
1029 gl::Context *context = gl::getContext();
1030
1031 if (context)
1032 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001033 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001034 }
1035 }
1036 break;
1037 default:
1038 return error(GL_INVALID_ENUM);
1039 }
1040 }
1041 catch(std::bad_alloc&)
1042 {
1043 return error(GL_OUT_OF_MEMORY);
1044 }
1045}
1046
1047void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1048{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001049 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001050
1051 try
1052 {
1053 if (n < 0)
1054 {
1055 return error(GL_INVALID_VALUE);
1056 }
1057
1058 gl::Context *context = gl::getContext();
1059
1060 if (context)
1061 {
1062 for (int i = 0; i < n; i++)
1063 {
1064 context->deleteBuffer(buffers[i]);
1065 }
1066 }
1067 }
1068 catch(std::bad_alloc&)
1069 {
1070 return error(GL_OUT_OF_MEMORY);
1071 }
1072}
1073
1074void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1075{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001076 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001077
1078 try
1079 {
1080 if (n < 0)
1081 {
1082 return error(GL_INVALID_VALUE);
1083 }
1084
1085 gl::Context *context = gl::getContext();
1086
1087 if (context)
1088 {
1089 for (int i = 0; i < n; i++)
1090 {
1091 if (framebuffers[i] != 0)
1092 {
1093 context->deleteFramebuffer(framebuffers[i]);
1094 }
1095 }
1096 }
1097 }
1098 catch(std::bad_alloc&)
1099 {
1100 return error(GL_OUT_OF_MEMORY);
1101 }
1102}
1103
1104void __stdcall glDeleteProgram(GLuint program)
1105{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001106 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001107
1108 try
1109 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001110 if (program == 0)
1111 {
1112 return;
1113 }
1114
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001115 gl::Context *context = gl::getContext();
1116
1117 if (context)
1118 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001119 if (!context->getProgram(program))
1120 {
1121 if(context->getShader(program))
1122 {
1123 return error(GL_INVALID_OPERATION);
1124 }
1125 else
1126 {
1127 return error(GL_INVALID_VALUE);
1128 }
1129 }
1130
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001131 context->deleteProgram(program);
1132 }
1133 }
1134 catch(std::bad_alloc&)
1135 {
1136 return error(GL_OUT_OF_MEMORY);
1137 }
1138}
1139
1140void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1141{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001142 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001143
1144 try
1145 {
1146 if (n < 0)
1147 {
1148 return error(GL_INVALID_VALUE);
1149 }
1150
1151 gl::Context *context = gl::getContext();
1152
1153 if (context)
1154 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001155 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001156 {
1157 context->deleteRenderbuffer(renderbuffers[i]);
1158 }
1159 }
1160 }
1161 catch(std::bad_alloc&)
1162 {
1163 return error(GL_OUT_OF_MEMORY);
1164 }
1165}
1166
1167void __stdcall glDeleteShader(GLuint shader)
1168{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001169 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001170
1171 try
1172 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001173 if (shader == 0)
1174 {
1175 return;
1176 }
1177
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001178 gl::Context *context = gl::getContext();
1179
1180 if (context)
1181 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001182 if (!context->getShader(shader))
1183 {
1184 if(context->getProgram(shader))
1185 {
1186 return error(GL_INVALID_OPERATION);
1187 }
1188 else
1189 {
1190 return error(GL_INVALID_VALUE);
1191 }
1192 }
1193
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001194 context->deleteShader(shader);
1195 }
1196 }
1197 catch(std::bad_alloc&)
1198 {
1199 return error(GL_OUT_OF_MEMORY);
1200 }
1201}
1202
1203void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1204{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001205 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001206
1207 try
1208 {
1209 if (n < 0)
1210 {
1211 return error(GL_INVALID_VALUE);
1212 }
1213
1214 gl::Context *context = gl::getContext();
1215
1216 if (context)
1217 {
1218 for (int i = 0; i < n; i++)
1219 {
1220 if (textures[i] != 0)
1221 {
1222 context->deleteTexture(textures[i]);
1223 }
1224 }
1225 }
1226 }
1227 catch(std::bad_alloc&)
1228 {
1229 return error(GL_OUT_OF_MEMORY);
1230 }
1231}
1232
1233void __stdcall glDepthFunc(GLenum func)
1234{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001235 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001236
1237 try
1238 {
1239 switch (func)
1240 {
1241 case GL_NEVER:
1242 case GL_ALWAYS:
1243 case GL_LESS:
1244 case GL_LEQUAL:
1245 case GL_EQUAL:
1246 case GL_GREATER:
1247 case GL_GEQUAL:
1248 case GL_NOTEQUAL:
1249 break;
1250 default:
1251 return error(GL_INVALID_ENUM);
1252 }
1253
1254 gl::Context *context = gl::getContext();
1255
1256 if (context)
1257 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001258 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001259 }
1260 }
1261 catch(std::bad_alloc&)
1262 {
1263 return error(GL_OUT_OF_MEMORY);
1264 }
1265}
1266
1267void __stdcall glDepthMask(GLboolean flag)
1268{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001269 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001270
1271 try
1272 {
1273 gl::Context *context = gl::getContext();
1274
1275 if (context)
1276 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001277 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001278 }
1279 }
1280 catch(std::bad_alloc&)
1281 {
1282 return error(GL_OUT_OF_MEMORY);
1283 }
1284}
1285
1286void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1287{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001288 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001289
1290 try
1291 {
1292 gl::Context *context = gl::getContext();
1293
1294 if (context)
1295 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001296 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001297 }
1298 }
1299 catch(std::bad_alloc&)
1300 {
1301 return error(GL_OUT_OF_MEMORY);
1302 }
1303}
1304
1305void __stdcall glDetachShader(GLuint program, GLuint shader)
1306{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001307 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001308
1309 try
1310 {
1311 gl::Context *context = gl::getContext();
1312
1313 if (context)
1314 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001315
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001316 gl::Program *programObject = context->getProgram(program);
1317 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001318
1319 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001320 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001321 gl::Shader *shaderByProgramHandle;
1322 shaderByProgramHandle = context->getShader(program);
1323 if (!shaderByProgramHandle)
1324 {
1325 return error(GL_INVALID_VALUE);
1326 }
1327 else
1328 {
1329 return error(GL_INVALID_OPERATION);
1330 }
1331 }
1332
1333 if (!shaderObject)
1334 {
1335 gl::Program *programByShaderHandle = context->getProgram(shader);
1336 if (!programByShaderHandle)
1337 {
1338 return error(GL_INVALID_VALUE);
1339 }
1340 else
1341 {
1342 return error(GL_INVALID_OPERATION);
1343 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001344 }
1345
1346 if (!programObject->detachShader(shaderObject))
1347 {
1348 return error(GL_INVALID_OPERATION);
1349 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001350 }
1351 }
1352 catch(std::bad_alloc&)
1353 {
1354 return error(GL_OUT_OF_MEMORY);
1355 }
1356}
1357
1358void __stdcall glDisable(GLenum cap)
1359{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001360 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001361
1362 try
1363 {
1364 gl::Context *context = gl::getContext();
1365
1366 if (context)
1367 {
1368 switch (cap)
1369 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001370 case GL_CULL_FACE: context->setCullFace(false); break;
1371 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1372 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1373 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1374 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1375 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1376 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1377 case GL_BLEND: context->setBlend(false); break;
1378 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001379 default:
1380 return error(GL_INVALID_ENUM);
1381 }
1382 }
1383 }
1384 catch(std::bad_alloc&)
1385 {
1386 return error(GL_OUT_OF_MEMORY);
1387 }
1388}
1389
1390void __stdcall glDisableVertexAttribArray(GLuint index)
1391{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001392 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001393
1394 try
1395 {
1396 if (index >= gl::MAX_VERTEX_ATTRIBS)
1397 {
1398 return error(GL_INVALID_VALUE);
1399 }
1400
1401 gl::Context *context = gl::getContext();
1402
1403 if (context)
1404 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001405 context->setVertexAttribEnabled(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001406 }
1407 }
1408 catch(std::bad_alloc&)
1409 {
1410 return error(GL_OUT_OF_MEMORY);
1411 }
1412}
1413
1414void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1415{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001416 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001417
1418 try
1419 {
1420 if (count < 0 || first < 0)
1421 {
1422 return error(GL_INVALID_VALUE);
1423 }
1424
1425 gl::Context *context = gl::getContext();
1426
1427 if (context)
1428 {
1429 context->drawArrays(mode, first, count);
1430 }
1431 }
1432 catch(std::bad_alloc&)
1433 {
1434 return error(GL_OUT_OF_MEMORY);
1435 }
1436}
1437
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001438void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001439{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001440 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 +00001441 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001442
1443 try
1444 {
1445 if (count < 0)
1446 {
1447 return error(GL_INVALID_VALUE);
1448 }
1449
1450 switch (type)
1451 {
1452 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001453 case GL_UNSIGNED_SHORT:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00001454 case GL_UNSIGNED_INT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001455 break;
1456 default:
1457 return error(GL_INVALID_ENUM);
1458 }
1459
1460 gl::Context *context = gl::getContext();
1461
1462 if (context)
1463 {
1464 context->drawElements(mode, count, type, indices);
1465 }
1466 }
1467 catch(std::bad_alloc&)
1468 {
1469 return error(GL_OUT_OF_MEMORY);
1470 }
1471}
1472
1473void __stdcall glEnable(GLenum cap)
1474{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001475 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001476
1477 try
1478 {
1479 gl::Context *context = gl::getContext();
1480
1481 if (context)
1482 {
1483 switch (cap)
1484 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001485 case GL_CULL_FACE: context->setCullFace(true); break;
1486 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1487 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1488 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1489 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1490 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1491 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1492 case GL_BLEND: context->setBlend(true); break;
1493 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001494 default:
1495 return error(GL_INVALID_ENUM);
1496 }
1497 }
1498 }
1499 catch(std::bad_alloc&)
1500 {
1501 return error(GL_OUT_OF_MEMORY);
1502 }
1503}
1504
1505void __stdcall glEnableVertexAttribArray(GLuint index)
1506{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001507 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001508
1509 try
1510 {
1511 if (index >= gl::MAX_VERTEX_ATTRIBS)
1512 {
1513 return error(GL_INVALID_VALUE);
1514 }
1515
1516 gl::Context *context = gl::getContext();
1517
1518 if (context)
1519 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001520 context->setVertexAttribEnabled(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001521 }
1522 }
1523 catch(std::bad_alloc&)
1524 {
1525 return error(GL_OUT_OF_MEMORY);
1526 }
1527}
1528
1529void __stdcall glFinish(void)
1530{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001531 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001532
1533 try
1534 {
1535 gl::Context *context = gl::getContext();
1536
1537 if (context)
1538 {
1539 context->finish();
1540 }
1541 }
1542 catch(std::bad_alloc&)
1543 {
1544 return error(GL_OUT_OF_MEMORY);
1545 }
1546}
1547
1548void __stdcall glFlush(void)
1549{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001550 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001551
1552 try
1553 {
1554 gl::Context *context = gl::getContext();
1555
1556 if (context)
1557 {
1558 context->flush();
1559 }
1560 }
1561 catch(std::bad_alloc&)
1562 {
1563 return error(GL_OUT_OF_MEMORY);
1564 }
1565}
1566
1567void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1568{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001569 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1570 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001571
1572 try
1573 {
1574 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1575 {
1576 return error(GL_INVALID_ENUM);
1577 }
1578
1579 gl::Context *context = gl::getContext();
1580
1581 if (context)
1582 {
1583 gl::Framebuffer *framebuffer = context->getFramebuffer();
1584
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001585 if (context->getFramebufferHandle() == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001586 {
1587 return error(GL_INVALID_OPERATION);
1588 }
1589
1590 switch (attachment)
1591 {
1592 case GL_COLOR_ATTACHMENT0:
1593 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1594 break;
1595 case GL_DEPTH_ATTACHMENT:
1596 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1597 break;
1598 case GL_STENCIL_ATTACHMENT:
1599 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1600 break;
1601 default:
1602 return error(GL_INVALID_ENUM);
1603 }
1604 }
1605 }
1606 catch(std::bad_alloc&)
1607 {
1608 return error(GL_OUT_OF_MEMORY);
1609 }
1610}
1611
1612void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1613{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001614 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1615 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001616
1617 try
1618 {
1619 if (target != GL_FRAMEBUFFER)
1620 {
1621 return error(GL_INVALID_ENUM);
1622 }
1623
1624 switch (attachment)
1625 {
1626 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001627 case GL_DEPTH_ATTACHMENT:
1628 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001629 break;
1630 default:
1631 return error(GL_INVALID_ENUM);
1632 }
1633
1634 gl::Context *context = gl::getContext();
1635
1636 if (context)
1637 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001638 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001639 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001640 textarget = GL_NONE;
1641 }
1642 else
1643 {
1644 gl::Texture *tex = context->getTexture(texture);
1645
1646 if (tex == NULL)
1647 {
1648 return error(GL_INVALID_OPERATION);
1649 }
1650
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001651 switch (textarget)
1652 {
1653 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001654 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001655 {
1656 return error(GL_INVALID_OPERATION);
1657 }
1658 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001659
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001660 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001661 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001662 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001663 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001664 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001665 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001666 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1667 {
1668 return error(GL_INVALID_OPERATION);
1669 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001670 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001671
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001672 default:
1673 return error(GL_INVALID_ENUM);
1674 }
1675
1676 if (level != 0)
1677 {
1678 return error(GL_INVALID_VALUE);
1679 }
1680 }
1681
1682 gl::Framebuffer *framebuffer = context->getFramebuffer();
1683
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001684 if (context->getFramebufferHandle() == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001685 {
1686 return error(GL_INVALID_OPERATION);
1687 }
1688
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001689 switch (attachment)
1690 {
1691 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
1692 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
1693 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
1694 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001695 }
1696 }
1697 catch(std::bad_alloc&)
1698 {
1699 return error(GL_OUT_OF_MEMORY);
1700 }
1701}
1702
1703void __stdcall glFrontFace(GLenum mode)
1704{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001705 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001706
1707 try
1708 {
1709 switch (mode)
1710 {
1711 case GL_CW:
1712 case GL_CCW:
1713 {
1714 gl::Context *context = gl::getContext();
1715
1716 if (context)
1717 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001718 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001719 }
1720 }
1721 break;
1722 default:
1723 return error(GL_INVALID_ENUM);
1724 }
1725 }
1726 catch(std::bad_alloc&)
1727 {
1728 return error(GL_OUT_OF_MEMORY);
1729 }
1730}
1731
1732void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1733{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001734 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001735
1736 try
1737 {
1738 if (n < 0)
1739 {
1740 return error(GL_INVALID_VALUE);
1741 }
1742
1743 gl::Context *context = gl::getContext();
1744
1745 if (context)
1746 {
1747 for (int i = 0; i < n; i++)
1748 {
1749 buffers[i] = context->createBuffer();
1750 }
1751 }
1752 }
1753 catch(std::bad_alloc&)
1754 {
1755 return error(GL_OUT_OF_MEMORY);
1756 }
1757}
1758
1759void __stdcall glGenerateMipmap(GLenum target)
1760{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001761 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001762
1763 try
1764 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00001765 gl::Context *context = gl::getContext();
1766
1767 if (context)
1768 {
1769 gl::Texture *texture;
1770
1771 switch (target)
1772 {
1773 case GL_TEXTURE_2D:
1774 texture = context->getTexture2D();
1775 break;
1776
1777 case GL_TEXTURE_CUBE_MAP:
1778 texture = context->getTextureCubeMap();
1779 break;
1780
1781 default:
1782 return error(GL_INVALID_ENUM);
1783 }
1784
1785 texture->generateMipmaps();
1786 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001787 }
1788 catch(std::bad_alloc&)
1789 {
1790 return error(GL_OUT_OF_MEMORY);
1791 }
1792}
1793
1794void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1795{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001796 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001797
1798 try
1799 {
1800 if (n < 0)
1801 {
1802 return error(GL_INVALID_VALUE);
1803 }
1804
1805 gl::Context *context = gl::getContext();
1806
1807 if (context)
1808 {
1809 for (int i = 0; i < n; i++)
1810 {
1811 framebuffers[i] = context->createFramebuffer();
1812 }
1813 }
1814 }
1815 catch(std::bad_alloc&)
1816 {
1817 return error(GL_OUT_OF_MEMORY);
1818 }
1819}
1820
1821void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1822{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001823 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001824
1825 try
1826 {
1827 if (n < 0)
1828 {
1829 return error(GL_INVALID_VALUE);
1830 }
1831
1832 gl::Context *context = gl::getContext();
1833
1834 if (context)
1835 {
1836 for (int i = 0; i < n; i++)
1837 {
1838 renderbuffers[i] = context->createRenderbuffer();
1839 }
1840 }
1841 }
1842 catch(std::bad_alloc&)
1843 {
1844 return error(GL_OUT_OF_MEMORY);
1845 }
1846}
1847
1848void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1849{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001850 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001851
1852 try
1853 {
1854 if (n < 0)
1855 {
1856 return error(GL_INVALID_VALUE);
1857 }
1858
1859 gl::Context *context = gl::getContext();
1860
1861 if (context)
1862 {
1863 for (int i = 0; i < n; i++)
1864 {
1865 textures[i] = context->createTexture();
1866 }
1867 }
1868 }
1869 catch(std::bad_alloc&)
1870 {
1871 return error(GL_OUT_OF_MEMORY);
1872 }
1873}
1874
daniel@transgaming.com85423182010-04-22 13:35:27 +00001875void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001876{
daniel@transgaming.com85423182010-04-22 13:35:27 +00001877 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
1878 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001879 program, index, bufsize, length, size, type, name);
1880
1881 try
1882 {
1883 if (bufsize < 0)
1884 {
1885 return error(GL_INVALID_VALUE);
1886 }
1887
daniel@transgaming.com85423182010-04-22 13:35:27 +00001888 gl::Context *context = gl::getContext();
1889
1890 if (context)
1891 {
1892 gl::Program *programObject = context->getProgram(program);
1893
1894 if (!programObject)
1895 {
1896 if (context->getShader(program))
1897 {
1898 return error(GL_INVALID_OPERATION);
1899 }
1900 else
1901 {
1902 return error(GL_INVALID_VALUE);
1903 }
1904 }
1905
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001906 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00001907 {
1908 return error(GL_INVALID_VALUE);
1909 }
1910
1911 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
1912 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001913 }
1914 catch(std::bad_alloc&)
1915 {
1916 return error(GL_OUT_OF_MEMORY);
1917 }
1918}
1919
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001920void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001921{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001922 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001923 "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 +00001924 program, index, bufsize, length, size, type, name);
1925
1926 try
1927 {
1928 if (bufsize < 0)
1929 {
1930 return error(GL_INVALID_VALUE);
1931 }
1932
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001933 gl::Context *context = gl::getContext();
1934
1935 if (context)
1936 {
1937 gl::Program *programObject = context->getProgram(program);
1938
1939 if (!programObject)
1940 {
1941 if (context->getShader(program))
1942 {
1943 return error(GL_INVALID_OPERATION);
1944 }
1945 else
1946 {
1947 return error(GL_INVALID_VALUE);
1948 }
1949 }
1950
1951 if (index >= (GLuint)programObject->getActiveUniformCount())
1952 {
1953 return error(GL_INVALID_VALUE);
1954 }
1955
1956 programObject->getActiveUniform(index, bufsize, length, size, type, name);
1957 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001958 }
1959 catch(std::bad_alloc&)
1960 {
1961 return error(GL_OUT_OF_MEMORY);
1962 }
1963}
1964
1965void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1966{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001967 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1968 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001969
1970 try
1971 {
1972 if (maxcount < 0)
1973 {
1974 return error(GL_INVALID_VALUE);
1975 }
1976
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001977 gl::Context *context = gl::getContext();
1978
1979 if (context)
1980 {
1981 gl::Program *programObject = context->getProgram(program);
1982
1983 if (!programObject)
1984 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00001985 if (context->getShader(program))
1986 {
1987 return error(GL_INVALID_OPERATION);
1988 }
1989 else
1990 {
1991 return error(GL_INVALID_VALUE);
1992 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001993 }
1994
1995 return programObject->getAttachedShaders(maxcount, count, shaders);
1996 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001997 }
1998 catch(std::bad_alloc&)
1999 {
2000 return error(GL_OUT_OF_MEMORY);
2001 }
2002}
2003
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002004int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002005{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002006 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002007
2008 try
2009 {
2010 gl::Context *context = gl::getContext();
2011
2012 if (context)
2013 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002014
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002015 gl::Program *programObject = context->getProgram(program);
2016
2017 if (!programObject)
2018 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002019 if (context->getShader(program))
2020 {
2021 return error(GL_INVALID_OPERATION, -1);
2022 }
2023 else
2024 {
2025 return error(GL_INVALID_VALUE, -1);
2026 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002027 }
2028
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002029 if (!programObject->isLinked())
2030 {
2031 return error(GL_INVALID_OPERATION, -1);
2032 }
2033
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002034 return programObject->getAttributeLocation(name);
2035 }
2036 }
2037 catch(std::bad_alloc&)
2038 {
2039 return error(GL_OUT_OF_MEMORY, -1);
2040 }
2041
2042 return -1;
2043}
2044
2045void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2046{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002047 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002048
2049 try
2050 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002051 gl::Context *context = gl::getContext();
2052
2053 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002054 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002055 if (!(context->getBooleanv(pname, params)))
2056 {
2057 GLenum nativeType;
2058 unsigned int numParams = 0;
2059 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2060 return error(GL_INVALID_ENUM);
2061
2062 if (numParams == 0)
2063 return; // it is known that the pname is valid, but there are no parameters to return
2064
2065 if (nativeType == GL_FLOAT)
2066 {
2067 GLfloat *floatParams = NULL;
2068 floatParams = new GLfloat[numParams];
2069
2070 context->getFloatv(pname, floatParams);
2071
2072 for (unsigned int i = 0; i < numParams; ++i)
2073 {
2074 if (floatParams[i] == 0.0f)
2075 params[i] = GL_FALSE;
2076 else
2077 params[i] = GL_TRUE;
2078 }
2079
2080 delete [] floatParams;
2081 }
2082 else if (nativeType == GL_INT)
2083 {
2084 GLint *intParams = NULL;
2085 intParams = new GLint[numParams];
2086
2087 context->getIntegerv(pname, intParams);
2088
2089 for (unsigned int i = 0; i < numParams; ++i)
2090 {
2091 if (intParams[i] == 0)
2092 params[i] = GL_FALSE;
2093 else
2094 params[i] = GL_TRUE;
2095 }
2096
2097 delete [] intParams;
2098 }
2099 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002100 }
2101 }
2102 catch(std::bad_alloc&)
2103 {
2104 return error(GL_OUT_OF_MEMORY);
2105 }
2106}
2107
2108void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2109{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002110 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 +00002111
2112 try
2113 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002114 gl::Context *context = gl::getContext();
2115
2116 if (context)
2117 {
2118 gl::Buffer *buffer;
2119
2120 switch (target)
2121 {
2122 case GL_ARRAY_BUFFER:
2123 buffer = context->getArrayBuffer();
2124 break;
2125 case GL_ELEMENT_ARRAY_BUFFER:
2126 buffer = context->getElementArrayBuffer();
2127 break;
2128 default: return error(GL_INVALID_ENUM);
2129 }
2130
2131 if (!buffer)
2132 {
2133 // A null buffer means that "0" is bound to the requested buffer target
2134 return error(GL_INVALID_OPERATION);
2135 }
2136
2137 switch (pname)
2138 {
2139 case GL_BUFFER_USAGE:
2140 *params = buffer->usage();
2141 break;
2142 case GL_BUFFER_SIZE:
2143 *params = buffer->size();
2144 break;
2145 default: return error(GL_INVALID_ENUM);
2146 }
2147 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002148 }
2149 catch(std::bad_alloc&)
2150 {
2151 return error(GL_OUT_OF_MEMORY);
2152 }
2153}
2154
2155GLenum __stdcall glGetError(void)
2156{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002157 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002158
2159 gl::Context *context = gl::getContext();
2160
2161 if (context)
2162 {
2163 return context->getError();
2164 }
2165
2166 return GL_NO_ERROR;
2167}
2168
2169void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2170{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002171 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002172
2173 try
2174 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002175 gl::Context *context = gl::getContext();
2176
2177 if (context)
2178 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002179 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002180 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002181 GLenum nativeType;
2182 unsigned int numParams = 0;
2183 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2184 return error(GL_INVALID_ENUM);
2185
2186 if (numParams == 0)
2187 return; // it is known that the pname is valid, but that there are no parameters to return.
2188
2189 if (nativeType == GL_BOOL)
2190 {
2191 GLboolean *boolParams = NULL;
2192 boolParams = new GLboolean[numParams];
2193
2194 context->getBooleanv(pname, boolParams);
2195
2196 for (unsigned int i = 0; i < numParams; ++i)
2197 {
2198 if (boolParams[i] == GL_FALSE)
2199 params[i] = 0.0f;
2200 else
2201 params[i] = 1.0f;
2202 }
2203
2204 delete [] boolParams;
2205 }
2206 else if (nativeType == GL_INT)
2207 {
2208 GLint *intParams = NULL;
2209 intParams = new GLint[numParams];
2210
2211 context->getIntegerv(pname, intParams);
2212
2213 for (unsigned int i = 0; i < numParams; ++i)
2214 {
2215 params[i] = (GLfloat)intParams[i];
2216 }
2217
2218 delete [] intParams;
2219 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002220 }
2221 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002222 }
2223 catch(std::bad_alloc&)
2224 {
2225 return error(GL_OUT_OF_MEMORY);
2226 }
2227}
2228
2229void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2230{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002231 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2232 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002233
2234 try
2235 {
2236 gl::Context *context = gl::getContext();
2237
2238 if (context)
2239 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002240 if (context->getFramebufferHandle() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002241 {
2242 return error(GL_INVALID_OPERATION);
2243 }
2244
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002245 if (target != GL_FRAMEBUFFER)
2246 {
2247 return error(GL_INVALID_ENUM);
2248 }
2249
2250 GLenum attachmentType;
2251 GLuint attachmentHandle;
2252 switch (attachment)
2253 {
2254 case GL_COLOR_ATTACHMENT0:
2255 attachmentType = context->getFramebuffer()->getColorbufferType();
2256 attachmentHandle = context->getFramebuffer()->getColorbufferHandle();
2257 break;
2258 case GL_DEPTH_ATTACHMENT:
2259 attachmentType = context->getFramebuffer()->getDepthbufferType();
2260 attachmentHandle = context->getFramebuffer()->getDepthbufferHandle();
2261 break;
2262 case GL_STENCIL_ATTACHMENT:
2263 attachmentType = context->getFramebuffer()->getStencilbufferType();
2264 attachmentHandle = context->getFramebuffer()->getStencilbufferHandle();
2265 break;
2266 default: return error(GL_INVALID_ENUM);
2267 }
2268
2269 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002270 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002271 {
2272 attachmentObjectType = attachmentType;
2273 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002274 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002275 {
2276 attachmentObjectType = GL_TEXTURE;
2277 }
2278 else UNREACHABLE();
2279
2280 switch (pname)
2281 {
2282 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2283 *params = attachmentObjectType;
2284 break;
2285 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2286 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2287 {
2288 *params = attachmentHandle;
2289 }
2290 else
2291 {
2292 return error(GL_INVALID_ENUM);
2293 }
2294 break;
2295 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2296 if (attachmentObjectType == GL_TEXTURE)
2297 {
2298 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2299 }
2300 else
2301 {
2302 return error(GL_INVALID_ENUM);
2303 }
2304 break;
2305 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2306 if (attachmentObjectType == GL_TEXTURE)
2307 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002308 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002309 {
2310 *params = attachmentType;
2311 }
2312 else
2313 {
2314 *params = 0;
2315 }
2316 }
2317 else
2318 {
2319 return error(GL_INVALID_ENUM);
2320 }
2321 break;
2322 default:
2323 return error(GL_INVALID_ENUM);
2324 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002325 }
2326 }
2327 catch(std::bad_alloc&)
2328 {
2329 return error(GL_OUT_OF_MEMORY);
2330 }
2331}
2332
2333void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2334{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002335 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002336
2337 try
2338 {
2339 gl::Context *context = gl::getContext();
2340
2341 if (context)
2342 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002343 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002344 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002345 GLenum nativeType;
2346 unsigned int numParams = 0;
2347 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2348 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002349
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002350 if (numParams == 0)
2351 return; // it is known that pname is valid, but there are no parameters to return
2352
2353 if (nativeType == GL_BOOL)
2354 {
2355 GLboolean *boolParams = NULL;
2356 boolParams = new GLboolean[numParams];
2357
2358 context->getBooleanv(pname, boolParams);
2359
2360 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002361 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002362 if (boolParams[i] == GL_FALSE)
2363 params[i] = 0;
2364 else
2365 params[i] = 1;
2366 }
2367
2368 delete [] boolParams;
2369 }
2370 else if (nativeType == GL_FLOAT)
2371 {
2372 GLfloat *floatParams = NULL;
2373 floatParams = new GLfloat[numParams];
2374
2375 context->getFloatv(pname, floatParams);
2376
2377 for (unsigned int i = 0; i < numParams; ++i)
2378 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002379 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 +00002380 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002381 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002382 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002383 else
2384 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 +00002385 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002386
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002387 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002388 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002389 }
2390 }
2391 }
2392 catch(std::bad_alloc&)
2393 {
2394 return error(GL_OUT_OF_MEMORY);
2395 }
2396}
2397
2398void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2399{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002400 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002401
2402 try
2403 {
2404 gl::Context *context = gl::getContext();
2405
2406 if (context)
2407 {
2408 gl::Program *programObject = context->getProgram(program);
2409
2410 if (!programObject)
2411 {
2412 return error(GL_INVALID_VALUE);
2413 }
2414
2415 switch (pname)
2416 {
2417 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002418 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002419 return;
2420 case GL_LINK_STATUS:
2421 *params = programObject->isLinked();
2422 return;
2423 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002424 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002425 return;
2426 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002427 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002428 return;
2429 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002430 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002431 return;
2432 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002433 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002434 return;
2435 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002436 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002437 return;
2438 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002439 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002440 return;
2441 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002442 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002443 return;
2444 default:
2445 return error(GL_INVALID_ENUM);
2446 }
2447 }
2448 }
2449 catch(std::bad_alloc&)
2450 {
2451 return error(GL_OUT_OF_MEMORY);
2452 }
2453}
2454
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002455void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002456{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002457 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 +00002458 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002459
2460 try
2461 {
2462 if (bufsize < 0)
2463 {
2464 return error(GL_INVALID_VALUE);
2465 }
2466
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002467 gl::Context *context = gl::getContext();
2468
2469 if (context)
2470 {
2471 gl::Program *programObject = context->getProgram(program);
2472
2473 if (!programObject)
2474 {
2475 return error(GL_INVALID_VALUE);
2476 }
2477
2478 programObject->getInfoLog(bufsize, length, infolog);
2479 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002480 }
2481 catch(std::bad_alloc&)
2482 {
2483 return error(GL_OUT_OF_MEMORY);
2484 }
2485}
2486
2487void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2488{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002489 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 +00002490
2491 try
2492 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002493 gl::Context *context = gl::getContext();
2494
2495 if (context)
2496 {
2497 if (target != GL_RENDERBUFFER)
2498 {
2499 return error(GL_INVALID_ENUM);
2500 }
2501
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002502 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002503 {
2504 return error(GL_INVALID_OPERATION);
2505 }
2506
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002507 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002508
2509 switch (pname)
2510 {
2511 case GL_RENDERBUFFER_WIDTH:
2512 *params = renderbuffer->getWidth();
2513 break;
2514 case GL_RENDERBUFFER_HEIGHT:
2515 *params = renderbuffer->getHeight();
2516 break;
2517 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2518 *params = renderbuffer->getFormat();
2519 break;
2520 case GL_RENDERBUFFER_RED_SIZE:
2521 if (renderbuffer->isColorbuffer())
2522 {
2523 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
2524 }
2525 else
2526 {
2527 *params = 0;
2528 }
2529 break;
2530 case GL_RENDERBUFFER_GREEN_SIZE:
2531 if (renderbuffer->isColorbuffer())
2532 {
2533 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
2534 }
2535 else
2536 {
2537 *params = 0;
2538 }
2539 break;
2540 case GL_RENDERBUFFER_BLUE_SIZE:
2541 if (renderbuffer->isColorbuffer())
2542 {
2543 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
2544 }
2545 else
2546 {
2547 *params = 0;
2548 }
2549 break;
2550 case GL_RENDERBUFFER_ALPHA_SIZE:
2551 if (renderbuffer->isColorbuffer())
2552 {
2553 *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
2554 }
2555 else
2556 {
2557 *params = 0;
2558 }
2559 break;
2560 case GL_RENDERBUFFER_DEPTH_SIZE:
2561 if (renderbuffer->isDepthbuffer())
2562 {
2563 *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
2564 }
2565 else
2566 {
2567 *params = 0;
2568 }
2569 break;
2570 case GL_RENDERBUFFER_STENCIL_SIZE:
2571 if (renderbuffer->isStencilbuffer())
2572 {
2573 *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
2574 }
2575 else
2576 {
2577 *params = 0;
2578 }
2579 break;
2580 default:
2581 return error(GL_INVALID_ENUM);
2582 }
2583 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002584 }
2585 catch(std::bad_alloc&)
2586 {
2587 return error(GL_OUT_OF_MEMORY);
2588 }
2589}
2590
2591void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2592{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002593 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002594
2595 try
2596 {
2597 gl::Context *context = gl::getContext();
2598
2599 if (context)
2600 {
2601 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002602
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002603 if (!shaderObject)
2604 {
2605 return error(GL_INVALID_VALUE);
2606 }
2607
2608 switch (pname)
2609 {
2610 case GL_SHADER_TYPE:
2611 *params = shaderObject->getType();
2612 return;
2613 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002614 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002615 return;
2616 case GL_COMPILE_STATUS:
2617 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2618 return;
2619 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002620 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002621 return;
2622 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002623 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002624 return;
2625 default:
2626 return error(GL_INVALID_ENUM);
2627 }
2628 }
2629 }
2630 catch(std::bad_alloc&)
2631 {
2632 return error(GL_OUT_OF_MEMORY);
2633 }
2634}
2635
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002636void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002637{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002638 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 +00002639 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002640
2641 try
2642 {
2643 if (bufsize < 0)
2644 {
2645 return error(GL_INVALID_VALUE);
2646 }
2647
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002648 gl::Context *context = gl::getContext();
2649
2650 if (context)
2651 {
2652 gl::Shader *shaderObject = context->getShader(shader);
2653
2654 if (!shaderObject)
2655 {
2656 return error(GL_INVALID_VALUE);
2657 }
2658
2659 shaderObject->getInfoLog(bufsize, length, infolog);
2660 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002661 }
2662 catch(std::bad_alloc&)
2663 {
2664 return error(GL_OUT_OF_MEMORY);
2665 }
2666}
2667
2668void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2669{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002670 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2671 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002672
2673 try
2674 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002675 switch (shadertype)
2676 {
2677 case GL_VERTEX_SHADER:
2678 case GL_FRAGMENT_SHADER:
2679 break;
2680 default:
2681 return error(GL_INVALID_ENUM);
2682 }
2683
2684 switch (precisiontype)
2685 {
2686 case GL_LOW_FLOAT:
2687 case GL_MEDIUM_FLOAT:
2688 case GL_HIGH_FLOAT:
2689 // Assume IEEE 754 precision
2690 range[0] = 127;
2691 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002692 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002693 break;
2694 case GL_LOW_INT:
2695 case GL_MEDIUM_INT:
2696 case GL_HIGH_INT:
2697 // Some (most) hardware only supports single-precision floating-point numbers,
2698 // which can accurately represent integers up to +/-16777216
2699 range[0] = 24;
2700 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002701 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002702 break;
2703 default:
2704 return error(GL_INVALID_ENUM);
2705 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002706 }
2707 catch(std::bad_alloc&)
2708 {
2709 return error(GL_OUT_OF_MEMORY);
2710 }
2711}
2712
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002713void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002714{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002715 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 +00002716 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002717
2718 try
2719 {
2720 if (bufsize < 0)
2721 {
2722 return error(GL_INVALID_VALUE);
2723 }
2724
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002725 gl::Context *context = gl::getContext();
2726
2727 if (context)
2728 {
2729 gl::Shader *shaderObject = context->getShader(shader);
2730
2731 if (!shaderObject)
2732 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002733 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002734 }
2735
2736 shaderObject->getSource(bufsize, length, source);
2737 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002738 }
2739 catch(std::bad_alloc&)
2740 {
2741 return error(GL_OUT_OF_MEMORY);
2742 }
2743}
2744
2745const GLubyte* __stdcall glGetString(GLenum name)
2746{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002747 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002748
2749 try
2750 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002751 gl::Context *context = gl::getContext();
2752
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002753 switch (name)
2754 {
2755 case GL_VENDOR:
2756 return (GLubyte*)"TransGaming Inc.";
2757 case GL_RENDERER:
2758 return (GLubyte*)"ANGLE";
2759 case GL_VERSION:
2760 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2761 case GL_SHADING_LANGUAGE_VERSION:
2762 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2763 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002764 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002765 default:
2766 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2767 }
2768 }
2769 catch(std::bad_alloc&)
2770 {
2771 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2772 }
2773
2774 return NULL;
2775}
2776
2777void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2778{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002779 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 +00002780
2781 try
2782 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002783 gl::Context *context = gl::getContext();
2784
2785 if (context)
2786 {
2787 gl::Texture *texture;
2788
2789 switch (target)
2790 {
2791 case GL_TEXTURE_2D:
2792 texture = context->getTexture2D();
2793 break;
2794 case GL_TEXTURE_CUBE_MAP:
2795 texture = context->getTextureCubeMap();
2796 break;
2797 default:
2798 return error(GL_INVALID_ENUM);
2799 }
2800
2801 switch (pname)
2802 {
2803 case GL_TEXTURE_MAG_FILTER:
2804 *params = (GLfloat)texture->getMagFilter();
2805 break;
2806 case GL_TEXTURE_MIN_FILTER:
2807 *params = (GLfloat)texture->getMinFilter();
2808 break;
2809 case GL_TEXTURE_WRAP_S:
2810 *params = (GLfloat)texture->getWrapS();
2811 break;
2812 case GL_TEXTURE_WRAP_T:
2813 *params = (GLfloat)texture->getWrapT();
2814 break;
2815 default:
2816 return error(GL_INVALID_ENUM);
2817 }
2818 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002819 }
2820 catch(std::bad_alloc&)
2821 {
2822 return error(GL_OUT_OF_MEMORY);
2823 }
2824}
2825
2826void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2827{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002828 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 +00002829
2830 try
2831 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002832 gl::Context *context = gl::getContext();
2833
2834 if (context)
2835 {
2836 gl::Texture *texture;
2837
2838 switch (target)
2839 {
2840 case GL_TEXTURE_2D:
2841 texture = context->getTexture2D();
2842 break;
2843 case GL_TEXTURE_CUBE_MAP:
2844 texture = context->getTextureCubeMap();
2845 break;
2846 default:
2847 return error(GL_INVALID_ENUM);
2848 }
2849
2850 switch (pname)
2851 {
2852 case GL_TEXTURE_MAG_FILTER:
2853 *params = texture->getMagFilter();
2854 break;
2855 case GL_TEXTURE_MIN_FILTER:
2856 *params = texture->getMinFilter();
2857 break;
2858 case GL_TEXTURE_WRAP_S:
2859 *params = texture->getWrapS();
2860 break;
2861 case GL_TEXTURE_WRAP_T:
2862 *params = texture->getWrapT();
2863 break;
2864 default:
2865 return error(GL_INVALID_ENUM);
2866 }
2867 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002868 }
2869 catch(std::bad_alloc&)
2870 {
2871 return error(GL_OUT_OF_MEMORY);
2872 }
2873}
2874
2875void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2876{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002877 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002878
2879 try
2880 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002881 gl::Context *context = gl::getContext();
2882
2883 if (context)
2884 {
2885 if (program == 0)
2886 {
2887 return error(GL_INVALID_VALUE);
2888 }
2889
2890 gl::Program *programObject = context->getProgram(program);
2891
2892 if (!programObject || !programObject->isLinked())
2893 {
2894 return error(GL_INVALID_OPERATION);
2895 }
2896
2897 if (!programObject->getUniformfv(location, params))
2898 {
2899 return error(GL_INVALID_OPERATION);
2900 }
2901 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002902 }
2903 catch(std::bad_alloc&)
2904 {
2905 return error(GL_OUT_OF_MEMORY);
2906 }
2907}
2908
2909void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2910{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002911 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002912
2913 try
2914 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002915 gl::Context *context = gl::getContext();
2916
2917 if (context)
2918 {
2919 if (program == 0)
2920 {
2921 return error(GL_INVALID_VALUE);
2922 }
2923
2924 gl::Program *programObject = context->getProgram(program);
2925
2926 if (!programObject || !programObject->isLinked())
2927 {
2928 return error(GL_INVALID_OPERATION);
2929 }
2930
2931 if (!programObject)
2932 {
2933 return error(GL_INVALID_OPERATION);
2934 }
2935
2936 if (!programObject->getUniformiv(location, params))
2937 {
2938 return error(GL_INVALID_OPERATION);
2939 }
2940 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002941 }
2942 catch(std::bad_alloc&)
2943 {
2944 return error(GL_OUT_OF_MEMORY);
2945 }
2946}
2947
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002948int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002949{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002950 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002951
2952 try
2953 {
2954 gl::Context *context = gl::getContext();
2955
2956 if (strstr(name, "gl_") == name)
2957 {
2958 return -1;
2959 }
2960
2961 if (context)
2962 {
2963 gl::Program *programObject = context->getProgram(program);
2964
2965 if (!programObject)
2966 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00002967 if (context->getShader(program))
2968 {
2969 return error(GL_INVALID_OPERATION, -1);
2970 }
2971 else
2972 {
2973 return error(GL_INVALID_VALUE, -1);
2974 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002975 }
2976
2977 if (!programObject->isLinked())
2978 {
2979 return error(GL_INVALID_OPERATION, -1);
2980 }
2981
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00002982 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002983 }
2984 }
2985 catch(std::bad_alloc&)
2986 {
2987 return error(GL_OUT_OF_MEMORY, -1);
2988 }
2989
2990 return -1;
2991}
2992
2993void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2994{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002995 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002996
2997 try
2998 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00002999 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003000
daniel@transgaming.come0078962010-04-15 20:45:08 +00003001 if (context)
3002 {
3003 if (index >= gl::MAX_VERTEX_ATTRIBS)
3004 {
3005 return error(GL_INVALID_VALUE);
3006 }
3007
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003008 gl::AttributeState attribState = context->getVertexAttribState(index);
3009
daniel@transgaming.come0078962010-04-15 20:45:08 +00003010 switch (pname)
3011 {
3012 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003013 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003014 break;
3015 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003016 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003017 break;
3018 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003019 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003020 break;
3021 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003022 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003023 break;
3024 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003025 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003026 break;
3027 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003028 *params = (GLfloat)attribState.mBoundBuffer;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003029 break;
3030 case GL_CURRENT_VERTEX_ATTRIB:
3031 for (int i = 0; i < 4; ++i)
3032 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003033 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003034 }
3035 break;
3036 default: return error(GL_INVALID_ENUM);
3037 }
3038 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003039 }
3040 catch(std::bad_alloc&)
3041 {
3042 return error(GL_OUT_OF_MEMORY);
3043 }
3044}
3045
3046void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3047{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003048 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003049
3050 try
3051 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003052 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003053
daniel@transgaming.come0078962010-04-15 20:45:08 +00003054 if (context)
3055 {
3056 if (index >= gl::MAX_VERTEX_ATTRIBS)
3057 {
3058 return error(GL_INVALID_VALUE);
3059 }
3060
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003061 gl::AttributeState attribState = context->getVertexAttribState(index);
3062
daniel@transgaming.come0078962010-04-15 20:45:08 +00003063 switch (pname)
3064 {
3065 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003066 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003067 break;
3068 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003069 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003070 break;
3071 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003072 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003073 break;
3074 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003075 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003076 break;
3077 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003078 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003079 break;
3080 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003081 *params = attribState.mBoundBuffer;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003082 break;
3083 case GL_CURRENT_VERTEX_ATTRIB:
3084 for (int i = 0; i < 4; ++i)
3085 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003086 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003087 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3088 }
3089 break;
3090 default: return error(GL_INVALID_ENUM);
3091 }
3092 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003093 }
3094 catch(std::bad_alloc&)
3095 {
3096 return error(GL_OUT_OF_MEMORY);
3097 }
3098}
3099
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003100void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003101{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003102 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003103
3104 try
3105 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003106 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003107
daniel@transgaming.come0078962010-04-15 20:45:08 +00003108 if (context)
3109 {
3110 if (index >= gl::MAX_VERTEX_ATTRIBS)
3111 {
3112 return error(GL_INVALID_VALUE);
3113 }
3114
3115 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3116 {
3117 return error(GL_INVALID_ENUM);
3118 }
3119
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003120 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003121 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003122 }
3123 catch(std::bad_alloc&)
3124 {
3125 return error(GL_OUT_OF_MEMORY);
3126 }
3127}
3128
3129void __stdcall glHint(GLenum target, GLenum mode)
3130{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003131 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003132
3133 try
3134 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003135 switch (target)
3136 {
3137 case GL_GENERATE_MIPMAP_HINT:
3138 switch (mode)
3139 {
3140 case GL_FASTEST:
3141 case GL_NICEST:
3142 case GL_DONT_CARE:
3143 break;
3144 default:
3145 return error(GL_INVALID_ENUM);
3146 }
3147 break;
3148 default:
3149 return error(GL_INVALID_ENUM);
3150 }
3151
3152 gl::Context *context = gl::getContext();
3153 if (context)
3154 {
3155 if (target == GL_GENERATE_MIPMAP_HINT)
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003156 context->setGenerateMipmapHint(mode);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003157 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003158 }
3159 catch(std::bad_alloc&)
3160 {
3161 return error(GL_OUT_OF_MEMORY);
3162 }
3163}
3164
3165GLboolean __stdcall glIsBuffer(GLuint buffer)
3166{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003167 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003168
3169 try
3170 {
3171 gl::Context *context = gl::getContext();
3172
3173 if (context && buffer)
3174 {
3175 gl::Buffer *bufferObject = context->getBuffer(buffer);
3176
3177 if (bufferObject)
3178 {
3179 return GL_TRUE;
3180 }
3181 }
3182 }
3183 catch(std::bad_alloc&)
3184 {
3185 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3186 }
3187
3188 return GL_FALSE;
3189}
3190
3191GLboolean __stdcall glIsEnabled(GLenum cap)
3192{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003193 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003194
3195 try
3196 {
3197 gl::Context *context = gl::getContext();
3198
3199 if (context)
3200 {
3201 switch (cap)
3202 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003203 case GL_CULL_FACE: return context->isCullFaceEnabled();
3204 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3205 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3206 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3207 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3208 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3209 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3210 case GL_BLEND: return context->isBlendEnabled();
3211 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003212 default:
3213 return error(GL_INVALID_ENUM, false);
3214 }
3215 }
3216 }
3217 catch(std::bad_alloc&)
3218 {
3219 return error(GL_OUT_OF_MEMORY, false);
3220 }
3221
3222 return false;
3223}
3224
3225GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3226{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003227 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003228
3229 try
3230 {
3231 gl::Context *context = gl::getContext();
3232
3233 if (context && framebuffer)
3234 {
3235 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3236
3237 if (framebufferObject)
3238 {
3239 return GL_TRUE;
3240 }
3241 }
3242 }
3243 catch(std::bad_alloc&)
3244 {
3245 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3246 }
3247
3248 return GL_FALSE;
3249}
3250
3251GLboolean __stdcall glIsProgram(GLuint program)
3252{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003253 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003254
3255 try
3256 {
3257 gl::Context *context = gl::getContext();
3258
3259 if (context && program)
3260 {
3261 gl::Program *programObject = context->getProgram(program);
3262
3263 if (programObject)
3264 {
3265 return GL_TRUE;
3266 }
3267 }
3268 }
3269 catch(std::bad_alloc&)
3270 {
3271 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3272 }
3273
3274 return GL_FALSE;
3275}
3276
3277GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3278{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003279 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003280
3281 try
3282 {
3283 gl::Context *context = gl::getContext();
3284
3285 if (context && renderbuffer)
3286 {
3287 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3288
3289 if (renderbufferObject)
3290 {
3291 return GL_TRUE;
3292 }
3293 }
3294 }
3295 catch(std::bad_alloc&)
3296 {
3297 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3298 }
3299
3300 return GL_FALSE;
3301}
3302
3303GLboolean __stdcall glIsShader(GLuint shader)
3304{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003305 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003306
3307 try
3308 {
3309 gl::Context *context = gl::getContext();
3310
3311 if (context && shader)
3312 {
3313 gl::Shader *shaderObject = context->getShader(shader);
3314
3315 if (shaderObject)
3316 {
3317 return GL_TRUE;
3318 }
3319 }
3320 }
3321 catch(std::bad_alloc&)
3322 {
3323 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3324 }
3325
3326 return GL_FALSE;
3327}
3328
3329GLboolean __stdcall glIsTexture(GLuint texture)
3330{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003331 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003332
3333 try
3334 {
3335 gl::Context *context = gl::getContext();
3336
3337 if (context && texture)
3338 {
3339 gl::Texture *textureObject = context->getTexture(texture);
3340
3341 if (textureObject)
3342 {
3343 return GL_TRUE;
3344 }
3345 }
3346 }
3347 catch(std::bad_alloc&)
3348 {
3349 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3350 }
3351
3352 return GL_FALSE;
3353}
3354
3355void __stdcall glLineWidth(GLfloat width)
3356{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003357 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003358
3359 try
3360 {
3361 if (width <= 0.0f)
3362 {
3363 return error(GL_INVALID_VALUE);
3364 }
3365
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003366 gl::Context *context = gl::getContext();
3367
3368 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003369 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003370 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003371 }
3372 }
3373 catch(std::bad_alloc&)
3374 {
3375 return error(GL_OUT_OF_MEMORY);
3376 }
3377}
3378
3379void __stdcall glLinkProgram(GLuint program)
3380{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003381 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003382
3383 try
3384 {
3385 gl::Context *context = gl::getContext();
3386
3387 if (context)
3388 {
3389 gl::Program *programObject = context->getProgram(program);
3390
3391 if (!programObject)
3392 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003393 if (context->getShader(program))
3394 {
3395 return error(GL_INVALID_OPERATION);
3396 }
3397 else
3398 {
3399 return error(GL_INVALID_VALUE);
3400 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003401 }
3402
3403 programObject->link();
3404 }
3405 }
3406 catch(std::bad_alloc&)
3407 {
3408 return error(GL_OUT_OF_MEMORY);
3409 }
3410}
3411
3412void __stdcall glPixelStorei(GLenum pname, GLint param)
3413{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003414 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003415
3416 try
3417 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003418 gl::Context *context = gl::getContext();
3419
3420 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003421 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003422 switch (pname)
3423 {
3424 case GL_UNPACK_ALIGNMENT:
3425 if (param != 1 && param != 2 && param != 4 && param != 8)
3426 {
3427 return error(GL_INVALID_VALUE);
3428 }
3429
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003430 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003431 break;
3432
3433 case GL_PACK_ALIGNMENT:
3434 if (param != 1 && param != 2 && param != 4 && param != 8)
3435 {
3436 return error(GL_INVALID_VALUE);
3437 }
3438
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003439 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003440 break;
3441
3442 default:
3443 return error(GL_INVALID_ENUM);
3444 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003445 }
3446 }
3447 catch(std::bad_alloc&)
3448 {
3449 return error(GL_OUT_OF_MEMORY);
3450 }
3451}
3452
3453void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3454{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003455 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003456
3457 try
3458 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003459 gl::Context *context = gl::getContext();
3460
3461 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003462 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003463 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003464 }
3465 }
3466 catch(std::bad_alloc&)
3467 {
3468 return error(GL_OUT_OF_MEMORY);
3469 }
3470}
3471
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003472void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003473{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003474 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003475 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003476 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003477
3478 try
3479 {
3480 if (width < 0 || height < 0)
3481 {
3482 return error(GL_INVALID_VALUE);
3483 }
3484
3485 switch (format)
3486 {
3487 case GL_RGBA:
3488 switch (type)
3489 {
3490 case GL_UNSIGNED_BYTE:
3491 break;
3492 default:
3493 return error(GL_INVALID_OPERATION);
3494 }
3495 break;
3496 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3497 switch (type)
3498 {
3499 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3500 break;
3501 default:
3502 return error(GL_INVALID_OPERATION);
3503 }
3504 break;
3505 default:
3506 return error(GL_INVALID_OPERATION);
3507 }
3508
3509 gl::Context *context = gl::getContext();
3510
3511 if (context)
3512 {
3513 context->readPixels(x, y, width, height, format, type, pixels);
3514 }
3515 }
3516 catch(std::bad_alloc&)
3517 {
3518 return error(GL_OUT_OF_MEMORY);
3519 }
3520}
3521
3522void __stdcall glReleaseShaderCompiler(void)
3523{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003524 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003525
3526 try
3527 {
3528 gl::Shader::releaseCompiler();
3529 }
3530 catch(std::bad_alloc&)
3531 {
3532 return error(GL_OUT_OF_MEMORY);
3533 }
3534}
3535
3536void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3537{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003538 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3539 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003540
3541 try
3542 {
3543 switch (target)
3544 {
3545 case GL_RENDERBUFFER:
3546 break;
3547 default:
3548 return error(GL_INVALID_ENUM);
3549 }
3550
3551 switch (internalformat)
3552 {
3553 case GL_DEPTH_COMPONENT16:
3554 case GL_RGBA4:
3555 case GL_RGB5_A1:
3556 case GL_RGB565:
3557 case GL_STENCIL_INDEX8:
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003558 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003559 break;
3560 default:
3561 return error(GL_INVALID_ENUM);
3562 }
3563
3564 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3565 {
3566 return error(GL_INVALID_VALUE);
3567 }
3568
3569 gl::Context *context = gl::getContext();
3570
3571 if (context)
3572 {
daniel@transgaming.com5d4c28f2010-05-19 07:14:19 +00003573 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003574 {
3575 return error(GL_INVALID_OPERATION);
3576 }
3577
3578 switch (internalformat)
3579 {
3580 case GL_DEPTH_COMPONENT16:
3581 context->setRenderbuffer(new gl::Depthbuffer(width, height));
3582 break;
3583 case GL_RGBA4:
3584 case GL_RGB5_A1:
3585 case GL_RGB565:
daniel@transgaming.com70d312a2010-04-20 18:52:38 +00003586 context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003587 break;
3588 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00003589 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003590 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003591 case GL_DEPTH24_STENCIL8_OES:
3592 context->setRenderbuffer(new gl::DepthStencilbuffer(width, height));
3593 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003594 default:
3595 return error(GL_INVALID_ENUM);
3596 }
3597 }
3598 }
3599 catch(std::bad_alloc&)
3600 {
3601 return error(GL_OUT_OF_MEMORY);
3602 }
3603}
3604
3605void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3606{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003607 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003608
3609 try
3610 {
3611 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003612
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003613 if (context)
3614 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00003615 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003616 }
3617 }
3618 catch(std::bad_alloc&)
3619 {
3620 return error(GL_OUT_OF_MEMORY);
3621 }
3622}
3623
3624void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3625{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003626 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 +00003627
3628 try
3629 {
3630 if (width < 0 || height < 0)
3631 {
3632 return error(GL_INVALID_VALUE);
3633 }
3634
3635 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003636
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003637 if (context)
3638 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003639 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003640 }
3641 }
3642 catch(std::bad_alloc&)
3643 {
3644 return error(GL_OUT_OF_MEMORY);
3645 }
3646}
3647
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003648void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003650 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003651 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003652 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003653
3654 try
3655 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00003656 // No binary shader formats are supported.
3657 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003658 }
3659 catch(std::bad_alloc&)
3660 {
3661 return error(GL_OUT_OF_MEMORY);
3662 }
3663}
3664
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003665void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003666{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003667 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 +00003668 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003669
3670 try
3671 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003672 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003673 {
3674 return error(GL_INVALID_VALUE);
3675 }
3676
3677 gl::Context *context = gl::getContext();
3678
3679 if (context)
3680 {
3681 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003682
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003683 if (!shaderObject)
3684 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003685 if (context->getProgram(shader))
3686 {
3687 return error(GL_INVALID_OPERATION);
3688 }
3689 else
3690 {
3691 return error(GL_INVALID_VALUE);
3692 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003693 }
3694
3695 shaderObject->setSource(count, string, length);
3696 }
3697 }
3698 catch(std::bad_alloc&)
3699 {
3700 return error(GL_OUT_OF_MEMORY);
3701 }
3702}
3703
3704void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3705{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003706 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003707}
3708
3709void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3710{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003711 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 +00003712
3713 try
3714 {
3715 switch (face)
3716 {
3717 case GL_FRONT:
3718 case GL_BACK:
3719 case GL_FRONT_AND_BACK:
3720 break;
3721 default:
3722 return error(GL_INVALID_ENUM);
3723 }
3724
3725 switch (func)
3726 {
3727 case GL_NEVER:
3728 case GL_ALWAYS:
3729 case GL_LESS:
3730 case GL_LEQUAL:
3731 case GL_EQUAL:
3732 case GL_GEQUAL:
3733 case GL_GREATER:
3734 case GL_NOTEQUAL:
3735 break;
3736 default:
3737 return error(GL_INVALID_ENUM);
3738 }
3739
3740 gl::Context *context = gl::getContext();
3741
3742 if (context)
3743 {
3744 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3745 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003746 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003747 }
3748
3749 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3750 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003751 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003752 }
3753 }
3754 }
3755 catch(std::bad_alloc&)
3756 {
3757 return error(GL_OUT_OF_MEMORY);
3758 }
3759}
3760
3761void __stdcall glStencilMask(GLuint mask)
3762{
3763 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3764}
3765
3766void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3767{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003768 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003769
3770 try
3771 {
3772 switch (face)
3773 {
3774 case GL_FRONT:
3775 case GL_BACK:
3776 case GL_FRONT_AND_BACK:
3777 break;
3778 default:
3779 return error(GL_INVALID_ENUM);
3780 }
3781
3782 gl::Context *context = gl::getContext();
3783
3784 if (context)
3785 {
3786 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3787 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003788 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003789 }
3790
3791 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3792 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003793 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003794 }
3795 }
3796 }
3797 catch(std::bad_alloc&)
3798 {
3799 return error(GL_OUT_OF_MEMORY);
3800 }
3801}
3802
3803void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3804{
3805 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3806}
3807
3808void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3809{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003810 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3811 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003812
3813 try
3814 {
3815 switch (face)
3816 {
3817 case GL_FRONT:
3818 case GL_BACK:
3819 case GL_FRONT_AND_BACK:
3820 break;
3821 default:
3822 return error(GL_INVALID_ENUM);
3823 }
3824
3825 switch (fail)
3826 {
3827 case GL_ZERO:
3828 case GL_KEEP:
3829 case GL_REPLACE:
3830 case GL_INCR:
3831 case GL_DECR:
3832 case GL_INVERT:
3833 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003834 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003835 break;
3836 default:
3837 return error(GL_INVALID_ENUM);
3838 }
3839
3840 switch (zfail)
3841 {
3842 case GL_ZERO:
3843 case GL_KEEP:
3844 case GL_REPLACE:
3845 case GL_INCR:
3846 case GL_DECR:
3847 case GL_INVERT:
3848 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003849 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003850 break;
3851 default:
3852 return error(GL_INVALID_ENUM);
3853 }
3854
3855 switch (zpass)
3856 {
3857 case GL_ZERO:
3858 case GL_KEEP:
3859 case GL_REPLACE:
3860 case GL_INCR:
3861 case GL_DECR:
3862 case GL_INVERT:
3863 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003864 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003865 break;
3866 default:
3867 return error(GL_INVALID_ENUM);
3868 }
3869
3870 gl::Context *context = gl::getContext();
3871
3872 if (context)
3873 {
3874 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3875 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003876 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003877 }
3878
3879 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3880 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003881 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003882 }
3883 }
3884 }
3885 catch(std::bad_alloc&)
3886 {
3887 return error(GL_OUT_OF_MEMORY);
3888 }
3889}
3890
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003891void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3892 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003893{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003894 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 +00003895 "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 +00003896 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003897
3898 try
3899 {
3900 if (level < 0 || width < 0 || height < 0)
3901 {
3902 return error(GL_INVALID_VALUE);
3903 }
3904
3905 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3906 {
3907 return error(GL_INVALID_VALUE);
3908 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003909
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003910 switch (target)
3911 {
3912 case GL_TEXTURE_2D:
3913 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3914 {
3915 return error(GL_INVALID_VALUE);
3916 }
3917 break;
3918 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3919 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3920 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3921 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3922 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3923 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003924 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003925 {
3926 return error(GL_INVALID_VALUE);
3927 }
3928
3929 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3930 {
3931 return error(GL_INVALID_VALUE);
3932 }
3933 break;
3934 default:
3935 return error(GL_INVALID_ENUM);
3936 }
3937
3938 if (internalformat != format)
3939 {
3940 return error(GL_INVALID_OPERATION);
3941 }
3942
3943 switch (internalformat)
3944 {
3945 case GL_ALPHA:
3946 case GL_LUMINANCE:
3947 case GL_LUMINANCE_ALPHA:
3948 switch (type)
3949 {
3950 case GL_UNSIGNED_BYTE:
3951 break;
3952 default:
3953 return error(GL_INVALID_ENUM);
3954 }
3955 break;
3956 case GL_RGB:
3957 switch (type)
3958 {
3959 case GL_UNSIGNED_BYTE:
3960 case GL_UNSIGNED_SHORT_5_6_5:
3961 break;
3962 default:
3963 return error(GL_INVALID_ENUM);
3964 }
3965 break;
3966 case GL_RGBA:
3967 switch (type)
3968 {
3969 case GL_UNSIGNED_BYTE:
3970 case GL_UNSIGNED_SHORT_4_4_4_4:
3971 case GL_UNSIGNED_SHORT_5_5_5_1:
3972 break;
3973 default:
3974 return error(GL_INVALID_ENUM);
3975 }
3976 break;
3977 default:
3978 return error(GL_INVALID_VALUE);
3979 }
3980
3981 if (border != 0)
3982 {
3983 return error(GL_INVALID_VALUE);
3984 }
3985
3986 gl::Context *context = gl::getContext();
3987
3988 if (context)
3989 {
3990 if (target == GL_TEXTURE_2D)
3991 {
3992 gl::Texture2D *texture = context->getTexture2D();
3993
3994 if (!texture)
3995 {
3996 return error(GL_INVALID_OPERATION);
3997 }
3998
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003999 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004000 }
4001 else
4002 {
4003 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4004
4005 if (!texture)
4006 {
4007 return error(GL_INVALID_OPERATION);
4008 }
4009
4010 switch (target)
4011 {
4012 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004013 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004014 break;
4015 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004016 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004017 break;
4018 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004019 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004020 break;
4021 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004022 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004023 break;
4024 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004025 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004026 break;
4027 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004028 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004029 break;
4030 default: UNREACHABLE();
4031 }
4032 }
4033 }
4034 }
4035 catch(std::bad_alloc&)
4036 {
4037 return error(GL_OUT_OF_MEMORY);
4038 }
4039}
4040
4041void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4042{
4043 glTexParameteri(target, pname, (GLint)param);
4044}
4045
4046void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4047{
4048 glTexParameteri(target, pname, (GLint)*params);
4049}
4050
4051void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4052{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004053 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004054
4055 try
4056 {
4057 gl::Context *context = gl::getContext();
4058
4059 if (context)
4060 {
4061 gl::Texture *texture;
4062
4063 switch (target)
4064 {
4065 case GL_TEXTURE_2D:
4066 texture = context->getTexture2D();
4067 break;
4068 case GL_TEXTURE_CUBE_MAP:
4069 texture = context->getTextureCubeMap();
4070 break;
4071 default:
4072 return error(GL_INVALID_ENUM);
4073 }
4074
4075 switch (pname)
4076 {
4077 case GL_TEXTURE_WRAP_S:
4078 if (!texture->setWrapS((GLenum)param))
4079 {
4080 return error(GL_INVALID_ENUM);
4081 }
4082 break;
4083 case GL_TEXTURE_WRAP_T:
4084 if (!texture->setWrapT((GLenum)param))
4085 {
4086 return error(GL_INVALID_ENUM);
4087 }
4088 break;
4089 case GL_TEXTURE_MIN_FILTER:
4090 if (!texture->setMinFilter((GLenum)param))
4091 {
4092 return error(GL_INVALID_ENUM);
4093 }
4094 break;
4095 case GL_TEXTURE_MAG_FILTER:
4096 if (!texture->setMagFilter((GLenum)param))
4097 {
4098 return error(GL_INVALID_ENUM);
4099 }
4100 break;
4101 default:
4102 return error(GL_INVALID_ENUM);
4103 }
4104 }
4105 }
4106 catch(std::bad_alloc&)
4107 {
4108 return error(GL_OUT_OF_MEMORY);
4109 }
4110}
4111
4112void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4113{
4114 glTexParameteri(target, pname, *params);
4115}
4116
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004117void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4118 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004119{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004120 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4121 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004122 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004123 target, level, xoffset, yoffset, width, height, format, type, pixels);
4124
4125 try
4126 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004127 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004128 {
4129 return error(GL_INVALID_ENUM);
4130 }
4131
4132 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004133 {
4134 return error(GL_INVALID_VALUE);
4135 }
4136
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004137 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4138 {
4139 return error(GL_INVALID_VALUE);
4140 }
4141
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004142 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004143 {
4144 return error(GL_INVALID_ENUM);
4145 }
4146
4147 if (width == 0 || height == 0 || pixels == NULL)
4148 {
4149 return;
4150 }
4151
4152 gl::Context *context = gl::getContext();
4153
4154 if (context)
4155 {
4156 if (target == GL_TEXTURE_2D)
4157 {
4158 gl::Texture2D *texture = context->getTexture2D();
4159
4160 if (!texture)
4161 {
4162 return error(GL_INVALID_OPERATION);
4163 }
4164
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004165 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004166 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004167 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004168 {
4169 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4170
4171 if (!texture)
4172 {
4173 return error(GL_INVALID_OPERATION);
4174 }
4175
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004176 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004177 }
4178 else
4179 {
4180 UNREACHABLE();
4181 }
4182 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004183 }
4184 catch(std::bad_alloc&)
4185 {
4186 return error(GL_OUT_OF_MEMORY);
4187 }
4188}
4189
4190void __stdcall glUniform1f(GLint location, GLfloat x)
4191{
4192 glUniform1fv(location, 1, &x);
4193}
4194
4195void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4196{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004197 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004198
4199 try
4200 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004201 if (count < 0)
4202 {
4203 return error(GL_INVALID_VALUE);
4204 }
4205
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004206 if (location == -1)
4207 {
4208 return;
4209 }
4210
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004211 gl::Context *context = gl::getContext();
4212
4213 if (context)
4214 {
4215 gl::Program *program = context->getCurrentProgram();
4216
4217 if (!program)
4218 {
4219 return error(GL_INVALID_OPERATION);
4220 }
4221
4222 if (!program->setUniform1fv(location, count, v))
4223 {
4224 return error(GL_INVALID_OPERATION);
4225 }
4226 }
4227 }
4228 catch(std::bad_alloc&)
4229 {
4230 return error(GL_OUT_OF_MEMORY);
4231 }
4232}
4233
4234void __stdcall glUniform1i(GLint location, GLint x)
4235{
4236 glUniform1iv(location, 1, &x);
4237}
4238
4239void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4240{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004241 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004242
4243 try
4244 {
4245 if (count < 0)
4246 {
4247 return error(GL_INVALID_VALUE);
4248 }
4249
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004250 if (location == -1)
4251 {
4252 return;
4253 }
4254
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004255 gl::Context *context = gl::getContext();
4256
4257 if (context)
4258 {
4259 gl::Program *program = context->getCurrentProgram();
4260
4261 if (!program)
4262 {
4263 return error(GL_INVALID_OPERATION);
4264 }
4265
4266 if (!program->setUniform1iv(location, count, v))
4267 {
4268 return error(GL_INVALID_OPERATION);
4269 }
4270 }
4271 }
4272 catch(std::bad_alloc&)
4273 {
4274 return error(GL_OUT_OF_MEMORY);
4275 }
4276}
4277
4278void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4279{
4280 GLfloat xy[2] = {x, y};
4281
4282 glUniform2fv(location, 1, (GLfloat*)&xy);
4283}
4284
4285void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4286{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004287 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004288
4289 try
4290 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004291 if (count < 0)
4292 {
4293 return error(GL_INVALID_VALUE);
4294 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004295
4296 if (location == -1)
4297 {
4298 return;
4299 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004300
4301 gl::Context *context = gl::getContext();
4302
4303 if (context)
4304 {
4305 gl::Program *program = context->getCurrentProgram();
4306
4307 if (!program)
4308 {
4309 return error(GL_INVALID_OPERATION);
4310 }
4311
4312 if (!program->setUniform2fv(location, count, v))
4313 {
4314 return error(GL_INVALID_OPERATION);
4315 }
4316 }
4317 }
4318 catch(std::bad_alloc&)
4319 {
4320 return error(GL_OUT_OF_MEMORY);
4321 }
4322}
4323
4324void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4325{
4326 GLint xy[4] = {x, y};
4327
4328 glUniform2iv(location, 1, (GLint*)&xy);
4329}
4330
4331void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4332{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004333 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004334
4335 try
4336 {
4337 if (count < 0)
4338 {
4339 return error(GL_INVALID_VALUE);
4340 }
4341
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004342 if (location == -1)
4343 {
4344 return;
4345 }
4346
4347 gl::Context *context = gl::getContext();
4348
4349 if (context)
4350 {
4351 gl::Program *program = context->getCurrentProgram();
4352
4353 if (!program)
4354 {
4355 return error(GL_INVALID_OPERATION);
4356 }
4357
4358 if (!program->setUniform2iv(location, count, v))
4359 {
4360 return error(GL_INVALID_OPERATION);
4361 }
4362 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004363 }
4364 catch(std::bad_alloc&)
4365 {
4366 return error(GL_OUT_OF_MEMORY);
4367 }
4368}
4369
4370void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4371{
4372 GLfloat xyz[3] = {x, y, z};
4373
4374 glUniform3fv(location, 1, (GLfloat*)&xyz);
4375}
4376
4377void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4378{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004379 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004380
4381 try
4382 {
4383 if (count < 0)
4384 {
4385 return error(GL_INVALID_VALUE);
4386 }
4387
4388 if (location == -1)
4389 {
4390 return;
4391 }
4392
4393 gl::Context *context = gl::getContext();
4394
4395 if (context)
4396 {
4397 gl::Program *program = context->getCurrentProgram();
4398
4399 if (!program)
4400 {
4401 return error(GL_INVALID_OPERATION);
4402 }
4403
4404 if (!program->setUniform3fv(location, count, v))
4405 {
4406 return error(GL_INVALID_OPERATION);
4407 }
4408 }
4409 }
4410 catch(std::bad_alloc&)
4411 {
4412 return error(GL_OUT_OF_MEMORY);
4413 }
4414}
4415
4416void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4417{
4418 GLint xyz[3] = {x, y, z};
4419
4420 glUniform3iv(location, 1, (GLint*)&xyz);
4421}
4422
4423void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4424{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004425 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004426
4427 try
4428 {
4429 if (count < 0)
4430 {
4431 return error(GL_INVALID_VALUE);
4432 }
4433
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004434 if (location == -1)
4435 {
4436 return;
4437 }
4438
4439 gl::Context *context = gl::getContext();
4440
4441 if (context)
4442 {
4443 gl::Program *program = context->getCurrentProgram();
4444
4445 if (!program)
4446 {
4447 return error(GL_INVALID_OPERATION);
4448 }
4449
4450 if (!program->setUniform3iv(location, count, v))
4451 {
4452 return error(GL_INVALID_OPERATION);
4453 }
4454 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004455 }
4456 catch(std::bad_alloc&)
4457 {
4458 return error(GL_OUT_OF_MEMORY);
4459 }
4460}
4461
4462void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4463{
4464 GLfloat xyzw[4] = {x, y, z, w};
4465
4466 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4467}
4468
4469void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4470{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004471 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004472
4473 try
4474 {
4475 if (count < 0)
4476 {
4477 return error(GL_INVALID_VALUE);
4478 }
4479
4480 if (location == -1)
4481 {
4482 return;
4483 }
4484
4485 gl::Context *context = gl::getContext();
4486
4487 if (context)
4488 {
4489 gl::Program *program = context->getCurrentProgram();
4490
4491 if (!program)
4492 {
4493 return error(GL_INVALID_OPERATION);
4494 }
4495
4496 if (!program->setUniform4fv(location, count, v))
4497 {
4498 return error(GL_INVALID_OPERATION);
4499 }
4500 }
4501 }
4502 catch(std::bad_alloc&)
4503 {
4504 return error(GL_OUT_OF_MEMORY);
4505 }
4506}
4507
4508void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4509{
4510 GLint xyzw[4] = {x, y, z, w};
4511
4512 glUniform4iv(location, 1, (GLint*)&xyzw);
4513}
4514
4515void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4516{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004517 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004518
4519 try
4520 {
4521 if (count < 0)
4522 {
4523 return error(GL_INVALID_VALUE);
4524 }
4525
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004526 if (location == -1)
4527 {
4528 return;
4529 }
4530
4531 gl::Context *context = gl::getContext();
4532
4533 if (context)
4534 {
4535 gl::Program *program = context->getCurrentProgram();
4536
4537 if (!program)
4538 {
4539 return error(GL_INVALID_OPERATION);
4540 }
4541
4542 if (!program->setUniform4iv(location, count, v))
4543 {
4544 return error(GL_INVALID_OPERATION);
4545 }
4546 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004547 }
4548 catch(std::bad_alloc&)
4549 {
4550 return error(GL_OUT_OF_MEMORY);
4551 }
4552}
4553
4554void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4555{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004556 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4557 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004558
4559 try
4560 {
4561 if (count < 0 || transpose != GL_FALSE)
4562 {
4563 return error(GL_INVALID_VALUE);
4564 }
4565
4566 if (location == -1)
4567 {
4568 return;
4569 }
4570
4571 gl::Context *context = gl::getContext();
4572
4573 if (context)
4574 {
4575 gl::Program *program = context->getCurrentProgram();
4576
4577 if (!program)
4578 {
4579 return error(GL_INVALID_OPERATION);
4580 }
4581
4582 if (!program->setUniformMatrix2fv(location, count, value))
4583 {
4584 return error(GL_INVALID_OPERATION);
4585 }
4586 }
4587 }
4588 catch(std::bad_alloc&)
4589 {
4590 return error(GL_OUT_OF_MEMORY);
4591 }
4592}
4593
4594void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4595{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004596 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4597 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004598
4599 try
4600 {
4601 if (count < 0 || transpose != GL_FALSE)
4602 {
4603 return error(GL_INVALID_VALUE);
4604 }
4605
4606 if (location == -1)
4607 {
4608 return;
4609 }
4610
4611 gl::Context *context = gl::getContext();
4612
4613 if (context)
4614 {
4615 gl::Program *program = context->getCurrentProgram();
4616
4617 if (!program)
4618 {
4619 return error(GL_INVALID_OPERATION);
4620 }
4621
4622 if (!program->setUniformMatrix3fv(location, count, value))
4623 {
4624 return error(GL_INVALID_OPERATION);
4625 }
4626 }
4627 }
4628 catch(std::bad_alloc&)
4629 {
4630 return error(GL_OUT_OF_MEMORY);
4631 }
4632}
4633
4634void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4635{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004636 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4637 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004638
4639 try
4640 {
4641 if (count < 0 || transpose != GL_FALSE)
4642 {
4643 return error(GL_INVALID_VALUE);
4644 }
4645
4646 if (location == -1)
4647 {
4648 return;
4649 }
4650
4651 gl::Context *context = gl::getContext();
4652
4653 if (context)
4654 {
4655 gl::Program *program = context->getCurrentProgram();
4656
4657 if (!program)
4658 {
4659 return error(GL_INVALID_OPERATION);
4660 }
4661
4662 if (!program->setUniformMatrix4fv(location, count, value))
4663 {
4664 return error(GL_INVALID_OPERATION);
4665 }
4666 }
4667 }
4668 catch(std::bad_alloc&)
4669 {
4670 return error(GL_OUT_OF_MEMORY);
4671 }
4672}
4673
4674void __stdcall glUseProgram(GLuint program)
4675{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004676 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004677
4678 try
4679 {
4680 gl::Context *context = gl::getContext();
4681
4682 if (context)
4683 {
4684 gl::Program *programObject = context->getProgram(program);
4685
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004686 if (!programObject && program != 0)
4687 {
4688 if (context->getShader(program))
4689 {
4690 return error(GL_INVALID_OPERATION);
4691 }
4692 else
4693 {
4694 return error(GL_INVALID_VALUE);
4695 }
4696 }
4697
4698 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004699 {
4700 return error(GL_INVALID_OPERATION);
4701 }
4702
4703 context->useProgram(program);
4704 }
4705 }
4706 catch(std::bad_alloc&)
4707 {
4708 return error(GL_OUT_OF_MEMORY);
4709 }
4710}
4711
4712void __stdcall glValidateProgram(GLuint program)
4713{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004714 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004715
4716 try
4717 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00004718 gl::Context *context = gl::getContext();
4719
4720 if (context)
4721 {
4722 gl::Program *programObject = context->getProgram(program);
4723
4724 if (!programObject)
4725 {
4726 if (context->getShader(program))
4727 {
4728 return error(GL_INVALID_OPERATION);
4729 }
4730 else
4731 {
4732 return error(GL_INVALID_VALUE);
4733 }
4734 }
4735
4736 programObject->validate();
4737 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004738 }
4739 catch(std::bad_alloc&)
4740 {
4741 return error(GL_OUT_OF_MEMORY);
4742 }
4743}
4744
4745void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4746{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004747 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004748
4749 try
4750 {
4751 if (index >= gl::MAX_VERTEX_ATTRIBS)
4752 {
4753 return error(GL_INVALID_VALUE);
4754 }
4755
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004756 gl::Context *context = gl::getContext();
4757
4758 if (context)
4759 {
4760 GLfloat vals[4] = { x, 0, 0, 1 };
4761 context->setVertexAttrib(index, vals);
4762 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004763 }
4764 catch(std::bad_alloc&)
4765 {
4766 return error(GL_OUT_OF_MEMORY);
4767 }
4768}
4769
4770void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4771{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004772 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004773
4774 try
4775 {
4776 if (index >= gl::MAX_VERTEX_ATTRIBS)
4777 {
4778 return error(GL_INVALID_VALUE);
4779 }
4780
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004781 gl::Context *context = gl::getContext();
4782
4783 if (context)
4784 {
4785 GLfloat vals[4] = { values[0], 0, 0, 1 };
4786 context->setVertexAttrib(index, vals);
4787 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004788 }
4789 catch(std::bad_alloc&)
4790 {
4791 return error(GL_OUT_OF_MEMORY);
4792 }
4793}
4794
4795void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4796{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004797 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004798
4799 try
4800 {
4801 if (index >= gl::MAX_VERTEX_ATTRIBS)
4802 {
4803 return error(GL_INVALID_VALUE);
4804 }
4805
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004806 gl::Context *context = gl::getContext();
4807
4808 if (context)
4809 {
4810 GLfloat vals[4] = { x, y, 0, 1 };
4811 context->setVertexAttrib(index, vals);
4812 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004813 }
4814 catch(std::bad_alloc&)
4815 {
4816 return error(GL_OUT_OF_MEMORY);
4817 }
4818}
4819
4820void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4821{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004822 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004823
4824 try
4825 {
4826 if (index >= gl::MAX_VERTEX_ATTRIBS)
4827 {
4828 return error(GL_INVALID_VALUE);
4829 }
4830
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004831 gl::Context *context = gl::getContext();
4832
4833 if (context)
4834 {
4835 GLfloat vals[4] = { values[0], values[1], 0, 1 };
4836 context->setVertexAttrib(index, vals);
4837 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004838 }
4839 catch(std::bad_alloc&)
4840 {
4841 return error(GL_OUT_OF_MEMORY);
4842 }
4843}
4844
4845void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4846{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004847 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 +00004848
4849 try
4850 {
4851 if (index >= gl::MAX_VERTEX_ATTRIBS)
4852 {
4853 return error(GL_INVALID_VALUE);
4854 }
4855
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004856 gl::Context *context = gl::getContext();
4857
4858 if (context)
4859 {
4860 GLfloat vals[4] = { x, y, z, 1 };
4861 context->setVertexAttrib(index, vals);
4862 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004863 }
4864 catch(std::bad_alloc&)
4865 {
4866 return error(GL_OUT_OF_MEMORY);
4867 }
4868}
4869
4870void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4871{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004872 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004873
4874 try
4875 {
4876 if (index >= gl::MAX_VERTEX_ATTRIBS)
4877 {
4878 return error(GL_INVALID_VALUE);
4879 }
4880
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004881 gl::Context *context = gl::getContext();
4882
4883 if (context)
4884 {
4885 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
4886 context->setVertexAttrib(index, vals);
4887 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004888 }
4889 catch(std::bad_alloc&)
4890 {
4891 return error(GL_OUT_OF_MEMORY);
4892 }
4893}
4894
4895void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4896{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004897 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 +00004898
4899 try
4900 {
4901 if (index >= gl::MAX_VERTEX_ATTRIBS)
4902 {
4903 return error(GL_INVALID_VALUE);
4904 }
4905
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004906 gl::Context *context = gl::getContext();
4907
4908 if (context)
4909 {
4910 GLfloat vals[4] = { x, y, z, w };
4911 context->setVertexAttrib(index, vals);
4912 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004913 }
4914 catch(std::bad_alloc&)
4915 {
4916 return error(GL_OUT_OF_MEMORY);
4917 }
4918}
4919
4920void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4921{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004922 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004923
4924 try
4925 {
4926 if (index >= gl::MAX_VERTEX_ATTRIBS)
4927 {
4928 return error(GL_INVALID_VALUE);
4929 }
4930
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004931 gl::Context *context = gl::getContext();
4932
4933 if (context)
4934 {
4935 context->setVertexAttrib(index, values);
4936 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004937 }
4938 catch(std::bad_alloc&)
4939 {
4940 return error(GL_OUT_OF_MEMORY);
4941 }
4942}
4943
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004944void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004945{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004946 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004947 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004948 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004949
4950 try
4951 {
4952 if (index >= gl::MAX_VERTEX_ATTRIBS)
4953 {
4954 return error(GL_INVALID_VALUE);
4955 }
4956
4957 if (size < 1 || size > 4)
4958 {
4959 return error(GL_INVALID_VALUE);
4960 }
4961
4962 switch (type)
4963 {
4964 case GL_BYTE:
4965 case GL_UNSIGNED_BYTE:
4966 case GL_SHORT:
4967 case GL_UNSIGNED_SHORT:
4968 case GL_FIXED:
4969 case GL_FLOAT:
4970 break;
4971 default:
4972 return error(GL_INVALID_ENUM);
4973 }
4974
4975 if (stride < 0)
4976 {
4977 return error(GL_INVALID_VALUE);
4978 }
4979
4980 gl::Context *context = gl::getContext();
4981
4982 if (context)
4983 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004984 context->setVertexAttribState(index, context->getArrayBufferHandle(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004985 }
4986 }
4987 catch(std::bad_alloc&)
4988 {
4989 return error(GL_OUT_OF_MEMORY);
4990 }
4991}
4992
4993void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4994{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004995 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 +00004996
4997 try
4998 {
4999 if (width < 0 || height < 0)
5000 {
5001 return error(GL_INVALID_VALUE);
5002 }
5003
5004 gl::Context *context = gl::getContext();
5005
5006 if (context)
5007 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005008 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005009 }
5010 }
5011 catch(std::bad_alloc&)
5012 {
5013 return error(GL_OUT_OF_MEMORY);
5014 }
5015}
5016
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005017void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5018 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005019{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005020 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5021 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005022 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005023 target, level, internalformat, width, height, depth, border, format, type, pixels);
5024
5025 try
5026 {
5027 UNIMPLEMENTED(); // FIXME
5028 }
5029 catch(std::bad_alloc&)
5030 {
5031 return error(GL_OUT_OF_MEMORY);
5032 }
5033}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005034
5035__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5036{
5037 struct Extension
5038 {
5039 const char *name;
5040 __eglMustCastToProperFunctionPointerType address;
5041 };
5042
5043 static const Extension glExtensions[] =
5044 {
5045 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
5046 };
5047
5048 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5049 {
5050 if (strcmp(procname, glExtensions[ext].name) == 0)
5051 {
5052 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5053 }
5054 }
5055
5056 return NULL;
5057}
5058
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005059}