blob: 3a31b69f41f0a0070ee98cbbf492f8ce0f3a0453 [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"
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000023#include "libGLESv2/Fence.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000024#include "libGLESv2/Framebuffer.h"
25#include "libGLESv2/Program.h"
26#include "libGLESv2/Renderbuffer.h"
27#include "libGLESv2/Shader.h"
28#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000029
30extern "C"
31{
32
33void __stdcall glActiveTexture(GLenum texture)
34{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000035 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000036
37 try
38 {
39 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
40 {
41 return error(GL_INVALID_ENUM);
42 }
43
44 gl::Context *context = gl::getContext();
45
46 if (context)
47 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +000048 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000049 }
50 }
51 catch(std::bad_alloc&)
52 {
53 return error(GL_OUT_OF_MEMORY);
54 }
55}
56
57void __stdcall glAttachShader(GLuint program, GLuint shader)
58{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000059 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000060
61 try
62 {
63 gl::Context *context = gl::getContext();
64
65 if (context)
66 {
67 gl::Program *programObject = context->getProgram(program);
68 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000069
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000070 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000071 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000072 if (context->getShader(program))
73 {
74 return error(GL_INVALID_OPERATION);
75 }
76 else
77 {
78 return error(GL_INVALID_VALUE);
79 }
80 }
81
82 if (!shaderObject)
83 {
84 if (context->getProgram(shader))
85 {
86 return error(GL_INVALID_OPERATION);
87 }
88 else
89 {
90 return error(GL_INVALID_VALUE);
91 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000092 }
93
94 if (!programObject->attachShader(shaderObject))
95 {
96 return error(GL_INVALID_OPERATION);
97 }
98 }
99 }
100 catch(std::bad_alloc&)
101 {
102 return error(GL_OUT_OF_MEMORY);
103 }
104}
105
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000106void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000108 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000109
110 try
111 {
112 if (index >= gl::MAX_VERTEX_ATTRIBS)
113 {
114 return error(GL_INVALID_VALUE);
115 }
116
117 gl::Context *context = gl::getContext();
118
119 if (context)
120 {
121 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000122
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000123 if (!programObject)
124 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000125 if (context->getShader(program))
126 {
127 return error(GL_INVALID_OPERATION);
128 }
129 else
130 {
131 return error(GL_INVALID_VALUE);
132 }
133 }
134
135 if (strncmp(name, "gl_", 3) == 0)
136 {
137 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000138 }
139
140 programObject->bindAttributeLocation(index, name);
141 }
142 }
143 catch(std::bad_alloc&)
144 {
145 return error(GL_OUT_OF_MEMORY);
146 }
147}
148
149void __stdcall glBindBuffer(GLenum target, GLuint buffer)
150{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000151 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000152
153 try
154 {
155 gl::Context *context = gl::getContext();
156
157 if (context)
158 {
159 switch (target)
160 {
161 case GL_ARRAY_BUFFER:
162 context->bindArrayBuffer(buffer);
163 return;
164 case GL_ELEMENT_ARRAY_BUFFER:
165 context->bindElementArrayBuffer(buffer);
166 return;
167 default:
168 return error(GL_INVALID_ENUM);
169 }
170 }
171 }
172 catch(std::bad_alloc&)
173 {
174 return error(GL_OUT_OF_MEMORY);
175 }
176}
177
178void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
179{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000180 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000181
182 try
183 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000184 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000185 {
186 return error(GL_INVALID_ENUM);
187 }
188
189 gl::Context *context = gl::getContext();
190
191 if (context)
192 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000193 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
194 {
195 context->bindReadFramebuffer(framebuffer);
196 }
197
198 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
199 {
200 context->bindDrawFramebuffer(framebuffer);
201 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000202 }
203 }
204 catch(std::bad_alloc&)
205 {
206 return error(GL_OUT_OF_MEMORY);
207 }
208}
209
210void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
211{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000212 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000213
214 try
215 {
216 if (target != GL_RENDERBUFFER)
217 {
218 return error(GL_INVALID_ENUM);
219 }
220
221 gl::Context *context = gl::getContext();
222
223 if (context)
224 {
225 context->bindRenderbuffer(renderbuffer);
226 }
227 }
228 catch(std::bad_alloc&)
229 {
230 return error(GL_OUT_OF_MEMORY);
231 }
232}
233
234void __stdcall glBindTexture(GLenum target, GLuint texture)
235{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000236 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000237
238 try
239 {
240 gl::Context *context = gl::getContext();
241
242 if (context)
243 {
244 gl::Texture *textureObject = context->getTexture(texture);
245
246 if (textureObject && textureObject->getTarget() != target && texture != 0)
247 {
248 return error(GL_INVALID_OPERATION);
249 }
250
251 switch (target)
252 {
253 case GL_TEXTURE_2D:
254 context->bindTexture2D(texture);
255 return;
256 case GL_TEXTURE_CUBE_MAP:
257 context->bindTextureCubeMap(texture);
258 return;
259 default:
260 return error(GL_INVALID_ENUM);
261 }
262 }
263 }
264 catch(std::bad_alloc&)
265 {
266 return error(GL_OUT_OF_MEMORY);
267 }
268}
269
270void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
271{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000272 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
273 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000274
275 try
276 {
277 gl::Context* context = gl::getContext();
278
279 if (context)
280 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000281 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000282 }
283 }
284 catch(std::bad_alloc&)
285 {
286 return error(GL_OUT_OF_MEMORY);
287 }
288}
289
290void __stdcall glBlendEquation(GLenum mode)
291{
292 glBlendEquationSeparate(mode, mode);
293}
294
295void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
296{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000297 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000298
299 try
300 {
301 switch (modeRGB)
302 {
303 case GL_FUNC_ADD:
304 case GL_FUNC_SUBTRACT:
305 case GL_FUNC_REVERSE_SUBTRACT:
306 break;
307 default:
308 return error(GL_INVALID_ENUM);
309 }
310
311 switch (modeAlpha)
312 {
313 case GL_FUNC_ADD:
314 case GL_FUNC_SUBTRACT:
315 case GL_FUNC_REVERSE_SUBTRACT:
316 break;
317 default:
318 return error(GL_INVALID_ENUM);
319 }
320
321 gl::Context *context = gl::getContext();
322
323 if (context)
324 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000325 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000326 }
327 }
328 catch(std::bad_alloc&)
329 {
330 return error(GL_OUT_OF_MEMORY);
331 }
332}
333
334void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
335{
336 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
337}
338
339void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
340{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000341 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
342 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000343
344 try
345 {
346 switch (srcRGB)
347 {
348 case GL_ZERO:
349 case GL_ONE:
350 case GL_SRC_COLOR:
351 case GL_ONE_MINUS_SRC_COLOR:
352 case GL_DST_COLOR:
353 case GL_ONE_MINUS_DST_COLOR:
354 case GL_SRC_ALPHA:
355 case GL_ONE_MINUS_SRC_ALPHA:
356 case GL_DST_ALPHA:
357 case GL_ONE_MINUS_DST_ALPHA:
358 case GL_CONSTANT_COLOR:
359 case GL_ONE_MINUS_CONSTANT_COLOR:
360 case GL_CONSTANT_ALPHA:
361 case GL_ONE_MINUS_CONSTANT_ALPHA:
362 case GL_SRC_ALPHA_SATURATE:
363 break;
364 default:
365 return error(GL_INVALID_ENUM);
366 }
367
368 switch (dstRGB)
369 {
370 case GL_ZERO:
371 case GL_ONE:
372 case GL_SRC_COLOR:
373 case GL_ONE_MINUS_SRC_COLOR:
374 case GL_DST_COLOR:
375 case GL_ONE_MINUS_DST_COLOR:
376 case GL_SRC_ALPHA:
377 case GL_ONE_MINUS_SRC_ALPHA:
378 case GL_DST_ALPHA:
379 case GL_ONE_MINUS_DST_ALPHA:
380 case GL_CONSTANT_COLOR:
381 case GL_ONE_MINUS_CONSTANT_COLOR:
382 case GL_CONSTANT_ALPHA:
383 case GL_ONE_MINUS_CONSTANT_ALPHA:
384 break;
385 default:
386 return error(GL_INVALID_ENUM);
387 }
388
389 switch (srcAlpha)
390 {
391 case GL_ZERO:
392 case GL_ONE:
393 case GL_SRC_COLOR:
394 case GL_ONE_MINUS_SRC_COLOR:
395 case GL_DST_COLOR:
396 case GL_ONE_MINUS_DST_COLOR:
397 case GL_SRC_ALPHA:
398 case GL_ONE_MINUS_SRC_ALPHA:
399 case GL_DST_ALPHA:
400 case GL_ONE_MINUS_DST_ALPHA:
401 case GL_CONSTANT_COLOR:
402 case GL_ONE_MINUS_CONSTANT_COLOR:
403 case GL_CONSTANT_ALPHA:
404 case GL_ONE_MINUS_CONSTANT_ALPHA:
405 case GL_SRC_ALPHA_SATURATE:
406 break;
407 default:
408 return error(GL_INVALID_ENUM);
409 }
410
411 switch (dstAlpha)
412 {
413 case GL_ZERO:
414 case GL_ONE:
415 case GL_SRC_COLOR:
416 case GL_ONE_MINUS_SRC_COLOR:
417 case GL_DST_COLOR:
418 case GL_ONE_MINUS_DST_COLOR:
419 case GL_SRC_ALPHA:
420 case GL_ONE_MINUS_SRC_ALPHA:
421 case GL_DST_ALPHA:
422 case GL_ONE_MINUS_DST_ALPHA:
423 case GL_CONSTANT_COLOR:
424 case GL_ONE_MINUS_CONSTANT_COLOR:
425 case GL_CONSTANT_ALPHA:
426 case GL_ONE_MINUS_CONSTANT_ALPHA:
427 break;
428 default:
429 return error(GL_INVALID_ENUM);
430 }
431
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000432 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
433 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
434
435 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
436 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
437
438 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000439 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000440 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
441 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000442 }
443
444 gl::Context *context = gl::getContext();
445
446 if (context)
447 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000448 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000449 }
450 }
451 catch(std::bad_alloc&)
452 {
453 return error(GL_OUT_OF_MEMORY);
454 }
455}
456
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000457void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000458{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000459 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 +0000460 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000461
462 try
463 {
464 if (size < 0)
465 {
466 return error(GL_INVALID_VALUE);
467 }
468
469 switch (usage)
470 {
471 case GL_STREAM_DRAW:
472 case GL_STATIC_DRAW:
473 case GL_DYNAMIC_DRAW:
474 break;
475 default:
476 return error(GL_INVALID_ENUM);
477 }
478
479 gl::Context *context = gl::getContext();
480
481 if (context)
482 {
483 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000484
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000485 switch (target)
486 {
487 case GL_ARRAY_BUFFER:
488 buffer = context->getArrayBuffer();
489 break;
490 case GL_ELEMENT_ARRAY_BUFFER:
491 buffer = context->getElementArrayBuffer();
492 break;
493 default:
494 return error(GL_INVALID_ENUM);
495 }
496
497 if (!buffer)
498 {
499 return error(GL_INVALID_OPERATION);
500 }
501
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000502 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000503 }
504 }
505 catch(std::bad_alloc&)
506 {
507 return error(GL_OUT_OF_MEMORY);
508 }
509}
510
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000511void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000513 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 +0000514 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000515
516 try
517 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000518 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000519 {
520 return error(GL_INVALID_VALUE);
521 }
522
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000523 if (data == NULL)
524 {
525 return;
526 }
527
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000528 gl::Context *context = gl::getContext();
529
530 if (context)
531 {
532 gl::Buffer *buffer;
533
534 switch (target)
535 {
536 case GL_ARRAY_BUFFER:
537 buffer = context->getArrayBuffer();
538 break;
539 case GL_ELEMENT_ARRAY_BUFFER:
540 buffer = context->getElementArrayBuffer();
541 break;
542 default:
543 return error(GL_INVALID_ENUM);
544 }
545
546 if (!buffer)
547 {
548 return error(GL_INVALID_OPERATION);
549 }
550
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000551 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000552 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000553 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000554 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000555
556 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000557 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000558 }
559 catch(std::bad_alloc&)
560 {
561 return error(GL_OUT_OF_MEMORY);
562 }
563}
564
565GLenum __stdcall glCheckFramebufferStatus(GLenum target)
566{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000567 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000568
569 try
570 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000571 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000572 {
573 return error(GL_INVALID_ENUM, 0);
574 }
575
576 gl::Context *context = gl::getContext();
577
578 if (context)
579 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000580 gl::Framebuffer *framebuffer = NULL;
581 if (target == GL_READ_FRAMEBUFFER_ANGLE)
582 {
583 framebuffer = context->getReadFramebuffer();
584 }
585 else
586 {
587 framebuffer = context->getDrawFramebuffer();
588 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000589
590 return framebuffer->completeness();
591 }
592 }
593 catch(std::bad_alloc&)
594 {
595 return error(GL_OUT_OF_MEMORY, 0);
596 }
597
598 return 0;
599}
600
601void __stdcall glClear(GLbitfield mask)
602{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000603 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000604
605 try
606 {
607 gl::Context *context = gl::getContext();
608
609 if (context)
610 {
611 context->clear(mask);
612 }
613 }
614 catch(std::bad_alloc&)
615 {
616 return error(GL_OUT_OF_MEMORY);
617 }
618}
619
620void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
621{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000622 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
623 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000624
625 try
626 {
627 gl::Context *context = gl::getContext();
628
629 if (context)
630 {
631 context->setClearColor(red, green, blue, alpha);
632 }
633 }
634 catch(std::bad_alloc&)
635 {
636 return error(GL_OUT_OF_MEMORY);
637 }
638}
639
640void __stdcall glClearDepthf(GLclampf depth)
641{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000642 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000643
644 try
645 {
646 gl::Context *context = gl::getContext();
647
648 if (context)
649 {
650 context->setClearDepth(depth);
651 }
652 }
653 catch(std::bad_alloc&)
654 {
655 return error(GL_OUT_OF_MEMORY);
656 }
657}
658
659void __stdcall glClearStencil(GLint s)
660{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000661 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000662
663 try
664 {
665 gl::Context *context = gl::getContext();
666
667 if (context)
668 {
669 context->setClearStencil(s);
670 }
671 }
672 catch(std::bad_alloc&)
673 {
674 return error(GL_OUT_OF_MEMORY);
675 }
676}
677
678void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
679{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000680 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
681 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000682
683 try
684 {
685 gl::Context *context = gl::getContext();
686
687 if (context)
688 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000689 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000690 }
691 }
692 catch(std::bad_alloc&)
693 {
694 return error(GL_OUT_OF_MEMORY);
695 }
696}
697
698void __stdcall glCompileShader(GLuint shader)
699{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000700 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000701
702 try
703 {
704 gl::Context *context = gl::getContext();
705
706 if (context)
707 {
708 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000709
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000710 if (!shaderObject)
711 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000712 if (context->getProgram(shader))
713 {
714 return error(GL_INVALID_OPERATION);
715 }
716 else
717 {
718 return error(GL_INVALID_VALUE);
719 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000720 }
721
722 shaderObject->compile();
723 }
724 }
725 catch(std::bad_alloc&)
726 {
727 return error(GL_OUT_OF_MEMORY);
728 }
729}
730
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000731void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
732 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000733{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000734 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000735 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000736 target, level, internalformat, width, height, border, imageSize, data);
737
738 try
739 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000740 if (level < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000741 {
742 return error(GL_INVALID_VALUE);
743 }
744
daniel@transgaming.com41430492010-03-11 20:36:18 +0000745 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
746 {
747 return error(GL_INVALID_VALUE);
748 }
749
daniel@transgaming.com01868132010-08-24 19:21:17 +0000750 switch (internalformat)
751 {
752 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
753 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
754 break;
755 default:
756 return error(GL_INVALID_ENUM);
757 }
758
759 if (border != 0)
760 {
761 return error(GL_INVALID_VALUE);
762 }
763
764 gl::Context *context = gl::getContext();
765
766 if (context)
767 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000768 if (level > context->getMaximumTextureLevel())
769 {
770 return error(GL_INVALID_VALUE);
771 }
772
773 switch (target)
774 {
775 case GL_TEXTURE_2D:
776 if (width > (context->getMaximumTextureDimension() >> level) ||
777 height > (context->getMaximumTextureDimension() >> level))
778 {
779 return error(GL_INVALID_VALUE);
780 }
781 break;
782 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
783 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
784 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
785 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
786 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
787 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
788 if (width != height)
789 {
790 return error(GL_INVALID_VALUE);
791 }
792
793 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
794 height > (context->getMaximumCubeTextureDimension() >> level))
795 {
796 return error(GL_INVALID_VALUE);
797 }
798 break;
799 default:
800 return error(GL_INVALID_ENUM);
801 }
802
daniel@transgaming.com01868132010-08-24 19:21:17 +0000803 if (!context->supportsCompressedTextures())
804 {
805 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
806 }
807
808 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
809 {
810 return error(GL_INVALID_VALUE);
811 }
812
813 if (target == GL_TEXTURE_2D)
814 {
815 gl::Texture2D *texture = context->getTexture2D();
816
817 if (!texture)
818 {
819 return error(GL_INVALID_OPERATION);
820 }
821
822 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
823 }
824 else
825 {
826 gl::TextureCubeMap *texture = context->getTextureCubeMap();
827
828 if (!texture)
829 {
830 return error(GL_INVALID_OPERATION);
831 }
832
833 switch (target)
834 {
835 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
836 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
837 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
838 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
839 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
840 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
841 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
842 break;
843 default: UNREACHABLE();
844 }
845 }
846 }
847
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000848 }
849 catch(std::bad_alloc&)
850 {
851 return error(GL_OUT_OF_MEMORY);
852 }
853}
854
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000855void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
856 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000857{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000858 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
859 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000860 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000861 target, level, xoffset, yoffset, width, height, format, imageSize, data);
862
863 try
864 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000865 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000866 {
867 return error(GL_INVALID_ENUM);
868 }
869
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000870 if (level < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000871 {
872 return error(GL_INVALID_VALUE);
873 }
874
daniel@transgaming.com01868132010-08-24 19:21:17 +0000875 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 ||
876 (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000877 {
878 return error(GL_INVALID_VALUE);
879 }
880
daniel@transgaming.com01868132010-08-24 19:21:17 +0000881 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000882 {
daniel@transgaming.com01868132010-08-24 19:21:17 +0000883 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
884 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
885 break;
886 default:
887 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +0000888 }
889
daniel@transgaming.com01868132010-08-24 19:21:17 +0000890 if (width == 0 || height == 0 || data == NULL)
891 {
892 return;
893 }
894
895 gl::Context *context = gl::getContext();
896
897 if (context)
898 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000899 if (level > context->getMaximumTextureLevel())
900 {
901 return error(GL_INVALID_VALUE);
902 }
903
daniel@transgaming.com01868132010-08-24 19:21:17 +0000904 if (!context->supportsCompressedTextures())
905 {
906 return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
907 }
908
909 if (imageSize != gl::ComputeCompressedSize(width, height, format))
910 {
911 return error(GL_INVALID_VALUE);
912 }
913
914 if (xoffset % 4 != 0 || yoffset % 4 != 0)
915 {
916 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
917 // does not exist unless DXT1 textures are supported.
918 }
919
920 if (target == GL_TEXTURE_2D)
921 {
922 gl::Texture2D *texture = context->getTexture2D();
923
924 if (!texture)
925 {
926 return error(GL_INVALID_OPERATION);
927 }
928
929 if (!texture->isCompressed())
930 {
931 return error(GL_INVALID_OPERATION);
932 }
933
934 if ((width % 4 != 0 && width != texture->getWidth()) ||
935 (height % 4 != 0 && height != texture->getHeight()))
936 {
937 return error(GL_INVALID_OPERATION);
938 }
939
940 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
941 }
942 else if (gl::IsCubemapTextureTarget(target))
943 {
944 gl::TextureCubeMap *texture = context->getTextureCubeMap();
945
946 if (!texture)
947 {
948 return error(GL_INVALID_OPERATION);
949 }
950
951 if (!texture->isCompressed())
952 {
953 return error(GL_INVALID_OPERATION);
954 }
955
956 if ((width % 4 != 0 && width != texture->getWidth()) ||
957 (height % 4 != 0 && height != texture->getHeight()))
958 {
959 return error(GL_INVALID_OPERATION);
960 }
961
962 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
963 }
964 else
965 {
966 UNREACHABLE();
967 }
968 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000969 }
970 catch(std::bad_alloc&)
971 {
972 return error(GL_OUT_OF_MEMORY);
973 }
974}
975
976void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
977{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000978 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
979 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000980 target, level, internalformat, x, y, width, height, border);
981
982 try
983 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000984 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000985 {
986 return error(GL_INVALID_VALUE);
987 }
988
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000989 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
990 {
991 return error(GL_INVALID_VALUE);
992 }
993
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000994 if (border != 0)
995 {
996 return error(GL_INVALID_VALUE);
997 }
998
999 gl::Context *context = gl::getContext();
1000
1001 if (context)
1002 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001003 switch (target)
1004 {
1005 case GL_TEXTURE_2D:
1006 if (width > (context->getMaximumTextureDimension() >> level) ||
1007 height > (context->getMaximumTextureDimension() >> level))
1008 {
1009 return error(GL_INVALID_VALUE);
1010 }
1011 break;
1012 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1013 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1014 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1015 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1016 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1017 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1018 if (width != height)
1019 {
1020 return error(GL_INVALID_VALUE);
1021 }
1022
1023 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1024 height > (context->getMaximumCubeTextureDimension() >> level))
1025 {
1026 return error(GL_INVALID_VALUE);
1027 }
1028 break;
1029 default:
1030 return error(GL_INVALID_ENUM);
1031 }
1032
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001033 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001034
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001035 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1036 {
1037 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1038 }
1039
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001040 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1041 {
1042 return error(GL_INVALID_OPERATION);
1043 }
1044
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001045 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001046 GLenum colorbufferFormat = source->getFormat();
1047
1048 // [OpenGL ES 2.0.24] table 3.9
1049 switch (internalformat)
1050 {
1051 case GL_ALPHA:
1052 if (colorbufferFormat != GL_ALPHA &&
1053 colorbufferFormat != GL_RGBA &&
1054 colorbufferFormat != GL_RGBA4 &&
1055 colorbufferFormat != GL_RGB5_A1 &&
1056 colorbufferFormat != GL_RGBA8_OES)
1057 {
1058 return error(GL_INVALID_OPERATION);
1059 }
1060 break;
1061 case GL_LUMINANCE:
1062 case GL_RGB:
1063 if (colorbufferFormat != GL_RGB &&
1064 colorbufferFormat != GL_RGB565 &&
1065 colorbufferFormat != GL_RGB8_OES &&
1066 colorbufferFormat != GL_RGBA &&
1067 colorbufferFormat != GL_RGBA4 &&
1068 colorbufferFormat != GL_RGB5_A1 &&
1069 colorbufferFormat != GL_RGBA8_OES)
1070 {
1071 return error(GL_INVALID_OPERATION);
1072 }
1073 break;
1074 case GL_LUMINANCE_ALPHA:
1075 case GL_RGBA:
1076 if (colorbufferFormat != GL_RGBA &&
1077 colorbufferFormat != GL_RGBA4 &&
1078 colorbufferFormat != GL_RGB5_A1 &&
1079 colorbufferFormat != GL_RGBA8_OES)
1080 {
1081 return error(GL_INVALID_OPERATION);
1082 }
1083 break;
1084 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1085 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1086 if (context->supportsCompressedTextures())
1087 {
1088 return error(GL_INVALID_OPERATION);
1089 }
1090 else
1091 {
1092 return error(GL_INVALID_ENUM);
1093 }
1094 break;
1095 default:
1096 return error(GL_INVALID_ENUM);
1097 }
1098
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001099 if (target == GL_TEXTURE_2D)
1100 {
1101 gl::Texture2D *texture = context->getTexture2D();
1102
1103 if (!texture)
1104 {
1105 return error(GL_INVALID_OPERATION);
1106 }
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001107
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001108 texture->copyImage(level, internalformat, x, y, width, height, source);
1109 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001110 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001111 {
1112 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1113
1114 if (!texture)
1115 {
1116 return error(GL_INVALID_OPERATION);
1117 }
1118
1119 texture->copyImage(target, level, internalformat, x, y, width, height, source);
1120 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001121 else UNREACHABLE();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001122 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001123 }
1124 catch(std::bad_alloc&)
1125 {
1126 return error(GL_OUT_OF_MEMORY);
1127 }
1128}
1129
1130void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1131{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001132 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1133 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001134 target, level, xoffset, yoffset, x, y, width, height);
1135
1136 try
1137 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001138 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001139 {
1140 return error(GL_INVALID_ENUM);
1141 }
1142
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001143 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001144 {
1145 return error(GL_INVALID_VALUE);
1146 }
1147
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001148 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1149 {
1150 return error(GL_INVALID_VALUE);
1151 }
1152
1153 if (width == 0 || height == 0)
1154 {
1155 return;
1156 }
1157
1158 gl::Context *context = gl::getContext();
1159
1160 if (context)
1161 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001162 if (level > context->getMaximumTextureLevel())
1163 {
1164 return error(GL_INVALID_VALUE);
1165 }
1166
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001167 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001168
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001169 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1170 {
1171 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1172 }
1173
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001174 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1175 {
1176 return error(GL_INVALID_OPERATION);
1177 }
1178
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001179 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001180 GLenum colorbufferFormat = source->getFormat();
1181 gl::Texture *texture = NULL;
1182
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001183 if (target == GL_TEXTURE_2D)
1184 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001185 texture = context->getTexture2D();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001186 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001187 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001188 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001189 texture = context->getTextureCubeMap();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001190 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001191 else UNREACHABLE();
1192
1193 if (!texture)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001194 {
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001195 return error(GL_INVALID_OPERATION);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001196 }
daniel@transgaming.com3f85fbb2010-10-15 17:58:05 +00001197
1198 GLenum textureFormat = texture->getFormat();
1199
1200 // [OpenGL ES 2.0.24] table 3.9
1201 switch (textureFormat)
1202 {
1203 case GL_ALPHA:
1204 if (colorbufferFormat != GL_ALPHA &&
1205 colorbufferFormat != GL_RGBA &&
1206 colorbufferFormat != GL_RGBA4 &&
1207 colorbufferFormat != GL_RGB5_A1 &&
1208 colorbufferFormat != GL_RGBA8_OES)
1209 {
1210 return error(GL_INVALID_OPERATION);
1211 }
1212 break;
1213 case GL_LUMINANCE:
1214 case GL_RGB:
1215 if (colorbufferFormat != GL_RGB &&
1216 colorbufferFormat != GL_RGB565 &&
1217 colorbufferFormat != GL_RGB8_OES &&
1218 colorbufferFormat != GL_RGBA &&
1219 colorbufferFormat != GL_RGBA4 &&
1220 colorbufferFormat != GL_RGB5_A1 &&
1221 colorbufferFormat != GL_RGBA8_OES)
1222 {
1223 return error(GL_INVALID_OPERATION);
1224 }
1225 break;
1226 case GL_LUMINANCE_ALPHA:
1227 case GL_RGBA:
1228 if (colorbufferFormat != GL_RGBA &&
1229 colorbufferFormat != GL_RGBA4 &&
1230 colorbufferFormat != GL_RGB5_A1 &&
1231 colorbufferFormat != GL_RGBA8_OES)
1232 {
1233 return error(GL_INVALID_OPERATION);
1234 }
1235 break;
1236 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1237 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1238 return error(GL_INVALID_OPERATION);
1239 default:
1240 return error(GL_INVALID_OPERATION);
1241 }
1242
1243 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001244 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001245 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001246
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001247 catch(std::bad_alloc&)
1248 {
1249 return error(GL_OUT_OF_MEMORY);
1250 }
1251}
1252
1253GLuint __stdcall glCreateProgram(void)
1254{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001255 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001256
1257 try
1258 {
1259 gl::Context *context = gl::getContext();
1260
1261 if (context)
1262 {
1263 return context->createProgram();
1264 }
1265 }
1266 catch(std::bad_alloc&)
1267 {
1268 return error(GL_OUT_OF_MEMORY, 0);
1269 }
1270
1271 return 0;
1272}
1273
1274GLuint __stdcall glCreateShader(GLenum type)
1275{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001276 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001277
1278 try
1279 {
1280 gl::Context *context = gl::getContext();
1281
1282 if (context)
1283 {
1284 switch (type)
1285 {
1286 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001287 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001288 return context->createShader(type);
1289 default:
1290 return error(GL_INVALID_ENUM, 0);
1291 }
1292 }
1293 }
1294 catch(std::bad_alloc&)
1295 {
1296 return error(GL_OUT_OF_MEMORY, 0);
1297 }
1298
1299 return 0;
1300}
1301
1302void __stdcall glCullFace(GLenum mode)
1303{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001304 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001305
1306 try
1307 {
1308 switch (mode)
1309 {
1310 case GL_FRONT:
1311 case GL_BACK:
1312 case GL_FRONT_AND_BACK:
1313 {
1314 gl::Context *context = gl::getContext();
1315
1316 if (context)
1317 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001318 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001319 }
1320 }
1321 break;
1322 default:
1323 return error(GL_INVALID_ENUM);
1324 }
1325 }
1326 catch(std::bad_alloc&)
1327 {
1328 return error(GL_OUT_OF_MEMORY);
1329 }
1330}
1331
1332void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1333{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001334 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001335
1336 try
1337 {
1338 if (n < 0)
1339 {
1340 return error(GL_INVALID_VALUE);
1341 }
1342
1343 gl::Context *context = gl::getContext();
1344
1345 if (context)
1346 {
1347 for (int i = 0; i < n; i++)
1348 {
1349 context->deleteBuffer(buffers[i]);
1350 }
1351 }
1352 }
1353 catch(std::bad_alloc&)
1354 {
1355 return error(GL_OUT_OF_MEMORY);
1356 }
1357}
1358
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001359void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1360{
1361 TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
1362
1363 try
1364 {
1365 if (n < 0)
1366 {
1367 return error(GL_INVALID_VALUE);
1368 }
1369
1370 gl::Context *context = gl::getContext();
1371
1372 if (context)
1373 {
1374 for (int i = 0; i < n; i++)
1375 {
1376 context->deleteFence(fences[i]);
1377 }
1378 }
1379 }
1380 catch(std::bad_alloc&)
1381 {
1382 return error(GL_OUT_OF_MEMORY);
1383 }
1384}
1385
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001386void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1387{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001388 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001389
1390 try
1391 {
1392 if (n < 0)
1393 {
1394 return error(GL_INVALID_VALUE);
1395 }
1396
1397 gl::Context *context = gl::getContext();
1398
1399 if (context)
1400 {
1401 for (int i = 0; i < n; i++)
1402 {
1403 if (framebuffers[i] != 0)
1404 {
1405 context->deleteFramebuffer(framebuffers[i]);
1406 }
1407 }
1408 }
1409 }
1410 catch(std::bad_alloc&)
1411 {
1412 return error(GL_OUT_OF_MEMORY);
1413 }
1414}
1415
1416void __stdcall glDeleteProgram(GLuint program)
1417{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001418 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001419
1420 try
1421 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001422 if (program == 0)
1423 {
1424 return;
1425 }
1426
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001427 gl::Context *context = gl::getContext();
1428
1429 if (context)
1430 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001431 if (!context->getProgram(program))
1432 {
1433 if(context->getShader(program))
1434 {
1435 return error(GL_INVALID_OPERATION);
1436 }
1437 else
1438 {
1439 return error(GL_INVALID_VALUE);
1440 }
1441 }
1442
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001443 context->deleteProgram(program);
1444 }
1445 }
1446 catch(std::bad_alloc&)
1447 {
1448 return error(GL_OUT_OF_MEMORY);
1449 }
1450}
1451
1452void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1453{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001454 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001455
1456 try
1457 {
1458 if (n < 0)
1459 {
1460 return error(GL_INVALID_VALUE);
1461 }
1462
1463 gl::Context *context = gl::getContext();
1464
1465 if (context)
1466 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001467 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001468 {
1469 context->deleteRenderbuffer(renderbuffers[i]);
1470 }
1471 }
1472 }
1473 catch(std::bad_alloc&)
1474 {
1475 return error(GL_OUT_OF_MEMORY);
1476 }
1477}
1478
1479void __stdcall glDeleteShader(GLuint shader)
1480{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001481 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001482
1483 try
1484 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001485 if (shader == 0)
1486 {
1487 return;
1488 }
1489
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001490 gl::Context *context = gl::getContext();
1491
1492 if (context)
1493 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001494 if (!context->getShader(shader))
1495 {
1496 if(context->getProgram(shader))
1497 {
1498 return error(GL_INVALID_OPERATION);
1499 }
1500 else
1501 {
1502 return error(GL_INVALID_VALUE);
1503 }
1504 }
1505
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001506 context->deleteShader(shader);
1507 }
1508 }
1509 catch(std::bad_alloc&)
1510 {
1511 return error(GL_OUT_OF_MEMORY);
1512 }
1513}
1514
1515void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1516{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001517 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001518
1519 try
1520 {
1521 if (n < 0)
1522 {
1523 return error(GL_INVALID_VALUE);
1524 }
1525
1526 gl::Context *context = gl::getContext();
1527
1528 if (context)
1529 {
1530 for (int i = 0; i < n; i++)
1531 {
1532 if (textures[i] != 0)
1533 {
1534 context->deleteTexture(textures[i]);
1535 }
1536 }
1537 }
1538 }
1539 catch(std::bad_alloc&)
1540 {
1541 return error(GL_OUT_OF_MEMORY);
1542 }
1543}
1544
1545void __stdcall glDepthFunc(GLenum func)
1546{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001547 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001548
1549 try
1550 {
1551 switch (func)
1552 {
1553 case GL_NEVER:
1554 case GL_ALWAYS:
1555 case GL_LESS:
1556 case GL_LEQUAL:
1557 case GL_EQUAL:
1558 case GL_GREATER:
1559 case GL_GEQUAL:
1560 case GL_NOTEQUAL:
1561 break;
1562 default:
1563 return error(GL_INVALID_ENUM);
1564 }
1565
1566 gl::Context *context = gl::getContext();
1567
1568 if (context)
1569 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001570 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001571 }
1572 }
1573 catch(std::bad_alloc&)
1574 {
1575 return error(GL_OUT_OF_MEMORY);
1576 }
1577}
1578
1579void __stdcall glDepthMask(GLboolean flag)
1580{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001581 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001582
1583 try
1584 {
1585 gl::Context *context = gl::getContext();
1586
1587 if (context)
1588 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001589 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001590 }
1591 }
1592 catch(std::bad_alloc&)
1593 {
1594 return error(GL_OUT_OF_MEMORY);
1595 }
1596}
1597
1598void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1599{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001600 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001601
1602 try
1603 {
1604 gl::Context *context = gl::getContext();
1605
1606 if (context)
1607 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001608 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001609 }
1610 }
1611 catch(std::bad_alloc&)
1612 {
1613 return error(GL_OUT_OF_MEMORY);
1614 }
1615}
1616
1617void __stdcall glDetachShader(GLuint program, GLuint shader)
1618{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001619 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001620
1621 try
1622 {
1623 gl::Context *context = gl::getContext();
1624
1625 if (context)
1626 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001627
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001628 gl::Program *programObject = context->getProgram(program);
1629 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001630
1631 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001632 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001633 gl::Shader *shaderByProgramHandle;
1634 shaderByProgramHandle = context->getShader(program);
1635 if (!shaderByProgramHandle)
1636 {
1637 return error(GL_INVALID_VALUE);
1638 }
1639 else
1640 {
1641 return error(GL_INVALID_OPERATION);
1642 }
1643 }
1644
1645 if (!shaderObject)
1646 {
1647 gl::Program *programByShaderHandle = context->getProgram(shader);
1648 if (!programByShaderHandle)
1649 {
1650 return error(GL_INVALID_VALUE);
1651 }
1652 else
1653 {
1654 return error(GL_INVALID_OPERATION);
1655 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001656 }
1657
1658 if (!programObject->detachShader(shaderObject))
1659 {
1660 return error(GL_INVALID_OPERATION);
1661 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001662 }
1663 }
1664 catch(std::bad_alloc&)
1665 {
1666 return error(GL_OUT_OF_MEMORY);
1667 }
1668}
1669
1670void __stdcall glDisable(GLenum cap)
1671{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001672 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001673
1674 try
1675 {
1676 gl::Context *context = gl::getContext();
1677
1678 if (context)
1679 {
1680 switch (cap)
1681 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001682 case GL_CULL_FACE: context->setCullFace(false); break;
1683 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1684 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1685 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1686 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1687 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1688 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1689 case GL_BLEND: context->setBlend(false); break;
1690 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001691 default:
1692 return error(GL_INVALID_ENUM);
1693 }
1694 }
1695 }
1696 catch(std::bad_alloc&)
1697 {
1698 return error(GL_OUT_OF_MEMORY);
1699 }
1700}
1701
1702void __stdcall glDisableVertexAttribArray(GLuint index)
1703{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001704 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001705
1706 try
1707 {
1708 if (index >= gl::MAX_VERTEX_ATTRIBS)
1709 {
1710 return error(GL_INVALID_VALUE);
1711 }
1712
1713 gl::Context *context = gl::getContext();
1714
1715 if (context)
1716 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001717 context->setVertexAttribEnabled(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001718 }
1719 }
1720 catch(std::bad_alloc&)
1721 {
1722 return error(GL_OUT_OF_MEMORY);
1723 }
1724}
1725
1726void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1727{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001728 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001729
1730 try
1731 {
1732 if (count < 0 || first < 0)
1733 {
1734 return error(GL_INVALID_VALUE);
1735 }
1736
1737 gl::Context *context = gl::getContext();
1738
1739 if (context)
1740 {
1741 context->drawArrays(mode, first, count);
1742 }
1743 }
1744 catch(std::bad_alloc&)
1745 {
1746 return error(GL_OUT_OF_MEMORY);
1747 }
1748}
1749
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001750void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001751{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001752 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 +00001753 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001754
1755 try
1756 {
1757 if (count < 0)
1758 {
1759 return error(GL_INVALID_VALUE);
1760 }
1761
1762 switch (type)
1763 {
1764 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001765 case GL_UNSIGNED_SHORT:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00001766 case GL_UNSIGNED_INT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001767 break;
1768 default:
1769 return error(GL_INVALID_ENUM);
1770 }
1771
1772 gl::Context *context = gl::getContext();
1773
1774 if (context)
1775 {
1776 context->drawElements(mode, count, type, indices);
1777 }
1778 }
1779 catch(std::bad_alloc&)
1780 {
1781 return error(GL_OUT_OF_MEMORY);
1782 }
1783}
1784
1785void __stdcall glEnable(GLenum cap)
1786{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001787 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001788
1789 try
1790 {
1791 gl::Context *context = gl::getContext();
1792
1793 if (context)
1794 {
1795 switch (cap)
1796 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001797 case GL_CULL_FACE: context->setCullFace(true); break;
1798 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1799 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1800 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1801 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1802 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1803 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1804 case GL_BLEND: context->setBlend(true); break;
1805 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001806 default:
1807 return error(GL_INVALID_ENUM);
1808 }
1809 }
1810 }
1811 catch(std::bad_alloc&)
1812 {
1813 return error(GL_OUT_OF_MEMORY);
1814 }
1815}
1816
1817void __stdcall glEnableVertexAttribArray(GLuint index)
1818{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001819 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001820
1821 try
1822 {
1823 if (index >= gl::MAX_VERTEX_ATTRIBS)
1824 {
1825 return error(GL_INVALID_VALUE);
1826 }
1827
1828 gl::Context *context = gl::getContext();
1829
1830 if (context)
1831 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001832 context->setVertexAttribEnabled(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001833 }
1834 }
1835 catch(std::bad_alloc&)
1836 {
1837 return error(GL_OUT_OF_MEMORY);
1838 }
1839}
1840
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001841void __stdcall glFinishFenceNV(GLuint fence)
1842{
1843 TRACE("(GLuint fence = %d)", fence);
1844
1845 try
1846 {
1847 gl::Context *context = gl::getContext();
1848
1849 if (context)
1850 {
1851 gl::Fence* fenceObject = context->getFence(fence);
1852
1853 if (fenceObject == NULL)
1854 {
1855 return error(GL_INVALID_OPERATION);
1856 }
1857
1858 fenceObject->finishFence();
1859 }
1860 }
1861 catch(std::bad_alloc&)
1862 {
1863 return error(GL_OUT_OF_MEMORY);
1864 }
1865}
1866
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001867void __stdcall glFinish(void)
1868{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001869 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001870
1871 try
1872 {
1873 gl::Context *context = gl::getContext();
1874
1875 if (context)
1876 {
1877 context->finish();
1878 }
1879 }
1880 catch(std::bad_alloc&)
1881 {
1882 return error(GL_OUT_OF_MEMORY);
1883 }
1884}
1885
1886void __stdcall glFlush(void)
1887{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001888 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001889
1890 try
1891 {
1892 gl::Context *context = gl::getContext();
1893
1894 if (context)
1895 {
1896 context->flush();
1897 }
1898 }
1899 catch(std::bad_alloc&)
1900 {
1901 return error(GL_OUT_OF_MEMORY);
1902 }
1903}
1904
1905void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1906{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001907 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1908 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001909
1910 try
1911 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001912 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1913 || renderbuffertarget != GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001914 {
1915 return error(GL_INVALID_ENUM);
1916 }
1917
1918 gl::Context *context = gl::getContext();
1919
1920 if (context)
1921 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001922 gl::Framebuffer *framebuffer = NULL;
1923 GLuint framebufferHandle = 0;
1924 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1925 {
1926 framebuffer = context->getReadFramebuffer();
1927 framebufferHandle = context->getReadFramebufferHandle();
1928 }
1929 else
1930 {
1931 framebuffer = context->getDrawFramebuffer();
1932 framebufferHandle = context->getDrawFramebufferHandle();
1933 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001934
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001935 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001936 {
1937 return error(GL_INVALID_OPERATION);
1938 }
1939
1940 switch (attachment)
1941 {
1942 case GL_COLOR_ATTACHMENT0:
1943 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1944 break;
1945 case GL_DEPTH_ATTACHMENT:
1946 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1947 break;
1948 case GL_STENCIL_ATTACHMENT:
1949 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1950 break;
1951 default:
1952 return error(GL_INVALID_ENUM);
1953 }
1954 }
1955 }
1956 catch(std::bad_alloc&)
1957 {
1958 return error(GL_OUT_OF_MEMORY);
1959 }
1960}
1961
1962void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1963{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001964 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1965 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001966
1967 try
1968 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001969 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001970 {
1971 return error(GL_INVALID_ENUM);
1972 }
1973
1974 switch (attachment)
1975 {
1976 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001977 case GL_DEPTH_ATTACHMENT:
1978 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001979 break;
1980 default:
1981 return error(GL_INVALID_ENUM);
1982 }
1983
1984 gl::Context *context = gl::getContext();
1985
1986 if (context)
1987 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001988 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001989 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001990 textarget = GL_NONE;
1991 }
1992 else
1993 {
1994 gl::Texture *tex = context->getTexture(texture);
1995
1996 if (tex == NULL)
1997 {
1998 return error(GL_INVALID_OPERATION);
1999 }
2000
daniel@transgaming.com01868132010-08-24 19:21:17 +00002001 if (tex->isCompressed())
2002 {
2003 return error(GL_INVALID_OPERATION);
2004 }
2005
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002006 switch (textarget)
2007 {
2008 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002009 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002010 {
2011 return error(GL_INVALID_OPERATION);
2012 }
2013 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002014
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002015 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002016 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002017 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002018 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002019 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002020 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002021 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2022 {
2023 return error(GL_INVALID_OPERATION);
2024 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002025 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002026
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002027 default:
2028 return error(GL_INVALID_ENUM);
2029 }
2030
2031 if (level != 0)
2032 {
2033 return error(GL_INVALID_VALUE);
2034 }
2035 }
2036
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002037 gl::Framebuffer *framebuffer = NULL;
2038 GLuint framebufferHandle = 0;
2039 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2040 {
2041 framebuffer = context->getReadFramebuffer();
2042 framebufferHandle = context->getReadFramebufferHandle();
2043 }
2044 else
2045 {
2046 framebuffer = context->getDrawFramebuffer();
2047 framebufferHandle = context->getDrawFramebufferHandle();
2048 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002049
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002050 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002051 {
2052 return error(GL_INVALID_OPERATION);
2053 }
2054
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002055 switch (attachment)
2056 {
2057 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2058 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2059 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2060 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002061 }
2062 }
2063 catch(std::bad_alloc&)
2064 {
2065 return error(GL_OUT_OF_MEMORY);
2066 }
2067}
2068
2069void __stdcall glFrontFace(GLenum mode)
2070{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002071 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002072
2073 try
2074 {
2075 switch (mode)
2076 {
2077 case GL_CW:
2078 case GL_CCW:
2079 {
2080 gl::Context *context = gl::getContext();
2081
2082 if (context)
2083 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002084 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002085 }
2086 }
2087 break;
2088 default:
2089 return error(GL_INVALID_ENUM);
2090 }
2091 }
2092 catch(std::bad_alloc&)
2093 {
2094 return error(GL_OUT_OF_MEMORY);
2095 }
2096}
2097
2098void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2099{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002100 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002101
2102 try
2103 {
2104 if (n < 0)
2105 {
2106 return error(GL_INVALID_VALUE);
2107 }
2108
2109 gl::Context *context = gl::getContext();
2110
2111 if (context)
2112 {
2113 for (int i = 0; i < n; i++)
2114 {
2115 buffers[i] = context->createBuffer();
2116 }
2117 }
2118 }
2119 catch(std::bad_alloc&)
2120 {
2121 return error(GL_OUT_OF_MEMORY);
2122 }
2123}
2124
2125void __stdcall glGenerateMipmap(GLenum target)
2126{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002127 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002128
2129 try
2130 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002131 gl::Context *context = gl::getContext();
2132
2133 if (context)
2134 {
2135 gl::Texture *texture;
2136
2137 switch (target)
2138 {
2139 case GL_TEXTURE_2D:
2140 texture = context->getTexture2D();
2141 break;
2142
2143 case GL_TEXTURE_CUBE_MAP:
2144 texture = context->getTextureCubeMap();
2145 break;
2146
2147 default:
2148 return error(GL_INVALID_ENUM);
2149 }
2150
daniel@transgaming.com01868132010-08-24 19:21:17 +00002151 if (texture->isCompressed())
2152 {
2153 return error(GL_INVALID_OPERATION);
2154 }
2155
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002156 texture->generateMipmaps();
2157 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002158 }
2159 catch(std::bad_alloc&)
2160 {
2161 return error(GL_OUT_OF_MEMORY);
2162 }
2163}
2164
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002165void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2166{
2167 TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
2168
2169 try
2170 {
2171 if (n < 0)
2172 {
2173 return error(GL_INVALID_VALUE);
2174 }
2175
2176 gl::Context *context = gl::getContext();
2177
2178 if (context)
2179 {
2180 for (int i = 0; i < n; i++)
2181 {
2182 fences[i] = context->createFence();
2183 }
2184 }
2185 }
2186 catch(std::bad_alloc&)
2187 {
2188 return error(GL_OUT_OF_MEMORY);
2189 }
2190}
2191
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002192void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2193{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002194 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002195
2196 try
2197 {
2198 if (n < 0)
2199 {
2200 return error(GL_INVALID_VALUE);
2201 }
2202
2203 gl::Context *context = gl::getContext();
2204
2205 if (context)
2206 {
2207 for (int i = 0; i < n; i++)
2208 {
2209 framebuffers[i] = context->createFramebuffer();
2210 }
2211 }
2212 }
2213 catch(std::bad_alloc&)
2214 {
2215 return error(GL_OUT_OF_MEMORY);
2216 }
2217}
2218
2219void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2220{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002221 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002222
2223 try
2224 {
2225 if (n < 0)
2226 {
2227 return error(GL_INVALID_VALUE);
2228 }
2229
2230 gl::Context *context = gl::getContext();
2231
2232 if (context)
2233 {
2234 for (int i = 0; i < n; i++)
2235 {
2236 renderbuffers[i] = context->createRenderbuffer();
2237 }
2238 }
2239 }
2240 catch(std::bad_alloc&)
2241 {
2242 return error(GL_OUT_OF_MEMORY);
2243 }
2244}
2245
2246void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2247{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002248 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002249
2250 try
2251 {
2252 if (n < 0)
2253 {
2254 return error(GL_INVALID_VALUE);
2255 }
2256
2257 gl::Context *context = gl::getContext();
2258
2259 if (context)
2260 {
2261 for (int i = 0; i < n; i++)
2262 {
2263 textures[i] = context->createTexture();
2264 }
2265 }
2266 }
2267 catch(std::bad_alloc&)
2268 {
2269 return error(GL_OUT_OF_MEMORY);
2270 }
2271}
2272
daniel@transgaming.com85423182010-04-22 13:35:27 +00002273void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002274{
daniel@transgaming.com85423182010-04-22 13:35:27 +00002275 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2276 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002277 program, index, bufsize, length, size, type, name);
2278
2279 try
2280 {
2281 if (bufsize < 0)
2282 {
2283 return error(GL_INVALID_VALUE);
2284 }
2285
daniel@transgaming.com85423182010-04-22 13:35:27 +00002286 gl::Context *context = gl::getContext();
2287
2288 if (context)
2289 {
2290 gl::Program *programObject = context->getProgram(program);
2291
2292 if (!programObject)
2293 {
2294 if (context->getShader(program))
2295 {
2296 return error(GL_INVALID_OPERATION);
2297 }
2298 else
2299 {
2300 return error(GL_INVALID_VALUE);
2301 }
2302 }
2303
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002304 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002305 {
2306 return error(GL_INVALID_VALUE);
2307 }
2308
2309 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2310 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002311 }
2312 catch(std::bad_alloc&)
2313 {
2314 return error(GL_OUT_OF_MEMORY);
2315 }
2316}
2317
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002318void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002319{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002320 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002321 "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 +00002322 program, index, bufsize, length, size, type, name);
2323
2324 try
2325 {
2326 if (bufsize < 0)
2327 {
2328 return error(GL_INVALID_VALUE);
2329 }
2330
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002331 gl::Context *context = gl::getContext();
2332
2333 if (context)
2334 {
2335 gl::Program *programObject = context->getProgram(program);
2336
2337 if (!programObject)
2338 {
2339 if (context->getShader(program))
2340 {
2341 return error(GL_INVALID_OPERATION);
2342 }
2343 else
2344 {
2345 return error(GL_INVALID_VALUE);
2346 }
2347 }
2348
2349 if (index >= (GLuint)programObject->getActiveUniformCount())
2350 {
2351 return error(GL_INVALID_VALUE);
2352 }
2353
2354 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2355 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002356 }
2357 catch(std::bad_alloc&)
2358 {
2359 return error(GL_OUT_OF_MEMORY);
2360 }
2361}
2362
2363void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2364{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002365 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2366 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002367
2368 try
2369 {
2370 if (maxcount < 0)
2371 {
2372 return error(GL_INVALID_VALUE);
2373 }
2374
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002375 gl::Context *context = gl::getContext();
2376
2377 if (context)
2378 {
2379 gl::Program *programObject = context->getProgram(program);
2380
2381 if (!programObject)
2382 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002383 if (context->getShader(program))
2384 {
2385 return error(GL_INVALID_OPERATION);
2386 }
2387 else
2388 {
2389 return error(GL_INVALID_VALUE);
2390 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002391 }
2392
2393 return programObject->getAttachedShaders(maxcount, count, shaders);
2394 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002395 }
2396 catch(std::bad_alloc&)
2397 {
2398 return error(GL_OUT_OF_MEMORY);
2399 }
2400}
2401
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002402int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002403{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002404 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002405
2406 try
2407 {
2408 gl::Context *context = gl::getContext();
2409
2410 if (context)
2411 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002412
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002413 gl::Program *programObject = context->getProgram(program);
2414
2415 if (!programObject)
2416 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002417 if (context->getShader(program))
2418 {
2419 return error(GL_INVALID_OPERATION, -1);
2420 }
2421 else
2422 {
2423 return error(GL_INVALID_VALUE, -1);
2424 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002425 }
2426
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002427 if (!programObject->isLinked())
2428 {
2429 return error(GL_INVALID_OPERATION, -1);
2430 }
2431
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002432 return programObject->getAttributeLocation(name);
2433 }
2434 }
2435 catch(std::bad_alloc&)
2436 {
2437 return error(GL_OUT_OF_MEMORY, -1);
2438 }
2439
2440 return -1;
2441}
2442
2443void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2444{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002445 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002446
2447 try
2448 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002449 gl::Context *context = gl::getContext();
2450
2451 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002452 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002453 if (!(context->getBooleanv(pname, params)))
2454 {
2455 GLenum nativeType;
2456 unsigned int numParams = 0;
2457 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2458 return error(GL_INVALID_ENUM);
2459
2460 if (numParams == 0)
2461 return; // it is known that the pname is valid, but there are no parameters to return
2462
2463 if (nativeType == GL_FLOAT)
2464 {
2465 GLfloat *floatParams = NULL;
2466 floatParams = new GLfloat[numParams];
2467
2468 context->getFloatv(pname, floatParams);
2469
2470 for (unsigned int i = 0; i < numParams; ++i)
2471 {
2472 if (floatParams[i] == 0.0f)
2473 params[i] = GL_FALSE;
2474 else
2475 params[i] = GL_TRUE;
2476 }
2477
2478 delete [] floatParams;
2479 }
2480 else if (nativeType == GL_INT)
2481 {
2482 GLint *intParams = NULL;
2483 intParams = new GLint[numParams];
2484
2485 context->getIntegerv(pname, intParams);
2486
2487 for (unsigned int i = 0; i < numParams; ++i)
2488 {
2489 if (intParams[i] == 0)
2490 params[i] = GL_FALSE;
2491 else
2492 params[i] = GL_TRUE;
2493 }
2494
2495 delete [] intParams;
2496 }
2497 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002498 }
2499 }
2500 catch(std::bad_alloc&)
2501 {
2502 return error(GL_OUT_OF_MEMORY);
2503 }
2504}
2505
2506void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2507{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002508 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 +00002509
2510 try
2511 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002512 gl::Context *context = gl::getContext();
2513
2514 if (context)
2515 {
2516 gl::Buffer *buffer;
2517
2518 switch (target)
2519 {
2520 case GL_ARRAY_BUFFER:
2521 buffer = context->getArrayBuffer();
2522 break;
2523 case GL_ELEMENT_ARRAY_BUFFER:
2524 buffer = context->getElementArrayBuffer();
2525 break;
2526 default: return error(GL_INVALID_ENUM);
2527 }
2528
2529 if (!buffer)
2530 {
2531 // A null buffer means that "0" is bound to the requested buffer target
2532 return error(GL_INVALID_OPERATION);
2533 }
2534
2535 switch (pname)
2536 {
2537 case GL_BUFFER_USAGE:
2538 *params = buffer->usage();
2539 break;
2540 case GL_BUFFER_SIZE:
2541 *params = buffer->size();
2542 break;
2543 default: return error(GL_INVALID_ENUM);
2544 }
2545 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002546 }
2547 catch(std::bad_alloc&)
2548 {
2549 return error(GL_OUT_OF_MEMORY);
2550 }
2551}
2552
2553GLenum __stdcall glGetError(void)
2554{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002555 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002556
2557 gl::Context *context = gl::getContext();
2558
2559 if (context)
2560 {
2561 return context->getError();
2562 }
2563
2564 return GL_NO_ERROR;
2565}
2566
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002567void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2568{
2569 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
2570
2571 try
2572 {
2573
2574 gl::Context *context = gl::getContext();
2575
2576 if (context)
2577 {
2578 gl::Fence *fenceObject = context->getFence(fence);
2579
2580 if (fenceObject == NULL)
2581 {
2582 return error(GL_INVALID_OPERATION);
2583 }
2584
2585 fenceObject->getFenceiv(pname, params);
2586 }
2587 }
2588 catch(std::bad_alloc&)
2589 {
2590 return error(GL_OUT_OF_MEMORY);
2591 }
2592}
2593
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002594void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2595{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002596 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002597
2598 try
2599 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002600 gl::Context *context = gl::getContext();
2601
2602 if (context)
2603 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002604 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002605 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002606 GLenum nativeType;
2607 unsigned int numParams = 0;
2608 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2609 return error(GL_INVALID_ENUM);
2610
2611 if (numParams == 0)
2612 return; // it is known that the pname is valid, but that there are no parameters to return.
2613
2614 if (nativeType == GL_BOOL)
2615 {
2616 GLboolean *boolParams = NULL;
2617 boolParams = new GLboolean[numParams];
2618
2619 context->getBooleanv(pname, boolParams);
2620
2621 for (unsigned int i = 0; i < numParams; ++i)
2622 {
2623 if (boolParams[i] == GL_FALSE)
2624 params[i] = 0.0f;
2625 else
2626 params[i] = 1.0f;
2627 }
2628
2629 delete [] boolParams;
2630 }
2631 else if (nativeType == GL_INT)
2632 {
2633 GLint *intParams = NULL;
2634 intParams = new GLint[numParams];
2635
2636 context->getIntegerv(pname, intParams);
2637
2638 for (unsigned int i = 0; i < numParams; ++i)
2639 {
2640 params[i] = (GLfloat)intParams[i];
2641 }
2642
2643 delete [] intParams;
2644 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002645 }
2646 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002647 }
2648 catch(std::bad_alloc&)
2649 {
2650 return error(GL_OUT_OF_MEMORY);
2651 }
2652}
2653
2654void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2655{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002656 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2657 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002658
2659 try
2660 {
2661 gl::Context *context = gl::getContext();
2662
2663 if (context)
2664 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002665 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002666 {
2667 return error(GL_INVALID_ENUM);
2668 }
2669
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002670 gl::Framebuffer *framebuffer = NULL;
2671 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2672 {
2673 if(context->getReadFramebufferHandle() == 0)
2674 {
2675 return error(GL_INVALID_OPERATION);
2676 }
2677
2678 framebuffer = context->getReadFramebuffer();
2679 }
2680 else
2681 {
2682 if (context->getDrawFramebufferHandle() == 0)
2683 {
2684 return error(GL_INVALID_OPERATION);
2685 }
2686
2687 framebuffer = context->getDrawFramebuffer();
2688 }
2689
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002690 GLenum attachmentType;
2691 GLuint attachmentHandle;
2692 switch (attachment)
2693 {
2694 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002695 attachmentType = framebuffer->getColorbufferType();
2696 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002697 break;
2698 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002699 attachmentType = framebuffer->getDepthbufferType();
2700 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002701 break;
2702 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002703 attachmentType = framebuffer->getStencilbufferType();
2704 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002705 break;
2706 default: return error(GL_INVALID_ENUM);
2707 }
2708
2709 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002710 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002711 {
2712 attachmentObjectType = attachmentType;
2713 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002714 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002715 {
2716 attachmentObjectType = GL_TEXTURE;
2717 }
2718 else UNREACHABLE();
2719
2720 switch (pname)
2721 {
2722 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2723 *params = attachmentObjectType;
2724 break;
2725 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2726 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2727 {
2728 *params = attachmentHandle;
2729 }
2730 else
2731 {
2732 return error(GL_INVALID_ENUM);
2733 }
2734 break;
2735 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2736 if (attachmentObjectType == GL_TEXTURE)
2737 {
2738 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2739 }
2740 else
2741 {
2742 return error(GL_INVALID_ENUM);
2743 }
2744 break;
2745 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2746 if (attachmentObjectType == GL_TEXTURE)
2747 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002748 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002749 {
2750 *params = attachmentType;
2751 }
2752 else
2753 {
2754 *params = 0;
2755 }
2756 }
2757 else
2758 {
2759 return error(GL_INVALID_ENUM);
2760 }
2761 break;
2762 default:
2763 return error(GL_INVALID_ENUM);
2764 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002765 }
2766 }
2767 catch(std::bad_alloc&)
2768 {
2769 return error(GL_OUT_OF_MEMORY);
2770 }
2771}
2772
2773void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2774{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002775 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002776
2777 try
2778 {
2779 gl::Context *context = gl::getContext();
2780
2781 if (context)
2782 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002783 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002784 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002785 GLenum nativeType;
2786 unsigned int numParams = 0;
2787 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2788 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002789
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002790 if (numParams == 0)
2791 return; // it is known that pname is valid, but there are no parameters to return
2792
2793 if (nativeType == GL_BOOL)
2794 {
2795 GLboolean *boolParams = NULL;
2796 boolParams = new GLboolean[numParams];
2797
2798 context->getBooleanv(pname, boolParams);
2799
2800 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002801 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002802 if (boolParams[i] == GL_FALSE)
2803 params[i] = 0;
2804 else
2805 params[i] = 1;
2806 }
2807
2808 delete [] boolParams;
2809 }
2810 else if (nativeType == GL_FLOAT)
2811 {
2812 GLfloat *floatParams = NULL;
2813 floatParams = new GLfloat[numParams];
2814
2815 context->getFloatv(pname, floatParams);
2816
2817 for (unsigned int i = 0; i < numParams; ++i)
2818 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002819 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 +00002820 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002821 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002822 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002823 else
2824 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 +00002825 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002826
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002827 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002828 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002829 }
2830 }
2831 }
2832 catch(std::bad_alloc&)
2833 {
2834 return error(GL_OUT_OF_MEMORY);
2835 }
2836}
2837
2838void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2839{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002840 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002841
2842 try
2843 {
2844 gl::Context *context = gl::getContext();
2845
2846 if (context)
2847 {
2848 gl::Program *programObject = context->getProgram(program);
2849
2850 if (!programObject)
2851 {
2852 return error(GL_INVALID_VALUE);
2853 }
2854
2855 switch (pname)
2856 {
2857 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002858 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002859 return;
2860 case GL_LINK_STATUS:
2861 *params = programObject->isLinked();
2862 return;
2863 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002864 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002865 return;
2866 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002867 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002868 return;
2869 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002870 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002871 return;
2872 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002873 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002874 return;
2875 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002876 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002877 return;
2878 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002879 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002880 return;
2881 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002882 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002883 return;
2884 default:
2885 return error(GL_INVALID_ENUM);
2886 }
2887 }
2888 }
2889 catch(std::bad_alloc&)
2890 {
2891 return error(GL_OUT_OF_MEMORY);
2892 }
2893}
2894
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002895void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002896{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002897 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 +00002898 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002899
2900 try
2901 {
2902 if (bufsize < 0)
2903 {
2904 return error(GL_INVALID_VALUE);
2905 }
2906
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002907 gl::Context *context = gl::getContext();
2908
2909 if (context)
2910 {
2911 gl::Program *programObject = context->getProgram(program);
2912
2913 if (!programObject)
2914 {
2915 return error(GL_INVALID_VALUE);
2916 }
2917
2918 programObject->getInfoLog(bufsize, length, infolog);
2919 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002920 }
2921 catch(std::bad_alloc&)
2922 {
2923 return error(GL_OUT_OF_MEMORY);
2924 }
2925}
2926
2927void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2928{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002929 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 +00002930
2931 try
2932 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002933 gl::Context *context = gl::getContext();
2934
2935 if (context)
2936 {
2937 if (target != GL_RENDERBUFFER)
2938 {
2939 return error(GL_INVALID_ENUM);
2940 }
2941
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002942 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002943 {
2944 return error(GL_INVALID_OPERATION);
2945 }
2946
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002947 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002948
2949 switch (pname)
2950 {
2951 case GL_RENDERBUFFER_WIDTH:
2952 *params = renderbuffer->getWidth();
2953 break;
2954 case GL_RENDERBUFFER_HEIGHT:
2955 *params = renderbuffer->getHeight();
2956 break;
2957 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2958 *params = renderbuffer->getFormat();
2959 break;
2960 case GL_RENDERBUFFER_RED_SIZE:
2961 if (renderbuffer->isColorbuffer())
2962 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002963 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002964 }
2965 else
2966 {
2967 *params = 0;
2968 }
2969 break;
2970 case GL_RENDERBUFFER_GREEN_SIZE:
2971 if (renderbuffer->isColorbuffer())
2972 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002973 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002974 }
2975 else
2976 {
2977 *params = 0;
2978 }
2979 break;
2980 case GL_RENDERBUFFER_BLUE_SIZE:
2981 if (renderbuffer->isColorbuffer())
2982 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002983 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002984 }
2985 else
2986 {
2987 *params = 0;
2988 }
2989 break;
2990 case GL_RENDERBUFFER_ALPHA_SIZE:
2991 if (renderbuffer->isColorbuffer())
2992 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002993 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002994 }
2995 else
2996 {
2997 *params = 0;
2998 }
2999 break;
3000 case GL_RENDERBUFFER_DEPTH_SIZE:
3001 if (renderbuffer->isDepthbuffer())
3002 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003003 *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003004 }
3005 else
3006 {
3007 *params = 0;
3008 }
3009 break;
3010 case GL_RENDERBUFFER_STENCIL_SIZE:
3011 if (renderbuffer->isStencilbuffer())
3012 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003013 *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003014 }
3015 else
3016 {
3017 *params = 0;
3018 }
3019 break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003020 case GL_RENDERBUFFER_SAMPLES_ANGLE:
3021 {
3022 if (context->getMaxSupportedSamples() != 0)
3023 {
3024 *params = renderbuffer->getStorage()->getSamples();
3025 }
3026 else
3027 {
3028 return error(GL_INVALID_ENUM);
3029 }
3030 }
3031 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003032 default:
3033 return error(GL_INVALID_ENUM);
3034 }
3035 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003036 }
3037 catch(std::bad_alloc&)
3038 {
3039 return error(GL_OUT_OF_MEMORY);
3040 }
3041}
3042
3043void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3044{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003045 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003046
3047 try
3048 {
3049 gl::Context *context = gl::getContext();
3050
3051 if (context)
3052 {
3053 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003054
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003055 if (!shaderObject)
3056 {
3057 return error(GL_INVALID_VALUE);
3058 }
3059
3060 switch (pname)
3061 {
3062 case GL_SHADER_TYPE:
3063 *params = shaderObject->getType();
3064 return;
3065 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003066 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003067 return;
3068 case GL_COMPILE_STATUS:
3069 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3070 return;
3071 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003072 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003073 return;
3074 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003075 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003076 return;
3077 default:
3078 return error(GL_INVALID_ENUM);
3079 }
3080 }
3081 }
3082 catch(std::bad_alloc&)
3083 {
3084 return error(GL_OUT_OF_MEMORY);
3085 }
3086}
3087
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003088void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003089{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003090 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 +00003091 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003092
3093 try
3094 {
3095 if (bufsize < 0)
3096 {
3097 return error(GL_INVALID_VALUE);
3098 }
3099
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003100 gl::Context *context = gl::getContext();
3101
3102 if (context)
3103 {
3104 gl::Shader *shaderObject = context->getShader(shader);
3105
3106 if (!shaderObject)
3107 {
3108 return error(GL_INVALID_VALUE);
3109 }
3110
3111 shaderObject->getInfoLog(bufsize, length, infolog);
3112 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003113 }
3114 catch(std::bad_alloc&)
3115 {
3116 return error(GL_OUT_OF_MEMORY);
3117 }
3118}
3119
3120void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3121{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003122 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
3123 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003124
3125 try
3126 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003127 switch (shadertype)
3128 {
3129 case GL_VERTEX_SHADER:
3130 case GL_FRAGMENT_SHADER:
3131 break;
3132 default:
3133 return error(GL_INVALID_ENUM);
3134 }
3135
3136 switch (precisiontype)
3137 {
3138 case GL_LOW_FLOAT:
3139 case GL_MEDIUM_FLOAT:
3140 case GL_HIGH_FLOAT:
3141 // Assume IEEE 754 precision
3142 range[0] = 127;
3143 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003144 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003145 break;
3146 case GL_LOW_INT:
3147 case GL_MEDIUM_INT:
3148 case GL_HIGH_INT:
3149 // Some (most) hardware only supports single-precision floating-point numbers,
3150 // which can accurately represent integers up to +/-16777216
3151 range[0] = 24;
3152 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003153 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003154 break;
3155 default:
3156 return error(GL_INVALID_ENUM);
3157 }
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
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003165void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003166{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003167 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 +00003168 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003169
3170 try
3171 {
3172 if (bufsize < 0)
3173 {
3174 return error(GL_INVALID_VALUE);
3175 }
3176
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003177 gl::Context *context = gl::getContext();
3178
3179 if (context)
3180 {
3181 gl::Shader *shaderObject = context->getShader(shader);
3182
3183 if (!shaderObject)
3184 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003185 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003186 }
3187
3188 shaderObject->getSource(bufsize, length, source);
3189 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003190 }
3191 catch(std::bad_alloc&)
3192 {
3193 return error(GL_OUT_OF_MEMORY);
3194 }
3195}
3196
3197const GLubyte* __stdcall glGetString(GLenum name)
3198{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003199 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003200
3201 try
3202 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003203 gl::Context *context = gl::getContext();
3204
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003205 switch (name)
3206 {
3207 case GL_VENDOR:
3208 return (GLubyte*)"TransGaming Inc.";
3209 case GL_RENDERER:
3210 return (GLubyte*)"ANGLE";
3211 case GL_VERSION:
3212 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
3213 case GL_SHADING_LANGUAGE_VERSION:
3214 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
3215 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003216 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003217 default:
3218 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3219 }
3220 }
3221 catch(std::bad_alloc&)
3222 {
3223 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3224 }
3225
3226 return NULL;
3227}
3228
3229void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3230{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003231 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 +00003232
3233 try
3234 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003235 gl::Context *context = gl::getContext();
3236
3237 if (context)
3238 {
3239 gl::Texture *texture;
3240
3241 switch (target)
3242 {
3243 case GL_TEXTURE_2D:
3244 texture = context->getTexture2D();
3245 break;
3246 case GL_TEXTURE_CUBE_MAP:
3247 texture = context->getTextureCubeMap();
3248 break;
3249 default:
3250 return error(GL_INVALID_ENUM);
3251 }
3252
3253 switch (pname)
3254 {
3255 case GL_TEXTURE_MAG_FILTER:
3256 *params = (GLfloat)texture->getMagFilter();
3257 break;
3258 case GL_TEXTURE_MIN_FILTER:
3259 *params = (GLfloat)texture->getMinFilter();
3260 break;
3261 case GL_TEXTURE_WRAP_S:
3262 *params = (GLfloat)texture->getWrapS();
3263 break;
3264 case GL_TEXTURE_WRAP_T:
3265 *params = (GLfloat)texture->getWrapT();
3266 break;
3267 default:
3268 return error(GL_INVALID_ENUM);
3269 }
3270 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003271 }
3272 catch(std::bad_alloc&)
3273 {
3274 return error(GL_OUT_OF_MEMORY);
3275 }
3276}
3277
3278void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3279{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003280 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 +00003281
3282 try
3283 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003284 gl::Context *context = gl::getContext();
3285
3286 if (context)
3287 {
3288 gl::Texture *texture;
3289
3290 switch (target)
3291 {
3292 case GL_TEXTURE_2D:
3293 texture = context->getTexture2D();
3294 break;
3295 case GL_TEXTURE_CUBE_MAP:
3296 texture = context->getTextureCubeMap();
3297 break;
3298 default:
3299 return error(GL_INVALID_ENUM);
3300 }
3301
3302 switch (pname)
3303 {
3304 case GL_TEXTURE_MAG_FILTER:
3305 *params = texture->getMagFilter();
3306 break;
3307 case GL_TEXTURE_MIN_FILTER:
3308 *params = texture->getMinFilter();
3309 break;
3310 case GL_TEXTURE_WRAP_S:
3311 *params = texture->getWrapS();
3312 break;
3313 case GL_TEXTURE_WRAP_T:
3314 *params = texture->getWrapT();
3315 break;
3316 default:
3317 return error(GL_INVALID_ENUM);
3318 }
3319 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003320 }
3321 catch(std::bad_alloc&)
3322 {
3323 return error(GL_OUT_OF_MEMORY);
3324 }
3325}
3326
3327void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3328{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003329 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003330
3331 try
3332 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003333 gl::Context *context = gl::getContext();
3334
3335 if (context)
3336 {
3337 if (program == 0)
3338 {
3339 return error(GL_INVALID_VALUE);
3340 }
3341
3342 gl::Program *programObject = context->getProgram(program);
3343
3344 if (!programObject || !programObject->isLinked())
3345 {
3346 return error(GL_INVALID_OPERATION);
3347 }
3348
3349 if (!programObject->getUniformfv(location, params))
3350 {
3351 return error(GL_INVALID_OPERATION);
3352 }
3353 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003354 }
3355 catch(std::bad_alloc&)
3356 {
3357 return error(GL_OUT_OF_MEMORY);
3358 }
3359}
3360
3361void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3362{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003363 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003364
3365 try
3366 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003367 gl::Context *context = gl::getContext();
3368
3369 if (context)
3370 {
3371 if (program == 0)
3372 {
3373 return error(GL_INVALID_VALUE);
3374 }
3375
3376 gl::Program *programObject = context->getProgram(program);
3377
3378 if (!programObject || !programObject->isLinked())
3379 {
3380 return error(GL_INVALID_OPERATION);
3381 }
3382
3383 if (!programObject)
3384 {
3385 return error(GL_INVALID_OPERATION);
3386 }
3387
3388 if (!programObject->getUniformiv(location, params))
3389 {
3390 return error(GL_INVALID_OPERATION);
3391 }
3392 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003393 }
3394 catch(std::bad_alloc&)
3395 {
3396 return error(GL_OUT_OF_MEMORY);
3397 }
3398}
3399
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003400int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003401{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003402 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003403
3404 try
3405 {
3406 gl::Context *context = gl::getContext();
3407
3408 if (strstr(name, "gl_") == name)
3409 {
3410 return -1;
3411 }
3412
3413 if (context)
3414 {
3415 gl::Program *programObject = context->getProgram(program);
3416
3417 if (!programObject)
3418 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003419 if (context->getShader(program))
3420 {
3421 return error(GL_INVALID_OPERATION, -1);
3422 }
3423 else
3424 {
3425 return error(GL_INVALID_VALUE, -1);
3426 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003427 }
3428
3429 if (!programObject->isLinked())
3430 {
3431 return error(GL_INVALID_OPERATION, -1);
3432 }
3433
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003434 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003435 }
3436 }
3437 catch(std::bad_alloc&)
3438 {
3439 return error(GL_OUT_OF_MEMORY, -1);
3440 }
3441
3442 return -1;
3443}
3444
3445void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3446{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003447 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003448
3449 try
3450 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003451 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003452
daniel@transgaming.come0078962010-04-15 20:45:08 +00003453 if (context)
3454 {
3455 if (index >= gl::MAX_VERTEX_ATTRIBS)
3456 {
3457 return error(GL_INVALID_VALUE);
3458 }
3459
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003460 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003461
daniel@transgaming.come0078962010-04-15 20:45:08 +00003462 switch (pname)
3463 {
3464 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003465 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003466 break;
3467 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003468 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003469 break;
3470 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003471 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003472 break;
3473 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003474 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003475 break;
3476 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003477 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003478 break;
3479 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003480 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003481 break;
3482 case GL_CURRENT_VERTEX_ATTRIB:
3483 for (int i = 0; i < 4; ++i)
3484 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003485 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003486 }
3487 break;
3488 default: return error(GL_INVALID_ENUM);
3489 }
3490 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003491 }
3492 catch(std::bad_alloc&)
3493 {
3494 return error(GL_OUT_OF_MEMORY);
3495 }
3496}
3497
3498void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3499{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003500 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003501
3502 try
3503 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003504 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003505
daniel@transgaming.come0078962010-04-15 20:45:08 +00003506 if (context)
3507 {
3508 if (index >= gl::MAX_VERTEX_ATTRIBS)
3509 {
3510 return error(GL_INVALID_VALUE);
3511 }
3512
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003513 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003514
daniel@transgaming.come0078962010-04-15 20:45:08 +00003515 switch (pname)
3516 {
3517 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003518 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003519 break;
3520 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003521 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003522 break;
3523 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003524 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003525 break;
3526 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003527 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003528 break;
3529 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003530 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003531 break;
3532 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003533 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003534 break;
3535 case GL_CURRENT_VERTEX_ATTRIB:
3536 for (int i = 0; i < 4; ++i)
3537 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003538 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003539 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3540 }
3541 break;
3542 default: return error(GL_INVALID_ENUM);
3543 }
3544 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003545 }
3546 catch(std::bad_alloc&)
3547 {
3548 return error(GL_OUT_OF_MEMORY);
3549 }
3550}
3551
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003552void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003553{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003554 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003555
3556 try
3557 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003558 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003559
daniel@transgaming.come0078962010-04-15 20:45:08 +00003560 if (context)
3561 {
3562 if (index >= gl::MAX_VERTEX_ATTRIBS)
3563 {
3564 return error(GL_INVALID_VALUE);
3565 }
3566
3567 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3568 {
3569 return error(GL_INVALID_ENUM);
3570 }
3571
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003572 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003573 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003574 }
3575 catch(std::bad_alloc&)
3576 {
3577 return error(GL_OUT_OF_MEMORY);
3578 }
3579}
3580
3581void __stdcall glHint(GLenum target, GLenum mode)
3582{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003583 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003584
3585 try
3586 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003587 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003588 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003589 case GL_FASTEST:
3590 case GL_NICEST:
3591 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003592 break;
3593 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003594 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003595 }
3596
3597 gl::Context *context = gl::getContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003598 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003599 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003600 case GL_GENERATE_MIPMAP_HINT:
3601 if (context) context->setGenerateMipmapHint(mode);
3602 break;
3603 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3604 if (context) context->setFragmentShaderDerivativeHint(mode);
3605 break;
3606 default:
3607 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003608 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003609 }
3610 catch(std::bad_alloc&)
3611 {
3612 return error(GL_OUT_OF_MEMORY);
3613 }
3614}
3615
3616GLboolean __stdcall glIsBuffer(GLuint buffer)
3617{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003618 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003619
3620 try
3621 {
3622 gl::Context *context = gl::getContext();
3623
3624 if (context && buffer)
3625 {
3626 gl::Buffer *bufferObject = context->getBuffer(buffer);
3627
3628 if (bufferObject)
3629 {
3630 return GL_TRUE;
3631 }
3632 }
3633 }
3634 catch(std::bad_alloc&)
3635 {
3636 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3637 }
3638
3639 return GL_FALSE;
3640}
3641
3642GLboolean __stdcall glIsEnabled(GLenum cap)
3643{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003644 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003645
3646 try
3647 {
3648 gl::Context *context = gl::getContext();
3649
3650 if (context)
3651 {
3652 switch (cap)
3653 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003654 case GL_CULL_FACE: return context->isCullFaceEnabled();
3655 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3656 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3657 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3658 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3659 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3660 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3661 case GL_BLEND: return context->isBlendEnabled();
3662 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003663 default:
3664 return error(GL_INVALID_ENUM, false);
3665 }
3666 }
3667 }
3668 catch(std::bad_alloc&)
3669 {
3670 return error(GL_OUT_OF_MEMORY, false);
3671 }
3672
3673 return false;
3674}
3675
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003676GLboolean __stdcall glIsFenceNV(GLuint fence)
3677{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003678 TRACE("(GLuint fence = %d)", fence);
3679
3680 try
3681 {
3682 gl::Context *context = gl::getContext();
3683
3684 if (context)
3685 {
3686 gl::Fence *fenceObject = context->getFence(fence);
3687
3688 if (fenceObject == NULL)
3689 {
3690 return GL_FALSE;
3691 }
3692
3693 return fenceObject->isFence();
3694 }
3695 }
3696 catch(std::bad_alloc&)
3697 {
3698 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3699 }
3700
3701 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003702}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003703
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003704GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3705{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003706 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003707
3708 try
3709 {
3710 gl::Context *context = gl::getContext();
3711
3712 if (context && framebuffer)
3713 {
3714 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3715
3716 if (framebufferObject)
3717 {
3718 return GL_TRUE;
3719 }
3720 }
3721 }
3722 catch(std::bad_alloc&)
3723 {
3724 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3725 }
3726
3727 return GL_FALSE;
3728}
3729
3730GLboolean __stdcall glIsProgram(GLuint program)
3731{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003732 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003733
3734 try
3735 {
3736 gl::Context *context = gl::getContext();
3737
3738 if (context && program)
3739 {
3740 gl::Program *programObject = context->getProgram(program);
3741
3742 if (programObject)
3743 {
3744 return GL_TRUE;
3745 }
3746 }
3747 }
3748 catch(std::bad_alloc&)
3749 {
3750 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3751 }
3752
3753 return GL_FALSE;
3754}
3755
3756GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3757{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003758 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003759
3760 try
3761 {
3762 gl::Context *context = gl::getContext();
3763
3764 if (context && renderbuffer)
3765 {
3766 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3767
3768 if (renderbufferObject)
3769 {
3770 return GL_TRUE;
3771 }
3772 }
3773 }
3774 catch(std::bad_alloc&)
3775 {
3776 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3777 }
3778
3779 return GL_FALSE;
3780}
3781
3782GLboolean __stdcall glIsShader(GLuint shader)
3783{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003784 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003785
3786 try
3787 {
3788 gl::Context *context = gl::getContext();
3789
3790 if (context && shader)
3791 {
3792 gl::Shader *shaderObject = context->getShader(shader);
3793
3794 if (shaderObject)
3795 {
3796 return GL_TRUE;
3797 }
3798 }
3799 }
3800 catch(std::bad_alloc&)
3801 {
3802 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3803 }
3804
3805 return GL_FALSE;
3806}
3807
3808GLboolean __stdcall glIsTexture(GLuint texture)
3809{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003810 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003811
3812 try
3813 {
3814 gl::Context *context = gl::getContext();
3815
3816 if (context && texture)
3817 {
3818 gl::Texture *textureObject = context->getTexture(texture);
3819
3820 if (textureObject)
3821 {
3822 return GL_TRUE;
3823 }
3824 }
3825 }
3826 catch(std::bad_alloc&)
3827 {
3828 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3829 }
3830
3831 return GL_FALSE;
3832}
3833
3834void __stdcall glLineWidth(GLfloat width)
3835{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003836 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003837
3838 try
3839 {
3840 if (width <= 0.0f)
3841 {
3842 return error(GL_INVALID_VALUE);
3843 }
3844
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003845 gl::Context *context = gl::getContext();
3846
3847 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003848 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003849 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003850 }
3851 }
3852 catch(std::bad_alloc&)
3853 {
3854 return error(GL_OUT_OF_MEMORY);
3855 }
3856}
3857
3858void __stdcall glLinkProgram(GLuint program)
3859{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003860 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003861
3862 try
3863 {
3864 gl::Context *context = gl::getContext();
3865
3866 if (context)
3867 {
3868 gl::Program *programObject = context->getProgram(program);
3869
3870 if (!programObject)
3871 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003872 if (context->getShader(program))
3873 {
3874 return error(GL_INVALID_OPERATION);
3875 }
3876 else
3877 {
3878 return error(GL_INVALID_VALUE);
3879 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003880 }
3881
3882 programObject->link();
3883 }
3884 }
3885 catch(std::bad_alloc&)
3886 {
3887 return error(GL_OUT_OF_MEMORY);
3888 }
3889}
3890
3891void __stdcall glPixelStorei(GLenum pname, GLint param)
3892{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003893 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003894
3895 try
3896 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003897 gl::Context *context = gl::getContext();
3898
3899 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003900 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003901 switch (pname)
3902 {
3903 case GL_UNPACK_ALIGNMENT:
3904 if (param != 1 && param != 2 && param != 4 && param != 8)
3905 {
3906 return error(GL_INVALID_VALUE);
3907 }
3908
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003909 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003910 break;
3911
3912 case GL_PACK_ALIGNMENT:
3913 if (param != 1 && param != 2 && param != 4 && param != 8)
3914 {
3915 return error(GL_INVALID_VALUE);
3916 }
3917
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003918 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003919 break;
3920
3921 default:
3922 return error(GL_INVALID_ENUM);
3923 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003924 }
3925 }
3926 catch(std::bad_alloc&)
3927 {
3928 return error(GL_OUT_OF_MEMORY);
3929 }
3930}
3931
3932void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3933{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003934 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003935
3936 try
3937 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003938 gl::Context *context = gl::getContext();
3939
3940 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003941 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003942 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003943 }
3944 }
3945 catch(std::bad_alloc&)
3946 {
3947 return error(GL_OUT_OF_MEMORY);
3948 }
3949}
3950
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003951void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003952{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003953 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003954 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003955 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003956
3957 try
3958 {
3959 if (width < 0 || height < 0)
3960 {
3961 return error(GL_INVALID_VALUE);
3962 }
3963
3964 switch (format)
3965 {
3966 case GL_RGBA:
3967 switch (type)
3968 {
3969 case GL_UNSIGNED_BYTE:
3970 break;
3971 default:
3972 return error(GL_INVALID_OPERATION);
3973 }
3974 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003975 case GL_BGRA_EXT:
3976 switch (type)
3977 {
3978 case GL_UNSIGNED_BYTE:
3979 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3980 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3981 break;
3982 default:
3983 return error(GL_INVALID_OPERATION);
3984 }
3985 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003986 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3987 switch (type)
3988 {
3989 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3990 break;
3991 default:
3992 return error(GL_INVALID_OPERATION);
3993 }
3994 break;
3995 default:
3996 return error(GL_INVALID_OPERATION);
3997 }
3998
3999 gl::Context *context = gl::getContext();
4000
4001 if (context)
4002 {
4003 context->readPixels(x, y, width, height, format, type, pixels);
4004 }
4005 }
4006 catch(std::bad_alloc&)
4007 {
4008 return error(GL_OUT_OF_MEMORY);
4009 }
4010}
4011
4012void __stdcall glReleaseShaderCompiler(void)
4013{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004014 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004015
4016 try
4017 {
4018 gl::Shader::releaseCompiler();
4019 }
4020 catch(std::bad_alloc&)
4021 {
4022 return error(GL_OUT_OF_MEMORY);
4023 }
4024}
4025
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004026void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004027{
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004028 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4029 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004030
4031 try
4032 {
4033 switch (target)
4034 {
4035 case GL_RENDERBUFFER:
4036 break;
4037 default:
4038 return error(GL_INVALID_ENUM);
4039 }
4040
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004041 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004042 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004043 return error(GL_INVALID_ENUM);
4044 }
4045
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004046 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004047 {
4048 return error(GL_INVALID_VALUE);
4049 }
4050
4051 gl::Context *context = gl::getContext();
4052
4053 if (context)
4054 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004055 if (width > context->getMaximumRenderbufferDimension() ||
4056 height > context->getMaximumRenderbufferDimension() ||
4057 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004058 {
4059 return error(GL_INVALID_VALUE);
4060 }
4061
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004062 GLuint handle = context->getRenderbufferHandle();
4063 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004064 {
4065 return error(GL_INVALID_OPERATION);
4066 }
4067
4068 switch (internalformat)
4069 {
4070 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004071 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004072 break;
4073 case GL_RGBA4:
4074 case GL_RGB5_A1:
4075 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004076 case GL_RGB8_OES:
4077 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004078 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004079 break;
4080 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004081 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004082 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004083 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004084 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004085 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004086 default:
4087 return error(GL_INVALID_ENUM);
4088 }
4089 }
4090 }
4091 catch(std::bad_alloc&)
4092 {
4093 return error(GL_OUT_OF_MEMORY);
4094 }
4095}
4096
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004097void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4098{
4099 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4100}
4101
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004102void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4103{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004104 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004105
4106 try
4107 {
4108 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004109
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004110 if (context)
4111 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004112 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004113 }
4114 }
4115 catch(std::bad_alloc&)
4116 {
4117 return error(GL_OUT_OF_MEMORY);
4118 }
4119}
4120
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004121void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4122{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004123 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
4124
4125 try
4126 {
4127 if (condition != GL_ALL_COMPLETED_NV)
4128 {
4129 return error(GL_INVALID_ENUM);
4130 }
4131
4132 gl::Context *context = gl::getContext();
4133
4134 if (context)
4135 {
4136 gl::Fence *fenceObject = context->getFence(fence);
4137
4138 if (fenceObject == NULL)
4139 {
4140 return error(GL_INVALID_OPERATION);
4141 }
4142
4143 fenceObject->setFence(condition);
4144 }
4145 }
4146 catch(std::bad_alloc&)
4147 {
4148 return error(GL_OUT_OF_MEMORY);
4149 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004150}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004151
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004152void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4153{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004154 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 +00004155
4156 try
4157 {
4158 if (width < 0 || height < 0)
4159 {
4160 return error(GL_INVALID_VALUE);
4161 }
4162
4163 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004164
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004165 if (context)
4166 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004167 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004168 }
4169 }
4170 catch(std::bad_alloc&)
4171 {
4172 return error(GL_OUT_OF_MEMORY);
4173 }
4174}
4175
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004176void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004177{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004178 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004179 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004180 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004181
4182 try
4183 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004184 // No binary shader formats are supported.
4185 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004186 }
4187 catch(std::bad_alloc&)
4188 {
4189 return error(GL_OUT_OF_MEMORY);
4190 }
4191}
4192
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004193void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004194{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004195 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 +00004196 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004197
4198 try
4199 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004200 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004201 {
4202 return error(GL_INVALID_VALUE);
4203 }
4204
4205 gl::Context *context = gl::getContext();
4206
4207 if (context)
4208 {
4209 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004210
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004211 if (!shaderObject)
4212 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004213 if (context->getProgram(shader))
4214 {
4215 return error(GL_INVALID_OPERATION);
4216 }
4217 else
4218 {
4219 return error(GL_INVALID_VALUE);
4220 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004221 }
4222
4223 shaderObject->setSource(count, string, length);
4224 }
4225 }
4226 catch(std::bad_alloc&)
4227 {
4228 return error(GL_OUT_OF_MEMORY);
4229 }
4230}
4231
4232void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4233{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004234 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004235}
4236
4237void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4238{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004239 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 +00004240
4241 try
4242 {
4243 switch (face)
4244 {
4245 case GL_FRONT:
4246 case GL_BACK:
4247 case GL_FRONT_AND_BACK:
4248 break;
4249 default:
4250 return error(GL_INVALID_ENUM);
4251 }
4252
4253 switch (func)
4254 {
4255 case GL_NEVER:
4256 case GL_ALWAYS:
4257 case GL_LESS:
4258 case GL_LEQUAL:
4259 case GL_EQUAL:
4260 case GL_GEQUAL:
4261 case GL_GREATER:
4262 case GL_NOTEQUAL:
4263 break;
4264 default:
4265 return error(GL_INVALID_ENUM);
4266 }
4267
4268 gl::Context *context = gl::getContext();
4269
4270 if (context)
4271 {
4272 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4273 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004274 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004275 }
4276
4277 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4278 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004279 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004280 }
4281 }
4282 }
4283 catch(std::bad_alloc&)
4284 {
4285 return error(GL_OUT_OF_MEMORY);
4286 }
4287}
4288
4289void __stdcall glStencilMask(GLuint mask)
4290{
4291 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4292}
4293
4294void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4295{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004296 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004297
4298 try
4299 {
4300 switch (face)
4301 {
4302 case GL_FRONT:
4303 case GL_BACK:
4304 case GL_FRONT_AND_BACK:
4305 break;
4306 default:
4307 return error(GL_INVALID_ENUM);
4308 }
4309
4310 gl::Context *context = gl::getContext();
4311
4312 if (context)
4313 {
4314 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4315 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004316 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004317 }
4318
4319 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4320 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004321 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004322 }
4323 }
4324 }
4325 catch(std::bad_alloc&)
4326 {
4327 return error(GL_OUT_OF_MEMORY);
4328 }
4329}
4330
4331void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4332{
4333 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4334}
4335
4336void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4337{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004338 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4339 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004340
4341 try
4342 {
4343 switch (face)
4344 {
4345 case GL_FRONT:
4346 case GL_BACK:
4347 case GL_FRONT_AND_BACK:
4348 break;
4349 default:
4350 return error(GL_INVALID_ENUM);
4351 }
4352
4353 switch (fail)
4354 {
4355 case GL_ZERO:
4356 case GL_KEEP:
4357 case GL_REPLACE:
4358 case GL_INCR:
4359 case GL_DECR:
4360 case GL_INVERT:
4361 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004362 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004363 break;
4364 default:
4365 return error(GL_INVALID_ENUM);
4366 }
4367
4368 switch (zfail)
4369 {
4370 case GL_ZERO:
4371 case GL_KEEP:
4372 case GL_REPLACE:
4373 case GL_INCR:
4374 case GL_DECR:
4375 case GL_INVERT:
4376 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004377 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004378 break;
4379 default:
4380 return error(GL_INVALID_ENUM);
4381 }
4382
4383 switch (zpass)
4384 {
4385 case GL_ZERO:
4386 case GL_KEEP:
4387 case GL_REPLACE:
4388 case GL_INCR:
4389 case GL_DECR:
4390 case GL_INVERT:
4391 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004392 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004393 break;
4394 default:
4395 return error(GL_INVALID_ENUM);
4396 }
4397
4398 gl::Context *context = gl::getContext();
4399
4400 if (context)
4401 {
4402 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4403 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004404 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004405 }
4406
4407 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4408 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004409 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004410 }
4411 }
4412 }
4413 catch(std::bad_alloc&)
4414 {
4415 return error(GL_OUT_OF_MEMORY);
4416 }
4417}
4418
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004419GLboolean __stdcall glTestFenceNV(GLuint fence)
4420{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004421 TRACE("(GLuint fence = %d)", fence);
4422
4423 try
4424 {
4425 gl::Context *context = gl::getContext();
4426
4427 if (context)
4428 {
4429 gl::Fence *fenceObject = context->getFence(fence);
4430
4431 if (fenceObject == NULL)
4432 {
4433 return error(GL_INVALID_OPERATION, GL_TRUE);
4434 }
4435
4436 return fenceObject->testFence();
4437 }
4438 }
4439 catch(std::bad_alloc&)
4440 {
4441 error(GL_OUT_OF_MEMORY);
4442 }
4443
4444 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004445}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004446
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004447void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4448 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004449{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004450 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 +00004451 "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 +00004452 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004453
4454 try
4455 {
4456 if (level < 0 || width < 0 || height < 0)
4457 {
4458 return error(GL_INVALID_VALUE);
4459 }
4460
4461 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
4462 {
4463 return error(GL_INVALID_VALUE);
4464 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004465
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004466 if (internalformat != format)
4467 {
4468 return error(GL_INVALID_OPERATION);
4469 }
4470
4471 switch (internalformat)
4472 {
4473 case GL_ALPHA:
4474 case GL_LUMINANCE:
4475 case GL_LUMINANCE_ALPHA:
4476 switch (type)
4477 {
4478 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004479 case GL_FLOAT:
4480 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004481 break;
4482 default:
4483 return error(GL_INVALID_ENUM);
4484 }
4485 break;
4486 case GL_RGB:
4487 switch (type)
4488 {
4489 case GL_UNSIGNED_BYTE:
4490 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004491 case GL_FLOAT:
4492 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004493 break;
4494 default:
4495 return error(GL_INVALID_ENUM);
4496 }
4497 break;
4498 case GL_RGBA:
4499 switch (type)
4500 {
4501 case GL_UNSIGNED_BYTE:
4502 case GL_UNSIGNED_SHORT_4_4_4_4:
4503 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004504 case GL_FLOAT:
4505 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004506 break;
4507 default:
4508 return error(GL_INVALID_ENUM);
4509 }
4510 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004511 case GL_BGRA_EXT:
4512 switch (type)
4513 {
4514 case GL_UNSIGNED_BYTE:
4515 break;
4516 default:
4517 return error(GL_INVALID_ENUM);
4518 }
4519 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004520 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4521 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4522 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004523 default:
4524 return error(GL_INVALID_VALUE);
4525 }
4526
4527 if (border != 0)
4528 {
4529 return error(GL_INVALID_VALUE);
4530 }
4531
4532 gl::Context *context = gl::getContext();
4533
4534 if (context)
4535 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004536 switch (target)
4537 {
4538 case GL_TEXTURE_2D:
4539 if (width > (context->getMaximumTextureDimension() >> level) ||
4540 height > (context->getMaximumTextureDimension() >> level))
4541 {
4542 return error(GL_INVALID_VALUE);
4543 }
4544 break;
4545 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4546 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4547 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4548 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4549 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4550 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4551 if (width != height)
4552 {
4553 return error(GL_INVALID_VALUE);
4554 }
4555
4556 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4557 height > (context->getMaximumCubeTextureDimension() >> level))
4558 {
4559 return error(GL_INVALID_VALUE);
4560 }
4561 break;
4562 default:
4563 return error(GL_INVALID_ENUM);
4564 }
4565
daniel@transgaming.com01868132010-08-24 19:21:17 +00004566 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4567 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
4568 {
4569 if (context->supportsCompressedTextures())
4570 {
4571 return error(GL_INVALID_OPERATION);
4572 }
4573 else
4574 {
4575 return error(GL_INVALID_ENUM);
4576 }
4577 }
4578
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004579 if (type == GL_FLOAT)
4580 {
4581 if (!context->supportsFloatTextures())
4582 {
4583 return error(GL_INVALID_ENUM);
4584 }
4585 }
4586 else if (type == GL_HALF_FLOAT_OES)
4587 {
4588 if (!context->supportsHalfFloatTextures())
4589 {
4590 return error(GL_INVALID_ENUM);
4591 }
4592 }
4593
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004594 if (target == GL_TEXTURE_2D)
4595 {
4596 gl::Texture2D *texture = context->getTexture2D();
4597
4598 if (!texture)
4599 {
4600 return error(GL_INVALID_OPERATION);
4601 }
4602
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004603 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004604 }
4605 else
4606 {
4607 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4608
4609 if (!texture)
4610 {
4611 return error(GL_INVALID_OPERATION);
4612 }
4613
4614 switch (target)
4615 {
4616 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004617 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004618 break;
4619 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004620 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004621 break;
4622 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004623 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004624 break;
4625 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004626 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004627 break;
4628 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004629 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004630 break;
4631 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004632 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004633 break;
4634 default: UNREACHABLE();
4635 }
4636 }
4637 }
4638 }
4639 catch(std::bad_alloc&)
4640 {
4641 return error(GL_OUT_OF_MEMORY);
4642 }
4643}
4644
4645void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4646{
4647 glTexParameteri(target, pname, (GLint)param);
4648}
4649
4650void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4651{
4652 glTexParameteri(target, pname, (GLint)*params);
4653}
4654
4655void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4656{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004657 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004658
4659 try
4660 {
4661 gl::Context *context = gl::getContext();
4662
4663 if (context)
4664 {
4665 gl::Texture *texture;
4666
4667 switch (target)
4668 {
4669 case GL_TEXTURE_2D:
4670 texture = context->getTexture2D();
4671 break;
4672 case GL_TEXTURE_CUBE_MAP:
4673 texture = context->getTextureCubeMap();
4674 break;
4675 default:
4676 return error(GL_INVALID_ENUM);
4677 }
4678
4679 switch (pname)
4680 {
4681 case GL_TEXTURE_WRAP_S:
4682 if (!texture->setWrapS((GLenum)param))
4683 {
4684 return error(GL_INVALID_ENUM);
4685 }
4686 break;
4687 case GL_TEXTURE_WRAP_T:
4688 if (!texture->setWrapT((GLenum)param))
4689 {
4690 return error(GL_INVALID_ENUM);
4691 }
4692 break;
4693 case GL_TEXTURE_MIN_FILTER:
4694 if (!texture->setMinFilter((GLenum)param))
4695 {
4696 return error(GL_INVALID_ENUM);
4697 }
4698 break;
4699 case GL_TEXTURE_MAG_FILTER:
4700 if (!texture->setMagFilter((GLenum)param))
4701 {
4702 return error(GL_INVALID_ENUM);
4703 }
4704 break;
4705 default:
4706 return error(GL_INVALID_ENUM);
4707 }
4708 }
4709 }
4710 catch(std::bad_alloc&)
4711 {
4712 return error(GL_OUT_OF_MEMORY);
4713 }
4714}
4715
4716void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4717{
4718 glTexParameteri(target, pname, *params);
4719}
4720
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004721void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4722 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004723{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004724 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4725 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004726 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004727 target, level, xoffset, yoffset, width, height, format, type, pixels);
4728
4729 try
4730 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004731 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004732 {
4733 return error(GL_INVALID_ENUM);
4734 }
4735
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004736 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004737 {
4738 return error(GL_INVALID_VALUE);
4739 }
4740
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004741 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4742 {
4743 return error(GL_INVALID_VALUE);
4744 }
4745
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004746 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004747 {
4748 return error(GL_INVALID_ENUM);
4749 }
4750
4751 if (width == 0 || height == 0 || pixels == NULL)
4752 {
4753 return;
4754 }
4755
4756 gl::Context *context = gl::getContext();
4757
4758 if (context)
4759 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004760 if (level > context->getMaximumTextureLevel())
4761 {
4762 return error(GL_INVALID_VALUE);
4763 }
4764
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004765 if (format == GL_FLOAT)
4766 {
4767 if (!context->supportsFloatTextures())
4768 {
4769 return error(GL_INVALID_ENUM);
4770 }
4771 }
4772 else if (format == GL_HALF_FLOAT_OES)
4773 {
4774 if (!context->supportsHalfFloatTextures())
4775 {
4776 return error(GL_INVALID_ENUM);
4777 }
4778 }
4779
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004780 if (target == GL_TEXTURE_2D)
4781 {
4782 gl::Texture2D *texture = context->getTexture2D();
4783
4784 if (!texture)
4785 {
4786 return error(GL_INVALID_OPERATION);
4787 }
4788
daniel@transgaming.com01868132010-08-24 19:21:17 +00004789 if (texture->isCompressed())
4790 {
4791 return error(GL_INVALID_OPERATION);
4792 }
4793
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004794 if (format != texture->getFormat())
4795 {
4796 return error(GL_INVALID_OPERATION);
4797 }
4798
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004799 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004800 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004801 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004802 {
4803 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4804
4805 if (!texture)
4806 {
4807 return error(GL_INVALID_OPERATION);
4808 }
4809
daniel@transgaming.com01868132010-08-24 19:21:17 +00004810 if (texture->isCompressed())
4811 {
4812 return error(GL_INVALID_OPERATION);
4813 }
4814
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004815 if (format != texture->getFormat())
4816 {
4817 return error(GL_INVALID_OPERATION);
4818 }
4819
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004820 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004821 }
4822 else
4823 {
4824 UNREACHABLE();
4825 }
4826 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004827 }
4828 catch(std::bad_alloc&)
4829 {
4830 return error(GL_OUT_OF_MEMORY);
4831 }
4832}
4833
4834void __stdcall glUniform1f(GLint location, GLfloat x)
4835{
4836 glUniform1fv(location, 1, &x);
4837}
4838
4839void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4840{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004841 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004842
4843 try
4844 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004845 if (count < 0)
4846 {
4847 return error(GL_INVALID_VALUE);
4848 }
4849
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004850 if (location == -1)
4851 {
4852 return;
4853 }
4854
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004855 gl::Context *context = gl::getContext();
4856
4857 if (context)
4858 {
4859 gl::Program *program = context->getCurrentProgram();
4860
4861 if (!program)
4862 {
4863 return error(GL_INVALID_OPERATION);
4864 }
4865
4866 if (!program->setUniform1fv(location, count, v))
4867 {
4868 return error(GL_INVALID_OPERATION);
4869 }
4870 }
4871 }
4872 catch(std::bad_alloc&)
4873 {
4874 return error(GL_OUT_OF_MEMORY);
4875 }
4876}
4877
4878void __stdcall glUniform1i(GLint location, GLint x)
4879{
4880 glUniform1iv(location, 1, &x);
4881}
4882
4883void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4884{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004885 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004886
4887 try
4888 {
4889 if (count < 0)
4890 {
4891 return error(GL_INVALID_VALUE);
4892 }
4893
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004894 if (location == -1)
4895 {
4896 return;
4897 }
4898
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004899 gl::Context *context = gl::getContext();
4900
4901 if (context)
4902 {
4903 gl::Program *program = context->getCurrentProgram();
4904
4905 if (!program)
4906 {
4907 return error(GL_INVALID_OPERATION);
4908 }
4909
4910 if (!program->setUniform1iv(location, count, v))
4911 {
4912 return error(GL_INVALID_OPERATION);
4913 }
4914 }
4915 }
4916 catch(std::bad_alloc&)
4917 {
4918 return error(GL_OUT_OF_MEMORY);
4919 }
4920}
4921
4922void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4923{
4924 GLfloat xy[2] = {x, y};
4925
4926 glUniform2fv(location, 1, (GLfloat*)&xy);
4927}
4928
4929void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4930{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004931 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004932
4933 try
4934 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004935 if (count < 0)
4936 {
4937 return error(GL_INVALID_VALUE);
4938 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004939
4940 if (location == -1)
4941 {
4942 return;
4943 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004944
4945 gl::Context *context = gl::getContext();
4946
4947 if (context)
4948 {
4949 gl::Program *program = context->getCurrentProgram();
4950
4951 if (!program)
4952 {
4953 return error(GL_INVALID_OPERATION);
4954 }
4955
4956 if (!program->setUniform2fv(location, count, v))
4957 {
4958 return error(GL_INVALID_OPERATION);
4959 }
4960 }
4961 }
4962 catch(std::bad_alloc&)
4963 {
4964 return error(GL_OUT_OF_MEMORY);
4965 }
4966}
4967
4968void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4969{
4970 GLint xy[4] = {x, y};
4971
4972 glUniform2iv(location, 1, (GLint*)&xy);
4973}
4974
4975void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4976{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004977 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004978
4979 try
4980 {
4981 if (count < 0)
4982 {
4983 return error(GL_INVALID_VALUE);
4984 }
4985
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004986 if (location == -1)
4987 {
4988 return;
4989 }
4990
4991 gl::Context *context = gl::getContext();
4992
4993 if (context)
4994 {
4995 gl::Program *program = context->getCurrentProgram();
4996
4997 if (!program)
4998 {
4999 return error(GL_INVALID_OPERATION);
5000 }
5001
5002 if (!program->setUniform2iv(location, count, v))
5003 {
5004 return error(GL_INVALID_OPERATION);
5005 }
5006 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005007 }
5008 catch(std::bad_alloc&)
5009 {
5010 return error(GL_OUT_OF_MEMORY);
5011 }
5012}
5013
5014void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5015{
5016 GLfloat xyz[3] = {x, y, z};
5017
5018 glUniform3fv(location, 1, (GLfloat*)&xyz);
5019}
5020
5021void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5022{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005023 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005024
5025 try
5026 {
5027 if (count < 0)
5028 {
5029 return error(GL_INVALID_VALUE);
5030 }
5031
5032 if (location == -1)
5033 {
5034 return;
5035 }
5036
5037 gl::Context *context = gl::getContext();
5038
5039 if (context)
5040 {
5041 gl::Program *program = context->getCurrentProgram();
5042
5043 if (!program)
5044 {
5045 return error(GL_INVALID_OPERATION);
5046 }
5047
5048 if (!program->setUniform3fv(location, count, v))
5049 {
5050 return error(GL_INVALID_OPERATION);
5051 }
5052 }
5053 }
5054 catch(std::bad_alloc&)
5055 {
5056 return error(GL_OUT_OF_MEMORY);
5057 }
5058}
5059
5060void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5061{
5062 GLint xyz[3] = {x, y, z};
5063
5064 glUniform3iv(location, 1, (GLint*)&xyz);
5065}
5066
5067void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5068{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005069 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005070
5071 try
5072 {
5073 if (count < 0)
5074 {
5075 return error(GL_INVALID_VALUE);
5076 }
5077
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005078 if (location == -1)
5079 {
5080 return;
5081 }
5082
5083 gl::Context *context = gl::getContext();
5084
5085 if (context)
5086 {
5087 gl::Program *program = context->getCurrentProgram();
5088
5089 if (!program)
5090 {
5091 return error(GL_INVALID_OPERATION);
5092 }
5093
5094 if (!program->setUniform3iv(location, count, v))
5095 {
5096 return error(GL_INVALID_OPERATION);
5097 }
5098 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005099 }
5100 catch(std::bad_alloc&)
5101 {
5102 return error(GL_OUT_OF_MEMORY);
5103 }
5104}
5105
5106void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5107{
5108 GLfloat xyzw[4] = {x, y, z, w};
5109
5110 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5111}
5112
5113void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5114{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005115 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005116
5117 try
5118 {
5119 if (count < 0)
5120 {
5121 return error(GL_INVALID_VALUE);
5122 }
5123
5124 if (location == -1)
5125 {
5126 return;
5127 }
5128
5129 gl::Context *context = gl::getContext();
5130
5131 if (context)
5132 {
5133 gl::Program *program = context->getCurrentProgram();
5134
5135 if (!program)
5136 {
5137 return error(GL_INVALID_OPERATION);
5138 }
5139
5140 if (!program->setUniform4fv(location, count, v))
5141 {
5142 return error(GL_INVALID_OPERATION);
5143 }
5144 }
5145 }
5146 catch(std::bad_alloc&)
5147 {
5148 return error(GL_OUT_OF_MEMORY);
5149 }
5150}
5151
5152void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5153{
5154 GLint xyzw[4] = {x, y, z, w};
5155
5156 glUniform4iv(location, 1, (GLint*)&xyzw);
5157}
5158
5159void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5160{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005161 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005162
5163 try
5164 {
5165 if (count < 0)
5166 {
5167 return error(GL_INVALID_VALUE);
5168 }
5169
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005170 if (location == -1)
5171 {
5172 return;
5173 }
5174
5175 gl::Context *context = gl::getContext();
5176
5177 if (context)
5178 {
5179 gl::Program *program = context->getCurrentProgram();
5180
5181 if (!program)
5182 {
5183 return error(GL_INVALID_OPERATION);
5184 }
5185
5186 if (!program->setUniform4iv(location, count, v))
5187 {
5188 return error(GL_INVALID_OPERATION);
5189 }
5190 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005191 }
5192 catch(std::bad_alloc&)
5193 {
5194 return error(GL_OUT_OF_MEMORY);
5195 }
5196}
5197
5198void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5199{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005200 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5201 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005202
5203 try
5204 {
5205 if (count < 0 || transpose != GL_FALSE)
5206 {
5207 return error(GL_INVALID_VALUE);
5208 }
5209
5210 if (location == -1)
5211 {
5212 return;
5213 }
5214
5215 gl::Context *context = gl::getContext();
5216
5217 if (context)
5218 {
5219 gl::Program *program = context->getCurrentProgram();
5220
5221 if (!program)
5222 {
5223 return error(GL_INVALID_OPERATION);
5224 }
5225
5226 if (!program->setUniformMatrix2fv(location, count, value))
5227 {
5228 return error(GL_INVALID_OPERATION);
5229 }
5230 }
5231 }
5232 catch(std::bad_alloc&)
5233 {
5234 return error(GL_OUT_OF_MEMORY);
5235 }
5236}
5237
5238void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5239{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005240 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5241 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005242
5243 try
5244 {
5245 if (count < 0 || transpose != GL_FALSE)
5246 {
5247 return error(GL_INVALID_VALUE);
5248 }
5249
5250 if (location == -1)
5251 {
5252 return;
5253 }
5254
5255 gl::Context *context = gl::getContext();
5256
5257 if (context)
5258 {
5259 gl::Program *program = context->getCurrentProgram();
5260
5261 if (!program)
5262 {
5263 return error(GL_INVALID_OPERATION);
5264 }
5265
5266 if (!program->setUniformMatrix3fv(location, count, value))
5267 {
5268 return error(GL_INVALID_OPERATION);
5269 }
5270 }
5271 }
5272 catch(std::bad_alloc&)
5273 {
5274 return error(GL_OUT_OF_MEMORY);
5275 }
5276}
5277
5278void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5279{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005280 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5281 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005282
5283 try
5284 {
5285 if (count < 0 || transpose != GL_FALSE)
5286 {
5287 return error(GL_INVALID_VALUE);
5288 }
5289
5290 if (location == -1)
5291 {
5292 return;
5293 }
5294
5295 gl::Context *context = gl::getContext();
5296
5297 if (context)
5298 {
5299 gl::Program *program = context->getCurrentProgram();
5300
5301 if (!program)
5302 {
5303 return error(GL_INVALID_OPERATION);
5304 }
5305
5306 if (!program->setUniformMatrix4fv(location, count, value))
5307 {
5308 return error(GL_INVALID_OPERATION);
5309 }
5310 }
5311 }
5312 catch(std::bad_alloc&)
5313 {
5314 return error(GL_OUT_OF_MEMORY);
5315 }
5316}
5317
5318void __stdcall glUseProgram(GLuint program)
5319{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005320 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005321
5322 try
5323 {
5324 gl::Context *context = gl::getContext();
5325
5326 if (context)
5327 {
5328 gl::Program *programObject = context->getProgram(program);
5329
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005330 if (!programObject && program != 0)
5331 {
5332 if (context->getShader(program))
5333 {
5334 return error(GL_INVALID_OPERATION);
5335 }
5336 else
5337 {
5338 return error(GL_INVALID_VALUE);
5339 }
5340 }
5341
5342 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005343 {
5344 return error(GL_INVALID_OPERATION);
5345 }
5346
5347 context->useProgram(program);
5348 }
5349 }
5350 catch(std::bad_alloc&)
5351 {
5352 return error(GL_OUT_OF_MEMORY);
5353 }
5354}
5355
5356void __stdcall glValidateProgram(GLuint program)
5357{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005358 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005359
5360 try
5361 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005362 gl::Context *context = gl::getContext();
5363
5364 if (context)
5365 {
5366 gl::Program *programObject = context->getProgram(program);
5367
5368 if (!programObject)
5369 {
5370 if (context->getShader(program))
5371 {
5372 return error(GL_INVALID_OPERATION);
5373 }
5374 else
5375 {
5376 return error(GL_INVALID_VALUE);
5377 }
5378 }
5379
5380 programObject->validate();
5381 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005382 }
5383 catch(std::bad_alloc&)
5384 {
5385 return error(GL_OUT_OF_MEMORY);
5386 }
5387}
5388
5389void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5390{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005391 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005392
5393 try
5394 {
5395 if (index >= gl::MAX_VERTEX_ATTRIBS)
5396 {
5397 return error(GL_INVALID_VALUE);
5398 }
5399
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005400 gl::Context *context = gl::getContext();
5401
5402 if (context)
5403 {
5404 GLfloat vals[4] = { x, 0, 0, 1 };
5405 context->setVertexAttrib(index, vals);
5406 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005407 }
5408 catch(std::bad_alloc&)
5409 {
5410 return error(GL_OUT_OF_MEMORY);
5411 }
5412}
5413
5414void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5415{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005416 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005417
5418 try
5419 {
5420 if (index >= gl::MAX_VERTEX_ATTRIBS)
5421 {
5422 return error(GL_INVALID_VALUE);
5423 }
5424
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005425 gl::Context *context = gl::getContext();
5426
5427 if (context)
5428 {
5429 GLfloat vals[4] = { values[0], 0, 0, 1 };
5430 context->setVertexAttrib(index, vals);
5431 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005432 }
5433 catch(std::bad_alloc&)
5434 {
5435 return error(GL_OUT_OF_MEMORY);
5436 }
5437}
5438
5439void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5440{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005441 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005442
5443 try
5444 {
5445 if (index >= gl::MAX_VERTEX_ATTRIBS)
5446 {
5447 return error(GL_INVALID_VALUE);
5448 }
5449
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005450 gl::Context *context = gl::getContext();
5451
5452 if (context)
5453 {
5454 GLfloat vals[4] = { x, y, 0, 1 };
5455 context->setVertexAttrib(index, vals);
5456 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005457 }
5458 catch(std::bad_alloc&)
5459 {
5460 return error(GL_OUT_OF_MEMORY);
5461 }
5462}
5463
5464void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5465{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005466 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005467
5468 try
5469 {
5470 if (index >= gl::MAX_VERTEX_ATTRIBS)
5471 {
5472 return error(GL_INVALID_VALUE);
5473 }
5474
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005475 gl::Context *context = gl::getContext();
5476
5477 if (context)
5478 {
5479 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5480 context->setVertexAttrib(index, vals);
5481 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005482 }
5483 catch(std::bad_alloc&)
5484 {
5485 return error(GL_OUT_OF_MEMORY);
5486 }
5487}
5488
5489void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5490{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005491 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 +00005492
5493 try
5494 {
5495 if (index >= gl::MAX_VERTEX_ATTRIBS)
5496 {
5497 return error(GL_INVALID_VALUE);
5498 }
5499
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005500 gl::Context *context = gl::getContext();
5501
5502 if (context)
5503 {
5504 GLfloat vals[4] = { x, y, z, 1 };
5505 context->setVertexAttrib(index, vals);
5506 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005507 }
5508 catch(std::bad_alloc&)
5509 {
5510 return error(GL_OUT_OF_MEMORY);
5511 }
5512}
5513
5514void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5515{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005516 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005517
5518 try
5519 {
5520 if (index >= gl::MAX_VERTEX_ATTRIBS)
5521 {
5522 return error(GL_INVALID_VALUE);
5523 }
5524
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005525 gl::Context *context = gl::getContext();
5526
5527 if (context)
5528 {
5529 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5530 context->setVertexAttrib(index, vals);
5531 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005532 }
5533 catch(std::bad_alloc&)
5534 {
5535 return error(GL_OUT_OF_MEMORY);
5536 }
5537}
5538
5539void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5540{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005541 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 +00005542
5543 try
5544 {
5545 if (index >= gl::MAX_VERTEX_ATTRIBS)
5546 {
5547 return error(GL_INVALID_VALUE);
5548 }
5549
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005550 gl::Context *context = gl::getContext();
5551
5552 if (context)
5553 {
5554 GLfloat vals[4] = { x, y, z, w };
5555 context->setVertexAttrib(index, vals);
5556 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005557 }
5558 catch(std::bad_alloc&)
5559 {
5560 return error(GL_OUT_OF_MEMORY);
5561 }
5562}
5563
5564void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5565{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005566 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005567
5568 try
5569 {
5570 if (index >= gl::MAX_VERTEX_ATTRIBS)
5571 {
5572 return error(GL_INVALID_VALUE);
5573 }
5574
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005575 gl::Context *context = gl::getContext();
5576
5577 if (context)
5578 {
5579 context->setVertexAttrib(index, values);
5580 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005581 }
5582 catch(std::bad_alloc&)
5583 {
5584 return error(GL_OUT_OF_MEMORY);
5585 }
5586}
5587
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005588void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005589{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005590 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005591 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005592 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005593
5594 try
5595 {
5596 if (index >= gl::MAX_VERTEX_ATTRIBS)
5597 {
5598 return error(GL_INVALID_VALUE);
5599 }
5600
5601 if (size < 1 || size > 4)
5602 {
5603 return error(GL_INVALID_VALUE);
5604 }
5605
5606 switch (type)
5607 {
5608 case GL_BYTE:
5609 case GL_UNSIGNED_BYTE:
5610 case GL_SHORT:
5611 case GL_UNSIGNED_SHORT:
5612 case GL_FIXED:
5613 case GL_FLOAT:
5614 break;
5615 default:
5616 return error(GL_INVALID_ENUM);
5617 }
5618
5619 if (stride < 0)
5620 {
5621 return error(GL_INVALID_VALUE);
5622 }
5623
5624 gl::Context *context = gl::getContext();
5625
5626 if (context)
5627 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005628 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005629 }
5630 }
5631 catch(std::bad_alloc&)
5632 {
5633 return error(GL_OUT_OF_MEMORY);
5634 }
5635}
5636
5637void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5638{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005639 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 +00005640
5641 try
5642 {
5643 if (width < 0 || height < 0)
5644 {
5645 return error(GL_INVALID_VALUE);
5646 }
5647
5648 gl::Context *context = gl::getContext();
5649
5650 if (context)
5651 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005652 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005653 }
5654 }
5655 catch(std::bad_alloc&)
5656 {
5657 return error(GL_OUT_OF_MEMORY);
5658 }
5659}
5660
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005661void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5662 GLbitfield mask, GLenum filter)
5663{
5664 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5665 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5666 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5667 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5668
5669 try
5670 {
5671 switch (filter)
5672 {
5673 case GL_NEAREST:
5674 break;
5675 default:
5676 return error(GL_INVALID_ENUM);
5677 }
5678
5679 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5680 {
5681 return error(GL_INVALID_VALUE);
5682 }
5683
5684 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5685 {
5686 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5687 return error(GL_INVALID_OPERATION);
5688 }
5689
5690 gl::Context *context = gl::getContext();
5691
5692 if (context)
5693 {
5694 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5695 {
5696 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5697 return error(GL_INVALID_OPERATION);
5698 }
5699
5700 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5701 }
5702 }
5703 catch(std::bad_alloc&)
5704 {
5705 return error(GL_OUT_OF_MEMORY);
5706 }
5707}
5708
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005709void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5710 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005711{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005712 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5713 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005714 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005715 target, level, internalformat, width, height, depth, border, format, type, pixels);
5716
5717 try
5718 {
5719 UNIMPLEMENTED(); // FIXME
5720 }
5721 catch(std::bad_alloc&)
5722 {
5723 return error(GL_OUT_OF_MEMORY);
5724 }
5725}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005726
5727__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5728{
5729 struct Extension
5730 {
5731 const char *name;
5732 __eglMustCastToProperFunctionPointerType address;
5733 };
5734
5735 static const Extension glExtensions[] =
5736 {
5737 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00005738 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005739 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
5740 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
5741 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
5742 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
5743 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
5744 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
5745 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005746 };
5747
5748 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5749 {
5750 if (strcmp(procname, glExtensions[ext].name) == 0)
5751 {
5752 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5753 }
5754 }
5755
5756 return NULL;
5757}
5758
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005759}