blob: 7fcd2dc41e0df64f757a75693f77ae14db8df0fa [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.com83921382011-01-08 05:46:00 +00001717 context->setEnableVertexAttribArray(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
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001762 gl::Context *context = gl::getContext();
1763
1764 if (context)
1765 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001766 switch (type)
1767 {
1768 case GL_UNSIGNED_BYTE:
1769 case GL_UNSIGNED_SHORT:
1770 break;
1771 case GL_UNSIGNED_INT:
1772 if (!context->supports32bitIndices())
1773 {
1774 return error(GL_INVALID_ENUM);
1775 }
1776 break;
1777 default:
1778 return error(GL_INVALID_ENUM);
1779 }
1780
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001781 context->drawElements(mode, count, type, indices);
1782 }
1783 }
1784 catch(std::bad_alloc&)
1785 {
1786 return error(GL_OUT_OF_MEMORY);
1787 }
1788}
1789
1790void __stdcall glEnable(GLenum cap)
1791{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001792 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001793
1794 try
1795 {
1796 gl::Context *context = gl::getContext();
1797
1798 if (context)
1799 {
1800 switch (cap)
1801 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001802 case GL_CULL_FACE: context->setCullFace(true); break;
1803 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1804 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1805 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1806 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1807 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1808 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1809 case GL_BLEND: context->setBlend(true); break;
1810 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001811 default:
1812 return error(GL_INVALID_ENUM);
1813 }
1814 }
1815 }
1816 catch(std::bad_alloc&)
1817 {
1818 return error(GL_OUT_OF_MEMORY);
1819 }
1820}
1821
1822void __stdcall glEnableVertexAttribArray(GLuint index)
1823{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001824 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001825
1826 try
1827 {
1828 if (index >= gl::MAX_VERTEX_ATTRIBS)
1829 {
1830 return error(GL_INVALID_VALUE);
1831 }
1832
1833 gl::Context *context = gl::getContext();
1834
1835 if (context)
1836 {
daniel@transgaming.com83921382011-01-08 05:46:00 +00001837 context->setEnableVertexAttribArray(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001838 }
1839 }
1840 catch(std::bad_alloc&)
1841 {
1842 return error(GL_OUT_OF_MEMORY);
1843 }
1844}
1845
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001846void __stdcall glFinishFenceNV(GLuint fence)
1847{
1848 TRACE("(GLuint fence = %d)", fence);
1849
1850 try
1851 {
1852 gl::Context *context = gl::getContext();
1853
1854 if (context)
1855 {
1856 gl::Fence* fenceObject = context->getFence(fence);
1857
1858 if (fenceObject == NULL)
1859 {
1860 return error(GL_INVALID_OPERATION);
1861 }
1862
1863 fenceObject->finishFence();
1864 }
1865 }
1866 catch(std::bad_alloc&)
1867 {
1868 return error(GL_OUT_OF_MEMORY);
1869 }
1870}
1871
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001872void __stdcall glFinish(void)
1873{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001874 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001875
1876 try
1877 {
1878 gl::Context *context = gl::getContext();
1879
1880 if (context)
1881 {
1882 context->finish();
1883 }
1884 }
1885 catch(std::bad_alloc&)
1886 {
1887 return error(GL_OUT_OF_MEMORY);
1888 }
1889}
1890
1891void __stdcall glFlush(void)
1892{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001893 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001894
1895 try
1896 {
1897 gl::Context *context = gl::getContext();
1898
1899 if (context)
1900 {
1901 context->flush();
1902 }
1903 }
1904 catch(std::bad_alloc&)
1905 {
1906 return error(GL_OUT_OF_MEMORY);
1907 }
1908}
1909
1910void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1911{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001912 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1913 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001914
1915 try
1916 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001917 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1918 || renderbuffertarget != GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001919 {
1920 return error(GL_INVALID_ENUM);
1921 }
1922
1923 gl::Context *context = gl::getContext();
1924
1925 if (context)
1926 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001927 gl::Framebuffer *framebuffer = NULL;
1928 GLuint framebufferHandle = 0;
1929 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1930 {
1931 framebuffer = context->getReadFramebuffer();
1932 framebufferHandle = context->getReadFramebufferHandle();
1933 }
1934 else
1935 {
1936 framebuffer = context->getDrawFramebuffer();
1937 framebufferHandle = context->getDrawFramebufferHandle();
1938 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001939
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001940 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001941 {
1942 return error(GL_INVALID_OPERATION);
1943 }
1944
1945 switch (attachment)
1946 {
1947 case GL_COLOR_ATTACHMENT0:
1948 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1949 break;
1950 case GL_DEPTH_ATTACHMENT:
1951 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1952 break;
1953 case GL_STENCIL_ATTACHMENT:
1954 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1955 break;
1956 default:
1957 return error(GL_INVALID_ENUM);
1958 }
1959 }
1960 }
1961 catch(std::bad_alloc&)
1962 {
1963 return error(GL_OUT_OF_MEMORY);
1964 }
1965}
1966
1967void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1968{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001969 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1970 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001971
1972 try
1973 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001974 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001975 {
1976 return error(GL_INVALID_ENUM);
1977 }
1978
1979 switch (attachment)
1980 {
1981 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001982 case GL_DEPTH_ATTACHMENT:
1983 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001984 break;
1985 default:
1986 return error(GL_INVALID_ENUM);
1987 }
1988
1989 gl::Context *context = gl::getContext();
1990
1991 if (context)
1992 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001993 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001994 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001995 textarget = GL_NONE;
1996 }
1997 else
1998 {
1999 gl::Texture *tex = context->getTexture(texture);
2000
2001 if (tex == NULL)
2002 {
2003 return error(GL_INVALID_OPERATION);
2004 }
2005
daniel@transgaming.com01868132010-08-24 19:21:17 +00002006 if (tex->isCompressed())
2007 {
2008 return error(GL_INVALID_OPERATION);
2009 }
2010
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002011 switch (textarget)
2012 {
2013 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002014 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002015 {
2016 return error(GL_INVALID_OPERATION);
2017 }
2018 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002019
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002020 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002021 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002022 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002023 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002024 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002025 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002026 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2027 {
2028 return error(GL_INVALID_OPERATION);
2029 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002030 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002031
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002032 default:
2033 return error(GL_INVALID_ENUM);
2034 }
2035
2036 if (level != 0)
2037 {
2038 return error(GL_INVALID_VALUE);
2039 }
2040 }
2041
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002042 gl::Framebuffer *framebuffer = NULL;
2043 GLuint framebufferHandle = 0;
2044 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2045 {
2046 framebuffer = context->getReadFramebuffer();
2047 framebufferHandle = context->getReadFramebufferHandle();
2048 }
2049 else
2050 {
2051 framebuffer = context->getDrawFramebuffer();
2052 framebufferHandle = context->getDrawFramebufferHandle();
2053 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002054
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002055 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002056 {
2057 return error(GL_INVALID_OPERATION);
2058 }
2059
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002060 switch (attachment)
2061 {
2062 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2063 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2064 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2065 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002066 }
2067 }
2068 catch(std::bad_alloc&)
2069 {
2070 return error(GL_OUT_OF_MEMORY);
2071 }
2072}
2073
2074void __stdcall glFrontFace(GLenum mode)
2075{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002076 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002077
2078 try
2079 {
2080 switch (mode)
2081 {
2082 case GL_CW:
2083 case GL_CCW:
2084 {
2085 gl::Context *context = gl::getContext();
2086
2087 if (context)
2088 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002089 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002090 }
2091 }
2092 break;
2093 default:
2094 return error(GL_INVALID_ENUM);
2095 }
2096 }
2097 catch(std::bad_alloc&)
2098 {
2099 return error(GL_OUT_OF_MEMORY);
2100 }
2101}
2102
2103void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2104{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002105 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002106
2107 try
2108 {
2109 if (n < 0)
2110 {
2111 return error(GL_INVALID_VALUE);
2112 }
2113
2114 gl::Context *context = gl::getContext();
2115
2116 if (context)
2117 {
2118 for (int i = 0; i < n; i++)
2119 {
2120 buffers[i] = context->createBuffer();
2121 }
2122 }
2123 }
2124 catch(std::bad_alloc&)
2125 {
2126 return error(GL_OUT_OF_MEMORY);
2127 }
2128}
2129
2130void __stdcall glGenerateMipmap(GLenum target)
2131{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002132 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002133
2134 try
2135 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002136 gl::Context *context = gl::getContext();
2137
2138 if (context)
2139 {
2140 gl::Texture *texture;
2141
2142 switch (target)
2143 {
2144 case GL_TEXTURE_2D:
2145 texture = context->getTexture2D();
2146 break;
2147
2148 case GL_TEXTURE_CUBE_MAP:
2149 texture = context->getTextureCubeMap();
2150 break;
2151
2152 default:
2153 return error(GL_INVALID_ENUM);
2154 }
2155
daniel@transgaming.com01868132010-08-24 19:21:17 +00002156 if (texture->isCompressed())
2157 {
2158 return error(GL_INVALID_OPERATION);
2159 }
2160
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002161 texture->generateMipmaps();
2162 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002163 }
2164 catch(std::bad_alloc&)
2165 {
2166 return error(GL_OUT_OF_MEMORY);
2167 }
2168}
2169
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002170void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2171{
2172 TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
2173
2174 try
2175 {
2176 if (n < 0)
2177 {
2178 return error(GL_INVALID_VALUE);
2179 }
2180
2181 gl::Context *context = gl::getContext();
2182
2183 if (context)
2184 {
2185 for (int i = 0; i < n; i++)
2186 {
2187 fences[i] = context->createFence();
2188 }
2189 }
2190 }
2191 catch(std::bad_alloc&)
2192 {
2193 return error(GL_OUT_OF_MEMORY);
2194 }
2195}
2196
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002197void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2198{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002199 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002200
2201 try
2202 {
2203 if (n < 0)
2204 {
2205 return error(GL_INVALID_VALUE);
2206 }
2207
2208 gl::Context *context = gl::getContext();
2209
2210 if (context)
2211 {
2212 for (int i = 0; i < n; i++)
2213 {
2214 framebuffers[i] = context->createFramebuffer();
2215 }
2216 }
2217 }
2218 catch(std::bad_alloc&)
2219 {
2220 return error(GL_OUT_OF_MEMORY);
2221 }
2222}
2223
2224void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2225{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002226 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002227
2228 try
2229 {
2230 if (n < 0)
2231 {
2232 return error(GL_INVALID_VALUE);
2233 }
2234
2235 gl::Context *context = gl::getContext();
2236
2237 if (context)
2238 {
2239 for (int i = 0; i < n; i++)
2240 {
2241 renderbuffers[i] = context->createRenderbuffer();
2242 }
2243 }
2244 }
2245 catch(std::bad_alloc&)
2246 {
2247 return error(GL_OUT_OF_MEMORY);
2248 }
2249}
2250
2251void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2252{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002253 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002254
2255 try
2256 {
2257 if (n < 0)
2258 {
2259 return error(GL_INVALID_VALUE);
2260 }
2261
2262 gl::Context *context = gl::getContext();
2263
2264 if (context)
2265 {
2266 for (int i = 0; i < n; i++)
2267 {
2268 textures[i] = context->createTexture();
2269 }
2270 }
2271 }
2272 catch(std::bad_alloc&)
2273 {
2274 return error(GL_OUT_OF_MEMORY);
2275 }
2276}
2277
daniel@transgaming.com85423182010-04-22 13:35:27 +00002278void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002279{
daniel@transgaming.com85423182010-04-22 13:35:27 +00002280 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2281 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002282 program, index, bufsize, length, size, type, name);
2283
2284 try
2285 {
2286 if (bufsize < 0)
2287 {
2288 return error(GL_INVALID_VALUE);
2289 }
2290
daniel@transgaming.com85423182010-04-22 13:35:27 +00002291 gl::Context *context = gl::getContext();
2292
2293 if (context)
2294 {
2295 gl::Program *programObject = context->getProgram(program);
2296
2297 if (!programObject)
2298 {
2299 if (context->getShader(program))
2300 {
2301 return error(GL_INVALID_OPERATION);
2302 }
2303 else
2304 {
2305 return error(GL_INVALID_VALUE);
2306 }
2307 }
2308
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002309 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002310 {
2311 return error(GL_INVALID_VALUE);
2312 }
2313
2314 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2315 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002316 }
2317 catch(std::bad_alloc&)
2318 {
2319 return error(GL_OUT_OF_MEMORY);
2320 }
2321}
2322
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002323void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002324{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002325 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002326 "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 +00002327 program, index, bufsize, length, size, type, name);
2328
2329 try
2330 {
2331 if (bufsize < 0)
2332 {
2333 return error(GL_INVALID_VALUE);
2334 }
2335
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002336 gl::Context *context = gl::getContext();
2337
2338 if (context)
2339 {
2340 gl::Program *programObject = context->getProgram(program);
2341
2342 if (!programObject)
2343 {
2344 if (context->getShader(program))
2345 {
2346 return error(GL_INVALID_OPERATION);
2347 }
2348 else
2349 {
2350 return error(GL_INVALID_VALUE);
2351 }
2352 }
2353
2354 if (index >= (GLuint)programObject->getActiveUniformCount())
2355 {
2356 return error(GL_INVALID_VALUE);
2357 }
2358
2359 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2360 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002361 }
2362 catch(std::bad_alloc&)
2363 {
2364 return error(GL_OUT_OF_MEMORY);
2365 }
2366}
2367
2368void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2369{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002370 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2371 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002372
2373 try
2374 {
2375 if (maxcount < 0)
2376 {
2377 return error(GL_INVALID_VALUE);
2378 }
2379
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002380 gl::Context *context = gl::getContext();
2381
2382 if (context)
2383 {
2384 gl::Program *programObject = context->getProgram(program);
2385
2386 if (!programObject)
2387 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002388 if (context->getShader(program))
2389 {
2390 return error(GL_INVALID_OPERATION);
2391 }
2392 else
2393 {
2394 return error(GL_INVALID_VALUE);
2395 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002396 }
2397
2398 return programObject->getAttachedShaders(maxcount, count, shaders);
2399 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002400 }
2401 catch(std::bad_alloc&)
2402 {
2403 return error(GL_OUT_OF_MEMORY);
2404 }
2405}
2406
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002407int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002408{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002409 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002410
2411 try
2412 {
2413 gl::Context *context = gl::getContext();
2414
2415 if (context)
2416 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002417
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002418 gl::Program *programObject = context->getProgram(program);
2419
2420 if (!programObject)
2421 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002422 if (context->getShader(program))
2423 {
2424 return error(GL_INVALID_OPERATION, -1);
2425 }
2426 else
2427 {
2428 return error(GL_INVALID_VALUE, -1);
2429 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002430 }
2431
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002432 if (!programObject->isLinked())
2433 {
2434 return error(GL_INVALID_OPERATION, -1);
2435 }
2436
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002437 return programObject->getAttributeLocation(name);
2438 }
2439 }
2440 catch(std::bad_alloc&)
2441 {
2442 return error(GL_OUT_OF_MEMORY, -1);
2443 }
2444
2445 return -1;
2446}
2447
2448void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2449{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002450 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002451
2452 try
2453 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002454 gl::Context *context = gl::getContext();
2455
2456 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002457 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002458 if (!(context->getBooleanv(pname, params)))
2459 {
2460 GLenum nativeType;
2461 unsigned int numParams = 0;
2462 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2463 return error(GL_INVALID_ENUM);
2464
2465 if (numParams == 0)
2466 return; // it is known that the pname is valid, but there are no parameters to return
2467
2468 if (nativeType == GL_FLOAT)
2469 {
2470 GLfloat *floatParams = NULL;
2471 floatParams = new GLfloat[numParams];
2472
2473 context->getFloatv(pname, floatParams);
2474
2475 for (unsigned int i = 0; i < numParams; ++i)
2476 {
2477 if (floatParams[i] == 0.0f)
2478 params[i] = GL_FALSE;
2479 else
2480 params[i] = GL_TRUE;
2481 }
2482
2483 delete [] floatParams;
2484 }
2485 else if (nativeType == GL_INT)
2486 {
2487 GLint *intParams = NULL;
2488 intParams = new GLint[numParams];
2489
2490 context->getIntegerv(pname, intParams);
2491
2492 for (unsigned int i = 0; i < numParams; ++i)
2493 {
2494 if (intParams[i] == 0)
2495 params[i] = GL_FALSE;
2496 else
2497 params[i] = GL_TRUE;
2498 }
2499
2500 delete [] intParams;
2501 }
2502 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002503 }
2504 }
2505 catch(std::bad_alloc&)
2506 {
2507 return error(GL_OUT_OF_MEMORY);
2508 }
2509}
2510
2511void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2512{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002513 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 +00002514
2515 try
2516 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002517 gl::Context *context = gl::getContext();
2518
2519 if (context)
2520 {
2521 gl::Buffer *buffer;
2522
2523 switch (target)
2524 {
2525 case GL_ARRAY_BUFFER:
2526 buffer = context->getArrayBuffer();
2527 break;
2528 case GL_ELEMENT_ARRAY_BUFFER:
2529 buffer = context->getElementArrayBuffer();
2530 break;
2531 default: return error(GL_INVALID_ENUM);
2532 }
2533
2534 if (!buffer)
2535 {
2536 // A null buffer means that "0" is bound to the requested buffer target
2537 return error(GL_INVALID_OPERATION);
2538 }
2539
2540 switch (pname)
2541 {
2542 case GL_BUFFER_USAGE:
2543 *params = buffer->usage();
2544 break;
2545 case GL_BUFFER_SIZE:
2546 *params = buffer->size();
2547 break;
2548 default: return error(GL_INVALID_ENUM);
2549 }
2550 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002551 }
2552 catch(std::bad_alloc&)
2553 {
2554 return error(GL_OUT_OF_MEMORY);
2555 }
2556}
2557
2558GLenum __stdcall glGetError(void)
2559{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002560 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002561
2562 gl::Context *context = gl::getContext();
2563
2564 if (context)
2565 {
2566 return context->getError();
2567 }
2568
2569 return GL_NO_ERROR;
2570}
2571
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002572void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2573{
2574 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
2575
2576 try
2577 {
2578
2579 gl::Context *context = gl::getContext();
2580
2581 if (context)
2582 {
2583 gl::Fence *fenceObject = context->getFence(fence);
2584
2585 if (fenceObject == NULL)
2586 {
2587 return error(GL_INVALID_OPERATION);
2588 }
2589
2590 fenceObject->getFenceiv(pname, params);
2591 }
2592 }
2593 catch(std::bad_alloc&)
2594 {
2595 return error(GL_OUT_OF_MEMORY);
2596 }
2597}
2598
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002599void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2600{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002601 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002602
2603 try
2604 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002605 gl::Context *context = gl::getContext();
2606
2607 if (context)
2608 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002609 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002610 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002611 GLenum nativeType;
2612 unsigned int numParams = 0;
2613 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2614 return error(GL_INVALID_ENUM);
2615
2616 if (numParams == 0)
2617 return; // it is known that the pname is valid, but that there are no parameters to return.
2618
2619 if (nativeType == GL_BOOL)
2620 {
2621 GLboolean *boolParams = NULL;
2622 boolParams = new GLboolean[numParams];
2623
2624 context->getBooleanv(pname, boolParams);
2625
2626 for (unsigned int i = 0; i < numParams; ++i)
2627 {
2628 if (boolParams[i] == GL_FALSE)
2629 params[i] = 0.0f;
2630 else
2631 params[i] = 1.0f;
2632 }
2633
2634 delete [] boolParams;
2635 }
2636 else if (nativeType == GL_INT)
2637 {
2638 GLint *intParams = NULL;
2639 intParams = new GLint[numParams];
2640
2641 context->getIntegerv(pname, intParams);
2642
2643 for (unsigned int i = 0; i < numParams; ++i)
2644 {
2645 params[i] = (GLfloat)intParams[i];
2646 }
2647
2648 delete [] intParams;
2649 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002650 }
2651 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002652 }
2653 catch(std::bad_alloc&)
2654 {
2655 return error(GL_OUT_OF_MEMORY);
2656 }
2657}
2658
2659void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2660{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002661 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2662 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002663
2664 try
2665 {
2666 gl::Context *context = gl::getContext();
2667
2668 if (context)
2669 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002670 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002671 {
2672 return error(GL_INVALID_ENUM);
2673 }
2674
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002675 gl::Framebuffer *framebuffer = NULL;
2676 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2677 {
2678 if(context->getReadFramebufferHandle() == 0)
2679 {
2680 return error(GL_INVALID_OPERATION);
2681 }
2682
2683 framebuffer = context->getReadFramebuffer();
2684 }
2685 else
2686 {
2687 if (context->getDrawFramebufferHandle() == 0)
2688 {
2689 return error(GL_INVALID_OPERATION);
2690 }
2691
2692 framebuffer = context->getDrawFramebuffer();
2693 }
2694
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002695 GLenum attachmentType;
2696 GLuint attachmentHandle;
2697 switch (attachment)
2698 {
2699 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002700 attachmentType = framebuffer->getColorbufferType();
2701 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002702 break;
2703 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002704 attachmentType = framebuffer->getDepthbufferType();
2705 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002706 break;
2707 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002708 attachmentType = framebuffer->getStencilbufferType();
2709 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002710 break;
2711 default: return error(GL_INVALID_ENUM);
2712 }
2713
2714 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002715 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002716 {
2717 attachmentObjectType = attachmentType;
2718 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002719 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002720 {
2721 attachmentObjectType = GL_TEXTURE;
2722 }
2723 else UNREACHABLE();
2724
2725 switch (pname)
2726 {
2727 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2728 *params = attachmentObjectType;
2729 break;
2730 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2731 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2732 {
2733 *params = attachmentHandle;
2734 }
2735 else
2736 {
2737 return error(GL_INVALID_ENUM);
2738 }
2739 break;
2740 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2741 if (attachmentObjectType == GL_TEXTURE)
2742 {
2743 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2744 }
2745 else
2746 {
2747 return error(GL_INVALID_ENUM);
2748 }
2749 break;
2750 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2751 if (attachmentObjectType == GL_TEXTURE)
2752 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002753 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002754 {
2755 *params = attachmentType;
2756 }
2757 else
2758 {
2759 *params = 0;
2760 }
2761 }
2762 else
2763 {
2764 return error(GL_INVALID_ENUM);
2765 }
2766 break;
2767 default:
2768 return error(GL_INVALID_ENUM);
2769 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002770 }
2771 }
2772 catch(std::bad_alloc&)
2773 {
2774 return error(GL_OUT_OF_MEMORY);
2775 }
2776}
2777
2778void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2779{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002780 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002781
2782 try
2783 {
2784 gl::Context *context = gl::getContext();
2785
2786 if (context)
2787 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002788 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002789 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002790 GLenum nativeType;
2791 unsigned int numParams = 0;
2792 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2793 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002794
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002795 if (numParams == 0)
2796 return; // it is known that pname is valid, but there are no parameters to return
2797
2798 if (nativeType == GL_BOOL)
2799 {
2800 GLboolean *boolParams = NULL;
2801 boolParams = new GLboolean[numParams];
2802
2803 context->getBooleanv(pname, boolParams);
2804
2805 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002806 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002807 if (boolParams[i] == GL_FALSE)
2808 params[i] = 0;
2809 else
2810 params[i] = 1;
2811 }
2812
2813 delete [] boolParams;
2814 }
2815 else if (nativeType == GL_FLOAT)
2816 {
2817 GLfloat *floatParams = NULL;
2818 floatParams = new GLfloat[numParams];
2819
2820 context->getFloatv(pname, floatParams);
2821
2822 for (unsigned int i = 0; i < numParams; ++i)
2823 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002824 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 +00002825 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002826 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002827 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002828 else
2829 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 +00002830 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002831
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002832 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002833 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002834 }
2835 }
2836 }
2837 catch(std::bad_alloc&)
2838 {
2839 return error(GL_OUT_OF_MEMORY);
2840 }
2841}
2842
2843void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2844{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002845 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002846
2847 try
2848 {
2849 gl::Context *context = gl::getContext();
2850
2851 if (context)
2852 {
2853 gl::Program *programObject = context->getProgram(program);
2854
2855 if (!programObject)
2856 {
2857 return error(GL_INVALID_VALUE);
2858 }
2859
2860 switch (pname)
2861 {
2862 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002863 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002864 return;
2865 case GL_LINK_STATUS:
2866 *params = programObject->isLinked();
2867 return;
2868 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002869 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002870 return;
2871 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002872 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002873 return;
2874 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002875 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002876 return;
2877 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002878 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002879 return;
2880 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002881 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002882 return;
2883 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002884 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002885 return;
2886 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002887 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002888 return;
2889 default:
2890 return error(GL_INVALID_ENUM);
2891 }
2892 }
2893 }
2894 catch(std::bad_alloc&)
2895 {
2896 return error(GL_OUT_OF_MEMORY);
2897 }
2898}
2899
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002900void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002901{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002902 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 +00002903 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002904
2905 try
2906 {
2907 if (bufsize < 0)
2908 {
2909 return error(GL_INVALID_VALUE);
2910 }
2911
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002912 gl::Context *context = gl::getContext();
2913
2914 if (context)
2915 {
2916 gl::Program *programObject = context->getProgram(program);
2917
2918 if (!programObject)
2919 {
2920 return error(GL_INVALID_VALUE);
2921 }
2922
2923 programObject->getInfoLog(bufsize, length, infolog);
2924 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002925 }
2926 catch(std::bad_alloc&)
2927 {
2928 return error(GL_OUT_OF_MEMORY);
2929 }
2930}
2931
2932void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2933{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002934 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 +00002935
2936 try
2937 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002938 gl::Context *context = gl::getContext();
2939
2940 if (context)
2941 {
2942 if (target != GL_RENDERBUFFER)
2943 {
2944 return error(GL_INVALID_ENUM);
2945 }
2946
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002947 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002948 {
2949 return error(GL_INVALID_OPERATION);
2950 }
2951
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002952 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002953
2954 switch (pname)
2955 {
2956 case GL_RENDERBUFFER_WIDTH:
2957 *params = renderbuffer->getWidth();
2958 break;
2959 case GL_RENDERBUFFER_HEIGHT:
2960 *params = renderbuffer->getHeight();
2961 break;
2962 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2963 *params = renderbuffer->getFormat();
2964 break;
2965 case GL_RENDERBUFFER_RED_SIZE:
2966 if (renderbuffer->isColorbuffer())
2967 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002968 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002969 }
2970 else
2971 {
2972 *params = 0;
2973 }
2974 break;
2975 case GL_RENDERBUFFER_GREEN_SIZE:
2976 if (renderbuffer->isColorbuffer())
2977 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002978 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002979 }
2980 else
2981 {
2982 *params = 0;
2983 }
2984 break;
2985 case GL_RENDERBUFFER_BLUE_SIZE:
2986 if (renderbuffer->isColorbuffer())
2987 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002988 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002989 }
2990 else
2991 {
2992 *params = 0;
2993 }
2994 break;
2995 case GL_RENDERBUFFER_ALPHA_SIZE:
2996 if (renderbuffer->isColorbuffer())
2997 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002998 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002999 }
3000 else
3001 {
3002 *params = 0;
3003 }
3004 break;
3005 case GL_RENDERBUFFER_DEPTH_SIZE:
3006 if (renderbuffer->isDepthbuffer())
3007 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003008 *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003009 }
3010 else
3011 {
3012 *params = 0;
3013 }
3014 break;
3015 case GL_RENDERBUFFER_STENCIL_SIZE:
3016 if (renderbuffer->isStencilbuffer())
3017 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003018 *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003019 }
3020 else
3021 {
3022 *params = 0;
3023 }
3024 break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003025 case GL_RENDERBUFFER_SAMPLES_ANGLE:
3026 {
3027 if (context->getMaxSupportedSamples() != 0)
3028 {
3029 *params = renderbuffer->getStorage()->getSamples();
3030 }
3031 else
3032 {
3033 return error(GL_INVALID_ENUM);
3034 }
3035 }
3036 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003037 default:
3038 return error(GL_INVALID_ENUM);
3039 }
3040 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003041 }
3042 catch(std::bad_alloc&)
3043 {
3044 return error(GL_OUT_OF_MEMORY);
3045 }
3046}
3047
3048void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3049{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003050 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003051
3052 try
3053 {
3054 gl::Context *context = gl::getContext();
3055
3056 if (context)
3057 {
3058 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003059
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003060 if (!shaderObject)
3061 {
3062 return error(GL_INVALID_VALUE);
3063 }
3064
3065 switch (pname)
3066 {
3067 case GL_SHADER_TYPE:
3068 *params = shaderObject->getType();
3069 return;
3070 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003071 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003072 return;
3073 case GL_COMPILE_STATUS:
3074 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3075 return;
3076 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003077 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003078 return;
3079 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003080 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003081 return;
3082 default:
3083 return error(GL_INVALID_ENUM);
3084 }
3085 }
3086 }
3087 catch(std::bad_alloc&)
3088 {
3089 return error(GL_OUT_OF_MEMORY);
3090 }
3091}
3092
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003093void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003094{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003095 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 +00003096 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003097
3098 try
3099 {
3100 if (bufsize < 0)
3101 {
3102 return error(GL_INVALID_VALUE);
3103 }
3104
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003105 gl::Context *context = gl::getContext();
3106
3107 if (context)
3108 {
3109 gl::Shader *shaderObject = context->getShader(shader);
3110
3111 if (!shaderObject)
3112 {
3113 return error(GL_INVALID_VALUE);
3114 }
3115
3116 shaderObject->getInfoLog(bufsize, length, infolog);
3117 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003118 }
3119 catch(std::bad_alloc&)
3120 {
3121 return error(GL_OUT_OF_MEMORY);
3122 }
3123}
3124
3125void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3126{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003127 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
3128 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003129
3130 try
3131 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003132 switch (shadertype)
3133 {
3134 case GL_VERTEX_SHADER:
3135 case GL_FRAGMENT_SHADER:
3136 break;
3137 default:
3138 return error(GL_INVALID_ENUM);
3139 }
3140
3141 switch (precisiontype)
3142 {
3143 case GL_LOW_FLOAT:
3144 case GL_MEDIUM_FLOAT:
3145 case GL_HIGH_FLOAT:
3146 // Assume IEEE 754 precision
3147 range[0] = 127;
3148 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003149 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003150 break;
3151 case GL_LOW_INT:
3152 case GL_MEDIUM_INT:
3153 case GL_HIGH_INT:
3154 // Some (most) hardware only supports single-precision floating-point numbers,
3155 // which can accurately represent integers up to +/-16777216
3156 range[0] = 24;
3157 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003158 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003159 break;
3160 default:
3161 return error(GL_INVALID_ENUM);
3162 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003163 }
3164 catch(std::bad_alloc&)
3165 {
3166 return error(GL_OUT_OF_MEMORY);
3167 }
3168}
3169
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003170void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003171{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003172 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 +00003173 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003174
3175 try
3176 {
3177 if (bufsize < 0)
3178 {
3179 return error(GL_INVALID_VALUE);
3180 }
3181
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003182 gl::Context *context = gl::getContext();
3183
3184 if (context)
3185 {
3186 gl::Shader *shaderObject = context->getShader(shader);
3187
3188 if (!shaderObject)
3189 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003190 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003191 }
3192
3193 shaderObject->getSource(bufsize, length, source);
3194 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003195 }
3196 catch(std::bad_alloc&)
3197 {
3198 return error(GL_OUT_OF_MEMORY);
3199 }
3200}
3201
3202const GLubyte* __stdcall glGetString(GLenum name)
3203{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003204 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003205
3206 try
3207 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003208 gl::Context *context = gl::getContext();
3209
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003210 switch (name)
3211 {
3212 case GL_VENDOR:
3213 return (GLubyte*)"TransGaming Inc.";
3214 case GL_RENDERER:
3215 return (GLubyte*)"ANGLE";
3216 case GL_VERSION:
3217 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
3218 case GL_SHADING_LANGUAGE_VERSION:
3219 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
3220 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003221 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003222 default:
3223 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3224 }
3225 }
3226 catch(std::bad_alloc&)
3227 {
3228 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3229 }
3230
3231 return NULL;
3232}
3233
3234void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3235{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003236 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 +00003237
3238 try
3239 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003240 gl::Context *context = gl::getContext();
3241
3242 if (context)
3243 {
3244 gl::Texture *texture;
3245
3246 switch (target)
3247 {
3248 case GL_TEXTURE_2D:
3249 texture = context->getTexture2D();
3250 break;
3251 case GL_TEXTURE_CUBE_MAP:
3252 texture = context->getTextureCubeMap();
3253 break;
3254 default:
3255 return error(GL_INVALID_ENUM);
3256 }
3257
3258 switch (pname)
3259 {
3260 case GL_TEXTURE_MAG_FILTER:
3261 *params = (GLfloat)texture->getMagFilter();
3262 break;
3263 case GL_TEXTURE_MIN_FILTER:
3264 *params = (GLfloat)texture->getMinFilter();
3265 break;
3266 case GL_TEXTURE_WRAP_S:
3267 *params = (GLfloat)texture->getWrapS();
3268 break;
3269 case GL_TEXTURE_WRAP_T:
3270 *params = (GLfloat)texture->getWrapT();
3271 break;
3272 default:
3273 return error(GL_INVALID_ENUM);
3274 }
3275 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003276 }
3277 catch(std::bad_alloc&)
3278 {
3279 return error(GL_OUT_OF_MEMORY);
3280 }
3281}
3282
3283void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3284{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003285 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 +00003286
3287 try
3288 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003289 gl::Context *context = gl::getContext();
3290
3291 if (context)
3292 {
3293 gl::Texture *texture;
3294
3295 switch (target)
3296 {
3297 case GL_TEXTURE_2D:
3298 texture = context->getTexture2D();
3299 break;
3300 case GL_TEXTURE_CUBE_MAP:
3301 texture = context->getTextureCubeMap();
3302 break;
3303 default:
3304 return error(GL_INVALID_ENUM);
3305 }
3306
3307 switch (pname)
3308 {
3309 case GL_TEXTURE_MAG_FILTER:
3310 *params = texture->getMagFilter();
3311 break;
3312 case GL_TEXTURE_MIN_FILTER:
3313 *params = texture->getMinFilter();
3314 break;
3315 case GL_TEXTURE_WRAP_S:
3316 *params = texture->getWrapS();
3317 break;
3318 case GL_TEXTURE_WRAP_T:
3319 *params = texture->getWrapT();
3320 break;
3321 default:
3322 return error(GL_INVALID_ENUM);
3323 }
3324 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003325 }
3326 catch(std::bad_alloc&)
3327 {
3328 return error(GL_OUT_OF_MEMORY);
3329 }
3330}
3331
3332void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3333{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003334 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003335
3336 try
3337 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003338 gl::Context *context = gl::getContext();
3339
3340 if (context)
3341 {
3342 if (program == 0)
3343 {
3344 return error(GL_INVALID_VALUE);
3345 }
3346
3347 gl::Program *programObject = context->getProgram(program);
3348
3349 if (!programObject || !programObject->isLinked())
3350 {
3351 return error(GL_INVALID_OPERATION);
3352 }
3353
3354 if (!programObject->getUniformfv(location, params))
3355 {
3356 return error(GL_INVALID_OPERATION);
3357 }
3358 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003359 }
3360 catch(std::bad_alloc&)
3361 {
3362 return error(GL_OUT_OF_MEMORY);
3363 }
3364}
3365
3366void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3367{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003368 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003369
3370 try
3371 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003372 gl::Context *context = gl::getContext();
3373
3374 if (context)
3375 {
3376 if (program == 0)
3377 {
3378 return error(GL_INVALID_VALUE);
3379 }
3380
3381 gl::Program *programObject = context->getProgram(program);
3382
3383 if (!programObject || !programObject->isLinked())
3384 {
3385 return error(GL_INVALID_OPERATION);
3386 }
3387
3388 if (!programObject)
3389 {
3390 return error(GL_INVALID_OPERATION);
3391 }
3392
3393 if (!programObject->getUniformiv(location, params))
3394 {
3395 return error(GL_INVALID_OPERATION);
3396 }
3397 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003398 }
3399 catch(std::bad_alloc&)
3400 {
3401 return error(GL_OUT_OF_MEMORY);
3402 }
3403}
3404
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003405int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003406{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003407 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003408
3409 try
3410 {
3411 gl::Context *context = gl::getContext();
3412
3413 if (strstr(name, "gl_") == name)
3414 {
3415 return -1;
3416 }
3417
3418 if (context)
3419 {
3420 gl::Program *programObject = context->getProgram(program);
3421
3422 if (!programObject)
3423 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003424 if (context->getShader(program))
3425 {
3426 return error(GL_INVALID_OPERATION, -1);
3427 }
3428 else
3429 {
3430 return error(GL_INVALID_VALUE, -1);
3431 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003432 }
3433
3434 if (!programObject->isLinked())
3435 {
3436 return error(GL_INVALID_OPERATION, -1);
3437 }
3438
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003439 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003440 }
3441 }
3442 catch(std::bad_alloc&)
3443 {
3444 return error(GL_OUT_OF_MEMORY, -1);
3445 }
3446
3447 return -1;
3448}
3449
3450void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3451{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003452 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003453
3454 try
3455 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003456 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003457
daniel@transgaming.come0078962010-04-15 20:45:08 +00003458 if (context)
3459 {
3460 if (index >= gl::MAX_VERTEX_ATTRIBS)
3461 {
3462 return error(GL_INVALID_VALUE);
3463 }
3464
daniel@transgaming.com83921382011-01-08 05:46:00 +00003465 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003466
daniel@transgaming.come0078962010-04-15 20:45:08 +00003467 switch (pname)
3468 {
3469 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003470 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003471 break;
3472 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003473 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003474 break;
3475 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003476 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003477 break;
3478 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003479 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003480 break;
3481 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003482 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003483 break;
3484 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003485 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003486 break;
3487 case GL_CURRENT_VERTEX_ATTRIB:
3488 for (int i = 0; i < 4; ++i)
3489 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003490 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003491 }
3492 break;
3493 default: return error(GL_INVALID_ENUM);
3494 }
3495 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003496 }
3497 catch(std::bad_alloc&)
3498 {
3499 return error(GL_OUT_OF_MEMORY);
3500 }
3501}
3502
3503void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3504{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003505 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003506
3507 try
3508 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003509 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003510
daniel@transgaming.come0078962010-04-15 20:45:08 +00003511 if (context)
3512 {
3513 if (index >= gl::MAX_VERTEX_ATTRIBS)
3514 {
3515 return error(GL_INVALID_VALUE);
3516 }
3517
daniel@transgaming.com83921382011-01-08 05:46:00 +00003518 const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003519
daniel@transgaming.come0078962010-04-15 20:45:08 +00003520 switch (pname)
3521 {
3522 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com83921382011-01-08 05:46:00 +00003523 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003524 break;
3525 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003526 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003527 break;
3528 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003529 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003530 break;
3531 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003532 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003533 break;
3534 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003535 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003536 break;
3537 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003538 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003539 break;
3540 case GL_CURRENT_VERTEX_ATTRIB:
3541 for (int i = 0; i < 4; ++i)
3542 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003543 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003544 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3545 }
3546 break;
3547 default: return error(GL_INVALID_ENUM);
3548 }
3549 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003550 }
3551 catch(std::bad_alloc&)
3552 {
3553 return error(GL_OUT_OF_MEMORY);
3554 }
3555}
3556
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003557void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003558{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003559 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003560
3561 try
3562 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003563 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003564
daniel@transgaming.come0078962010-04-15 20:45:08 +00003565 if (context)
3566 {
3567 if (index >= gl::MAX_VERTEX_ATTRIBS)
3568 {
3569 return error(GL_INVALID_VALUE);
3570 }
3571
3572 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3573 {
3574 return error(GL_INVALID_ENUM);
3575 }
3576
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003577 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003578 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003579 }
3580 catch(std::bad_alloc&)
3581 {
3582 return error(GL_OUT_OF_MEMORY);
3583 }
3584}
3585
3586void __stdcall glHint(GLenum target, GLenum mode)
3587{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003588 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003589
3590 try
3591 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003592 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003593 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003594 case GL_FASTEST:
3595 case GL_NICEST:
3596 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003597 break;
3598 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003599 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003600 }
3601
3602 gl::Context *context = gl::getContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003603 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003604 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003605 case GL_GENERATE_MIPMAP_HINT:
3606 if (context) context->setGenerateMipmapHint(mode);
3607 break;
3608 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3609 if (context) context->setFragmentShaderDerivativeHint(mode);
3610 break;
3611 default:
3612 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003613 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003614 }
3615 catch(std::bad_alloc&)
3616 {
3617 return error(GL_OUT_OF_MEMORY);
3618 }
3619}
3620
3621GLboolean __stdcall glIsBuffer(GLuint buffer)
3622{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003623 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003624
3625 try
3626 {
3627 gl::Context *context = gl::getContext();
3628
3629 if (context && buffer)
3630 {
3631 gl::Buffer *bufferObject = context->getBuffer(buffer);
3632
3633 if (bufferObject)
3634 {
3635 return GL_TRUE;
3636 }
3637 }
3638 }
3639 catch(std::bad_alloc&)
3640 {
3641 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3642 }
3643
3644 return GL_FALSE;
3645}
3646
3647GLboolean __stdcall glIsEnabled(GLenum cap)
3648{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003649 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003650
3651 try
3652 {
3653 gl::Context *context = gl::getContext();
3654
3655 if (context)
3656 {
3657 switch (cap)
3658 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003659 case GL_CULL_FACE: return context->isCullFaceEnabled();
3660 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3661 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3662 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3663 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3664 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3665 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3666 case GL_BLEND: return context->isBlendEnabled();
3667 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003668 default:
3669 return error(GL_INVALID_ENUM, false);
3670 }
3671 }
3672 }
3673 catch(std::bad_alloc&)
3674 {
3675 return error(GL_OUT_OF_MEMORY, false);
3676 }
3677
3678 return false;
3679}
3680
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003681GLboolean __stdcall glIsFenceNV(GLuint fence)
3682{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003683 TRACE("(GLuint fence = %d)", fence);
3684
3685 try
3686 {
3687 gl::Context *context = gl::getContext();
3688
3689 if (context)
3690 {
3691 gl::Fence *fenceObject = context->getFence(fence);
3692
3693 if (fenceObject == NULL)
3694 {
3695 return GL_FALSE;
3696 }
3697
3698 return fenceObject->isFence();
3699 }
3700 }
3701 catch(std::bad_alloc&)
3702 {
3703 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3704 }
3705
3706 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003707}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003708
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003709GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3710{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003711 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003712
3713 try
3714 {
3715 gl::Context *context = gl::getContext();
3716
3717 if (context && framebuffer)
3718 {
3719 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3720
3721 if (framebufferObject)
3722 {
3723 return GL_TRUE;
3724 }
3725 }
3726 }
3727 catch(std::bad_alloc&)
3728 {
3729 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3730 }
3731
3732 return GL_FALSE;
3733}
3734
3735GLboolean __stdcall glIsProgram(GLuint program)
3736{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003737 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003738
3739 try
3740 {
3741 gl::Context *context = gl::getContext();
3742
3743 if (context && program)
3744 {
3745 gl::Program *programObject = context->getProgram(program);
3746
3747 if (programObject)
3748 {
3749 return GL_TRUE;
3750 }
3751 }
3752 }
3753 catch(std::bad_alloc&)
3754 {
3755 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3756 }
3757
3758 return GL_FALSE;
3759}
3760
3761GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3762{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003763 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003764
3765 try
3766 {
3767 gl::Context *context = gl::getContext();
3768
3769 if (context && renderbuffer)
3770 {
3771 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3772
3773 if (renderbufferObject)
3774 {
3775 return GL_TRUE;
3776 }
3777 }
3778 }
3779 catch(std::bad_alloc&)
3780 {
3781 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3782 }
3783
3784 return GL_FALSE;
3785}
3786
3787GLboolean __stdcall glIsShader(GLuint shader)
3788{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003789 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003790
3791 try
3792 {
3793 gl::Context *context = gl::getContext();
3794
3795 if (context && shader)
3796 {
3797 gl::Shader *shaderObject = context->getShader(shader);
3798
3799 if (shaderObject)
3800 {
3801 return GL_TRUE;
3802 }
3803 }
3804 }
3805 catch(std::bad_alloc&)
3806 {
3807 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3808 }
3809
3810 return GL_FALSE;
3811}
3812
3813GLboolean __stdcall glIsTexture(GLuint texture)
3814{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003815 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003816
3817 try
3818 {
3819 gl::Context *context = gl::getContext();
3820
3821 if (context && texture)
3822 {
3823 gl::Texture *textureObject = context->getTexture(texture);
3824
3825 if (textureObject)
3826 {
3827 return GL_TRUE;
3828 }
3829 }
3830 }
3831 catch(std::bad_alloc&)
3832 {
3833 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3834 }
3835
3836 return GL_FALSE;
3837}
3838
3839void __stdcall glLineWidth(GLfloat width)
3840{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003841 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003842
3843 try
3844 {
3845 if (width <= 0.0f)
3846 {
3847 return error(GL_INVALID_VALUE);
3848 }
3849
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003850 gl::Context *context = gl::getContext();
3851
3852 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003853 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003854 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003855 }
3856 }
3857 catch(std::bad_alloc&)
3858 {
3859 return error(GL_OUT_OF_MEMORY);
3860 }
3861}
3862
3863void __stdcall glLinkProgram(GLuint program)
3864{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003865 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003866
3867 try
3868 {
3869 gl::Context *context = gl::getContext();
3870
3871 if (context)
3872 {
3873 gl::Program *programObject = context->getProgram(program);
3874
3875 if (!programObject)
3876 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003877 if (context->getShader(program))
3878 {
3879 return error(GL_INVALID_OPERATION);
3880 }
3881 else
3882 {
3883 return error(GL_INVALID_VALUE);
3884 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003885 }
3886
3887 programObject->link();
3888 }
3889 }
3890 catch(std::bad_alloc&)
3891 {
3892 return error(GL_OUT_OF_MEMORY);
3893 }
3894}
3895
3896void __stdcall glPixelStorei(GLenum pname, GLint param)
3897{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003898 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003899
3900 try
3901 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003902 gl::Context *context = gl::getContext();
3903
3904 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003905 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003906 switch (pname)
3907 {
3908 case GL_UNPACK_ALIGNMENT:
3909 if (param != 1 && param != 2 && param != 4 && param != 8)
3910 {
3911 return error(GL_INVALID_VALUE);
3912 }
3913
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003914 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003915 break;
3916
3917 case GL_PACK_ALIGNMENT:
3918 if (param != 1 && param != 2 && param != 4 && param != 8)
3919 {
3920 return error(GL_INVALID_VALUE);
3921 }
3922
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003923 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003924 break;
3925
3926 default:
3927 return error(GL_INVALID_ENUM);
3928 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003929 }
3930 }
3931 catch(std::bad_alloc&)
3932 {
3933 return error(GL_OUT_OF_MEMORY);
3934 }
3935}
3936
3937void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3938{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003939 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003940
3941 try
3942 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003943 gl::Context *context = gl::getContext();
3944
3945 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003946 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003947 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003948 }
3949 }
3950 catch(std::bad_alloc&)
3951 {
3952 return error(GL_OUT_OF_MEMORY);
3953 }
3954}
3955
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003956void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003957{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003958 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003959 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003960 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003961
3962 try
3963 {
3964 if (width < 0 || height < 0)
3965 {
3966 return error(GL_INVALID_VALUE);
3967 }
3968
3969 switch (format)
3970 {
3971 case GL_RGBA:
3972 switch (type)
3973 {
3974 case GL_UNSIGNED_BYTE:
3975 break;
3976 default:
3977 return error(GL_INVALID_OPERATION);
3978 }
3979 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003980 case GL_BGRA_EXT:
3981 switch (type)
3982 {
3983 case GL_UNSIGNED_BYTE:
3984 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3985 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3986 break;
3987 default:
3988 return error(GL_INVALID_OPERATION);
3989 }
3990 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003991 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3992 switch (type)
3993 {
3994 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3995 break;
3996 default:
3997 return error(GL_INVALID_OPERATION);
3998 }
3999 break;
4000 default:
4001 return error(GL_INVALID_OPERATION);
4002 }
4003
4004 gl::Context *context = gl::getContext();
4005
4006 if (context)
4007 {
4008 context->readPixels(x, y, width, height, format, type, pixels);
4009 }
4010 }
4011 catch(std::bad_alloc&)
4012 {
4013 return error(GL_OUT_OF_MEMORY);
4014 }
4015}
4016
4017void __stdcall glReleaseShaderCompiler(void)
4018{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004019 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004020
4021 try
4022 {
4023 gl::Shader::releaseCompiler();
4024 }
4025 catch(std::bad_alloc&)
4026 {
4027 return error(GL_OUT_OF_MEMORY);
4028 }
4029}
4030
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004031void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004032{
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004033 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4034 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004035
4036 try
4037 {
4038 switch (target)
4039 {
4040 case GL_RENDERBUFFER:
4041 break;
4042 default:
4043 return error(GL_INVALID_ENUM);
4044 }
4045
daniel@transgaming.comedc19182010-10-15 17:57:55 +00004046 if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004047 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004048 return error(GL_INVALID_ENUM);
4049 }
4050
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004051 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004052 {
4053 return error(GL_INVALID_VALUE);
4054 }
4055
4056 gl::Context *context = gl::getContext();
4057
4058 if (context)
4059 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004060 if (width > context->getMaximumRenderbufferDimension() ||
4061 height > context->getMaximumRenderbufferDimension() ||
4062 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004063 {
4064 return error(GL_INVALID_VALUE);
4065 }
4066
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004067 GLuint handle = context->getRenderbufferHandle();
4068 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004069 {
4070 return error(GL_INVALID_OPERATION);
4071 }
4072
4073 switch (internalformat)
4074 {
4075 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004076 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004077 break;
4078 case GL_RGBA4:
4079 case GL_RGB5_A1:
4080 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004081 case GL_RGB8_OES:
4082 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004083 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004084 break;
4085 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004086 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004087 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004088 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004089 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004090 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004091 default:
4092 return error(GL_INVALID_ENUM);
4093 }
4094 }
4095 }
4096 catch(std::bad_alloc&)
4097 {
4098 return error(GL_OUT_OF_MEMORY);
4099 }
4100}
4101
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004102void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4103{
4104 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4105}
4106
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004107void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4108{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004109 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004110
4111 try
4112 {
4113 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004114
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004115 if (context)
4116 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004117 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004118 }
4119 }
4120 catch(std::bad_alloc&)
4121 {
4122 return error(GL_OUT_OF_MEMORY);
4123 }
4124}
4125
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004126void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4127{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004128 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
4129
4130 try
4131 {
4132 if (condition != GL_ALL_COMPLETED_NV)
4133 {
4134 return error(GL_INVALID_ENUM);
4135 }
4136
4137 gl::Context *context = gl::getContext();
4138
4139 if (context)
4140 {
4141 gl::Fence *fenceObject = context->getFence(fence);
4142
4143 if (fenceObject == NULL)
4144 {
4145 return error(GL_INVALID_OPERATION);
4146 }
4147
4148 fenceObject->setFence(condition);
4149 }
4150 }
4151 catch(std::bad_alloc&)
4152 {
4153 return error(GL_OUT_OF_MEMORY);
4154 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004155}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004156
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004157void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4158{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004159 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 +00004160
4161 try
4162 {
4163 if (width < 0 || height < 0)
4164 {
4165 return error(GL_INVALID_VALUE);
4166 }
4167
4168 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004169
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004170 if (context)
4171 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004172 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004173 }
4174 }
4175 catch(std::bad_alloc&)
4176 {
4177 return error(GL_OUT_OF_MEMORY);
4178 }
4179}
4180
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004181void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004182{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004183 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004184 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004185 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004186
4187 try
4188 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004189 // No binary shader formats are supported.
4190 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004191 }
4192 catch(std::bad_alloc&)
4193 {
4194 return error(GL_OUT_OF_MEMORY);
4195 }
4196}
4197
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004198void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004199{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004200 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 +00004201 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004202
4203 try
4204 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004205 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004206 {
4207 return error(GL_INVALID_VALUE);
4208 }
4209
4210 gl::Context *context = gl::getContext();
4211
4212 if (context)
4213 {
4214 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004215
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004216 if (!shaderObject)
4217 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004218 if (context->getProgram(shader))
4219 {
4220 return error(GL_INVALID_OPERATION);
4221 }
4222 else
4223 {
4224 return error(GL_INVALID_VALUE);
4225 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004226 }
4227
4228 shaderObject->setSource(count, string, length);
4229 }
4230 }
4231 catch(std::bad_alloc&)
4232 {
4233 return error(GL_OUT_OF_MEMORY);
4234 }
4235}
4236
4237void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4238{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004239 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004240}
4241
4242void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4243{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004244 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 +00004245
4246 try
4247 {
4248 switch (face)
4249 {
4250 case GL_FRONT:
4251 case GL_BACK:
4252 case GL_FRONT_AND_BACK:
4253 break;
4254 default:
4255 return error(GL_INVALID_ENUM);
4256 }
4257
4258 switch (func)
4259 {
4260 case GL_NEVER:
4261 case GL_ALWAYS:
4262 case GL_LESS:
4263 case GL_LEQUAL:
4264 case GL_EQUAL:
4265 case GL_GEQUAL:
4266 case GL_GREATER:
4267 case GL_NOTEQUAL:
4268 break;
4269 default:
4270 return error(GL_INVALID_ENUM);
4271 }
4272
4273 gl::Context *context = gl::getContext();
4274
4275 if (context)
4276 {
4277 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4278 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004279 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004280 }
4281
4282 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4283 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004284 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004285 }
4286 }
4287 }
4288 catch(std::bad_alloc&)
4289 {
4290 return error(GL_OUT_OF_MEMORY);
4291 }
4292}
4293
4294void __stdcall glStencilMask(GLuint mask)
4295{
4296 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4297}
4298
4299void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4300{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004301 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004302
4303 try
4304 {
4305 switch (face)
4306 {
4307 case GL_FRONT:
4308 case GL_BACK:
4309 case GL_FRONT_AND_BACK:
4310 break;
4311 default:
4312 return error(GL_INVALID_ENUM);
4313 }
4314
4315 gl::Context *context = gl::getContext();
4316
4317 if (context)
4318 {
4319 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4320 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004321 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004322 }
4323
4324 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4325 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004326 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004327 }
4328 }
4329 }
4330 catch(std::bad_alloc&)
4331 {
4332 return error(GL_OUT_OF_MEMORY);
4333 }
4334}
4335
4336void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4337{
4338 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4339}
4340
4341void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4342{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004343 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4344 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004345
4346 try
4347 {
4348 switch (face)
4349 {
4350 case GL_FRONT:
4351 case GL_BACK:
4352 case GL_FRONT_AND_BACK:
4353 break;
4354 default:
4355 return error(GL_INVALID_ENUM);
4356 }
4357
4358 switch (fail)
4359 {
4360 case GL_ZERO:
4361 case GL_KEEP:
4362 case GL_REPLACE:
4363 case GL_INCR:
4364 case GL_DECR:
4365 case GL_INVERT:
4366 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004367 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004368 break;
4369 default:
4370 return error(GL_INVALID_ENUM);
4371 }
4372
4373 switch (zfail)
4374 {
4375 case GL_ZERO:
4376 case GL_KEEP:
4377 case GL_REPLACE:
4378 case GL_INCR:
4379 case GL_DECR:
4380 case GL_INVERT:
4381 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004382 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004383 break;
4384 default:
4385 return error(GL_INVALID_ENUM);
4386 }
4387
4388 switch (zpass)
4389 {
4390 case GL_ZERO:
4391 case GL_KEEP:
4392 case GL_REPLACE:
4393 case GL_INCR:
4394 case GL_DECR:
4395 case GL_INVERT:
4396 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004397 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004398 break;
4399 default:
4400 return error(GL_INVALID_ENUM);
4401 }
4402
4403 gl::Context *context = gl::getContext();
4404
4405 if (context)
4406 {
4407 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4408 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004409 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004410 }
4411
4412 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4413 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004414 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004415 }
4416 }
4417 }
4418 catch(std::bad_alloc&)
4419 {
4420 return error(GL_OUT_OF_MEMORY);
4421 }
4422}
4423
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004424GLboolean __stdcall glTestFenceNV(GLuint fence)
4425{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004426 TRACE("(GLuint fence = %d)", fence);
4427
4428 try
4429 {
4430 gl::Context *context = gl::getContext();
4431
4432 if (context)
4433 {
4434 gl::Fence *fenceObject = context->getFence(fence);
4435
4436 if (fenceObject == NULL)
4437 {
4438 return error(GL_INVALID_OPERATION, GL_TRUE);
4439 }
4440
4441 return fenceObject->testFence();
4442 }
4443 }
4444 catch(std::bad_alloc&)
4445 {
4446 error(GL_OUT_OF_MEMORY);
4447 }
4448
4449 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004450}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004451
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004452void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4453 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004454{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004455 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 +00004456 "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 +00004457 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004458
4459 try
4460 {
4461 if (level < 0 || width < 0 || height < 0)
4462 {
4463 return error(GL_INVALID_VALUE);
4464 }
4465
4466 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
4467 {
4468 return error(GL_INVALID_VALUE);
4469 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004470
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004471 if (internalformat != format)
4472 {
4473 return error(GL_INVALID_OPERATION);
4474 }
4475
4476 switch (internalformat)
4477 {
4478 case GL_ALPHA:
4479 case GL_LUMINANCE:
4480 case GL_LUMINANCE_ALPHA:
4481 switch (type)
4482 {
4483 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004484 case GL_FLOAT:
4485 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004486 break;
4487 default:
4488 return error(GL_INVALID_ENUM);
4489 }
4490 break;
4491 case GL_RGB:
4492 switch (type)
4493 {
4494 case GL_UNSIGNED_BYTE:
4495 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004496 case GL_FLOAT:
4497 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004498 break;
4499 default:
4500 return error(GL_INVALID_ENUM);
4501 }
4502 break;
4503 case GL_RGBA:
4504 switch (type)
4505 {
4506 case GL_UNSIGNED_BYTE:
4507 case GL_UNSIGNED_SHORT_4_4_4_4:
4508 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004509 case GL_FLOAT:
4510 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004511 break;
4512 default:
4513 return error(GL_INVALID_ENUM);
4514 }
4515 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004516 case GL_BGRA_EXT:
4517 switch (type)
4518 {
4519 case GL_UNSIGNED_BYTE:
4520 break;
4521 default:
4522 return error(GL_INVALID_ENUM);
4523 }
4524 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004525 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4526 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4527 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004528 default:
4529 return error(GL_INVALID_VALUE);
4530 }
4531
4532 if (border != 0)
4533 {
4534 return error(GL_INVALID_VALUE);
4535 }
4536
4537 gl::Context *context = gl::getContext();
4538
4539 if (context)
4540 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004541 switch (target)
4542 {
4543 case GL_TEXTURE_2D:
4544 if (width > (context->getMaximumTextureDimension() >> level) ||
4545 height > (context->getMaximumTextureDimension() >> level))
4546 {
4547 return error(GL_INVALID_VALUE);
4548 }
4549 break;
4550 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4551 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4552 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4553 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4554 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4555 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4556 if (width != height)
4557 {
4558 return error(GL_INVALID_VALUE);
4559 }
4560
4561 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4562 height > (context->getMaximumCubeTextureDimension() >> level))
4563 {
4564 return error(GL_INVALID_VALUE);
4565 }
4566 break;
4567 default:
4568 return error(GL_INVALID_ENUM);
4569 }
4570
daniel@transgaming.com01868132010-08-24 19:21:17 +00004571 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4572 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
4573 {
4574 if (context->supportsCompressedTextures())
4575 {
4576 return error(GL_INVALID_OPERATION);
4577 }
4578 else
4579 {
4580 return error(GL_INVALID_ENUM);
4581 }
4582 }
4583
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004584 if (type == GL_FLOAT)
4585 {
4586 if (!context->supportsFloatTextures())
4587 {
4588 return error(GL_INVALID_ENUM);
4589 }
4590 }
4591 else if (type == GL_HALF_FLOAT_OES)
4592 {
4593 if (!context->supportsHalfFloatTextures())
4594 {
4595 return error(GL_INVALID_ENUM);
4596 }
4597 }
4598
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004599 if (target == GL_TEXTURE_2D)
4600 {
4601 gl::Texture2D *texture = context->getTexture2D();
4602
4603 if (!texture)
4604 {
4605 return error(GL_INVALID_OPERATION);
4606 }
4607
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004608 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004609 }
4610 else
4611 {
4612 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4613
4614 if (!texture)
4615 {
4616 return error(GL_INVALID_OPERATION);
4617 }
4618
4619 switch (target)
4620 {
4621 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004622 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004623 break;
4624 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004625 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004626 break;
4627 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004628 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004629 break;
4630 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004631 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004632 break;
4633 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004634 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004635 break;
4636 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004637 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004638 break;
4639 default: UNREACHABLE();
4640 }
4641 }
4642 }
4643 }
4644 catch(std::bad_alloc&)
4645 {
4646 return error(GL_OUT_OF_MEMORY);
4647 }
4648}
4649
4650void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4651{
4652 glTexParameteri(target, pname, (GLint)param);
4653}
4654
4655void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4656{
4657 glTexParameteri(target, pname, (GLint)*params);
4658}
4659
4660void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4661{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004662 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004663
4664 try
4665 {
4666 gl::Context *context = gl::getContext();
4667
4668 if (context)
4669 {
4670 gl::Texture *texture;
4671
4672 switch (target)
4673 {
4674 case GL_TEXTURE_2D:
4675 texture = context->getTexture2D();
4676 break;
4677 case GL_TEXTURE_CUBE_MAP:
4678 texture = context->getTextureCubeMap();
4679 break;
4680 default:
4681 return error(GL_INVALID_ENUM);
4682 }
4683
4684 switch (pname)
4685 {
4686 case GL_TEXTURE_WRAP_S:
4687 if (!texture->setWrapS((GLenum)param))
4688 {
4689 return error(GL_INVALID_ENUM);
4690 }
4691 break;
4692 case GL_TEXTURE_WRAP_T:
4693 if (!texture->setWrapT((GLenum)param))
4694 {
4695 return error(GL_INVALID_ENUM);
4696 }
4697 break;
4698 case GL_TEXTURE_MIN_FILTER:
4699 if (!texture->setMinFilter((GLenum)param))
4700 {
4701 return error(GL_INVALID_ENUM);
4702 }
4703 break;
4704 case GL_TEXTURE_MAG_FILTER:
4705 if (!texture->setMagFilter((GLenum)param))
4706 {
4707 return error(GL_INVALID_ENUM);
4708 }
4709 break;
4710 default:
4711 return error(GL_INVALID_ENUM);
4712 }
4713 }
4714 }
4715 catch(std::bad_alloc&)
4716 {
4717 return error(GL_OUT_OF_MEMORY);
4718 }
4719}
4720
4721void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4722{
4723 glTexParameteri(target, pname, *params);
4724}
4725
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004726void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4727 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004728{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004729 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4730 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004731 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004732 target, level, xoffset, yoffset, width, height, format, type, pixels);
4733
4734 try
4735 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004736 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004737 {
4738 return error(GL_INVALID_ENUM);
4739 }
4740
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004741 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004742 {
4743 return error(GL_INVALID_VALUE);
4744 }
4745
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004746 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4747 {
4748 return error(GL_INVALID_VALUE);
4749 }
4750
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004751 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004752 {
4753 return error(GL_INVALID_ENUM);
4754 }
4755
4756 if (width == 0 || height == 0 || pixels == NULL)
4757 {
4758 return;
4759 }
4760
4761 gl::Context *context = gl::getContext();
4762
4763 if (context)
4764 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004765 if (level > context->getMaximumTextureLevel())
4766 {
4767 return error(GL_INVALID_VALUE);
4768 }
4769
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004770 if (format == GL_FLOAT)
4771 {
4772 if (!context->supportsFloatTextures())
4773 {
4774 return error(GL_INVALID_ENUM);
4775 }
4776 }
4777 else if (format == GL_HALF_FLOAT_OES)
4778 {
4779 if (!context->supportsHalfFloatTextures())
4780 {
4781 return error(GL_INVALID_ENUM);
4782 }
4783 }
4784
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004785 if (target == GL_TEXTURE_2D)
4786 {
4787 gl::Texture2D *texture = context->getTexture2D();
4788
4789 if (!texture)
4790 {
4791 return error(GL_INVALID_OPERATION);
4792 }
4793
daniel@transgaming.com01868132010-08-24 19:21:17 +00004794 if (texture->isCompressed())
4795 {
4796 return error(GL_INVALID_OPERATION);
4797 }
4798
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004799 if (format != texture->getFormat())
4800 {
4801 return error(GL_INVALID_OPERATION);
4802 }
4803
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004804 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004805 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004806 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004807 {
4808 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4809
4810 if (!texture)
4811 {
4812 return error(GL_INVALID_OPERATION);
4813 }
4814
daniel@transgaming.com01868132010-08-24 19:21:17 +00004815 if (texture->isCompressed())
4816 {
4817 return error(GL_INVALID_OPERATION);
4818 }
4819
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004820 if (format != texture->getFormat())
4821 {
4822 return error(GL_INVALID_OPERATION);
4823 }
4824
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004825 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004826 }
4827 else
4828 {
4829 UNREACHABLE();
4830 }
4831 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004832 }
4833 catch(std::bad_alloc&)
4834 {
4835 return error(GL_OUT_OF_MEMORY);
4836 }
4837}
4838
4839void __stdcall glUniform1f(GLint location, GLfloat x)
4840{
4841 glUniform1fv(location, 1, &x);
4842}
4843
4844void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4845{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004846 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004847
4848 try
4849 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004850 if (count < 0)
4851 {
4852 return error(GL_INVALID_VALUE);
4853 }
4854
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004855 if (location == -1)
4856 {
4857 return;
4858 }
4859
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004860 gl::Context *context = gl::getContext();
4861
4862 if (context)
4863 {
4864 gl::Program *program = context->getCurrentProgram();
4865
4866 if (!program)
4867 {
4868 return error(GL_INVALID_OPERATION);
4869 }
4870
4871 if (!program->setUniform1fv(location, count, v))
4872 {
4873 return error(GL_INVALID_OPERATION);
4874 }
4875 }
4876 }
4877 catch(std::bad_alloc&)
4878 {
4879 return error(GL_OUT_OF_MEMORY);
4880 }
4881}
4882
4883void __stdcall glUniform1i(GLint location, GLint x)
4884{
4885 glUniform1iv(location, 1, &x);
4886}
4887
4888void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4889{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004890 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004891
4892 try
4893 {
4894 if (count < 0)
4895 {
4896 return error(GL_INVALID_VALUE);
4897 }
4898
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004899 if (location == -1)
4900 {
4901 return;
4902 }
4903
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004904 gl::Context *context = gl::getContext();
4905
4906 if (context)
4907 {
4908 gl::Program *program = context->getCurrentProgram();
4909
4910 if (!program)
4911 {
4912 return error(GL_INVALID_OPERATION);
4913 }
4914
4915 if (!program->setUniform1iv(location, count, v))
4916 {
4917 return error(GL_INVALID_OPERATION);
4918 }
4919 }
4920 }
4921 catch(std::bad_alloc&)
4922 {
4923 return error(GL_OUT_OF_MEMORY);
4924 }
4925}
4926
4927void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4928{
4929 GLfloat xy[2] = {x, y};
4930
4931 glUniform2fv(location, 1, (GLfloat*)&xy);
4932}
4933
4934void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4935{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004936 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004937
4938 try
4939 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004940 if (count < 0)
4941 {
4942 return error(GL_INVALID_VALUE);
4943 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004944
4945 if (location == -1)
4946 {
4947 return;
4948 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004949
4950 gl::Context *context = gl::getContext();
4951
4952 if (context)
4953 {
4954 gl::Program *program = context->getCurrentProgram();
4955
4956 if (!program)
4957 {
4958 return error(GL_INVALID_OPERATION);
4959 }
4960
4961 if (!program->setUniform2fv(location, count, v))
4962 {
4963 return error(GL_INVALID_OPERATION);
4964 }
4965 }
4966 }
4967 catch(std::bad_alloc&)
4968 {
4969 return error(GL_OUT_OF_MEMORY);
4970 }
4971}
4972
4973void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4974{
4975 GLint xy[4] = {x, y};
4976
4977 glUniform2iv(location, 1, (GLint*)&xy);
4978}
4979
4980void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4981{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004982 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004983
4984 try
4985 {
4986 if (count < 0)
4987 {
4988 return error(GL_INVALID_VALUE);
4989 }
4990
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004991 if (location == -1)
4992 {
4993 return;
4994 }
4995
4996 gl::Context *context = gl::getContext();
4997
4998 if (context)
4999 {
5000 gl::Program *program = context->getCurrentProgram();
5001
5002 if (!program)
5003 {
5004 return error(GL_INVALID_OPERATION);
5005 }
5006
5007 if (!program->setUniform2iv(location, count, v))
5008 {
5009 return error(GL_INVALID_OPERATION);
5010 }
5011 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005012 }
5013 catch(std::bad_alloc&)
5014 {
5015 return error(GL_OUT_OF_MEMORY);
5016 }
5017}
5018
5019void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5020{
5021 GLfloat xyz[3] = {x, y, z};
5022
5023 glUniform3fv(location, 1, (GLfloat*)&xyz);
5024}
5025
5026void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5027{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005028 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005029
5030 try
5031 {
5032 if (count < 0)
5033 {
5034 return error(GL_INVALID_VALUE);
5035 }
5036
5037 if (location == -1)
5038 {
5039 return;
5040 }
5041
5042 gl::Context *context = gl::getContext();
5043
5044 if (context)
5045 {
5046 gl::Program *program = context->getCurrentProgram();
5047
5048 if (!program)
5049 {
5050 return error(GL_INVALID_OPERATION);
5051 }
5052
5053 if (!program->setUniform3fv(location, count, v))
5054 {
5055 return error(GL_INVALID_OPERATION);
5056 }
5057 }
5058 }
5059 catch(std::bad_alloc&)
5060 {
5061 return error(GL_OUT_OF_MEMORY);
5062 }
5063}
5064
5065void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5066{
5067 GLint xyz[3] = {x, y, z};
5068
5069 glUniform3iv(location, 1, (GLint*)&xyz);
5070}
5071
5072void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5073{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005074 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005075
5076 try
5077 {
5078 if (count < 0)
5079 {
5080 return error(GL_INVALID_VALUE);
5081 }
5082
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005083 if (location == -1)
5084 {
5085 return;
5086 }
5087
5088 gl::Context *context = gl::getContext();
5089
5090 if (context)
5091 {
5092 gl::Program *program = context->getCurrentProgram();
5093
5094 if (!program)
5095 {
5096 return error(GL_INVALID_OPERATION);
5097 }
5098
5099 if (!program->setUniform3iv(location, count, v))
5100 {
5101 return error(GL_INVALID_OPERATION);
5102 }
5103 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005104 }
5105 catch(std::bad_alloc&)
5106 {
5107 return error(GL_OUT_OF_MEMORY);
5108 }
5109}
5110
5111void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5112{
5113 GLfloat xyzw[4] = {x, y, z, w};
5114
5115 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5116}
5117
5118void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5119{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005120 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005121
5122 try
5123 {
5124 if (count < 0)
5125 {
5126 return error(GL_INVALID_VALUE);
5127 }
5128
5129 if (location == -1)
5130 {
5131 return;
5132 }
5133
5134 gl::Context *context = gl::getContext();
5135
5136 if (context)
5137 {
5138 gl::Program *program = context->getCurrentProgram();
5139
5140 if (!program)
5141 {
5142 return error(GL_INVALID_OPERATION);
5143 }
5144
5145 if (!program->setUniform4fv(location, count, v))
5146 {
5147 return error(GL_INVALID_OPERATION);
5148 }
5149 }
5150 }
5151 catch(std::bad_alloc&)
5152 {
5153 return error(GL_OUT_OF_MEMORY);
5154 }
5155}
5156
5157void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5158{
5159 GLint xyzw[4] = {x, y, z, w};
5160
5161 glUniform4iv(location, 1, (GLint*)&xyzw);
5162}
5163
5164void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5165{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005166 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005167
5168 try
5169 {
5170 if (count < 0)
5171 {
5172 return error(GL_INVALID_VALUE);
5173 }
5174
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005175 if (location == -1)
5176 {
5177 return;
5178 }
5179
5180 gl::Context *context = gl::getContext();
5181
5182 if (context)
5183 {
5184 gl::Program *program = context->getCurrentProgram();
5185
5186 if (!program)
5187 {
5188 return error(GL_INVALID_OPERATION);
5189 }
5190
5191 if (!program->setUniform4iv(location, count, v))
5192 {
5193 return error(GL_INVALID_OPERATION);
5194 }
5195 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005196 }
5197 catch(std::bad_alloc&)
5198 {
5199 return error(GL_OUT_OF_MEMORY);
5200 }
5201}
5202
5203void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5204{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005205 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5206 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005207
5208 try
5209 {
5210 if (count < 0 || transpose != GL_FALSE)
5211 {
5212 return error(GL_INVALID_VALUE);
5213 }
5214
5215 if (location == -1)
5216 {
5217 return;
5218 }
5219
5220 gl::Context *context = gl::getContext();
5221
5222 if (context)
5223 {
5224 gl::Program *program = context->getCurrentProgram();
5225
5226 if (!program)
5227 {
5228 return error(GL_INVALID_OPERATION);
5229 }
5230
5231 if (!program->setUniformMatrix2fv(location, count, value))
5232 {
5233 return error(GL_INVALID_OPERATION);
5234 }
5235 }
5236 }
5237 catch(std::bad_alloc&)
5238 {
5239 return error(GL_OUT_OF_MEMORY);
5240 }
5241}
5242
5243void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5244{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005245 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5246 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005247
5248 try
5249 {
5250 if (count < 0 || transpose != GL_FALSE)
5251 {
5252 return error(GL_INVALID_VALUE);
5253 }
5254
5255 if (location == -1)
5256 {
5257 return;
5258 }
5259
5260 gl::Context *context = gl::getContext();
5261
5262 if (context)
5263 {
5264 gl::Program *program = context->getCurrentProgram();
5265
5266 if (!program)
5267 {
5268 return error(GL_INVALID_OPERATION);
5269 }
5270
5271 if (!program->setUniformMatrix3fv(location, count, value))
5272 {
5273 return error(GL_INVALID_OPERATION);
5274 }
5275 }
5276 }
5277 catch(std::bad_alloc&)
5278 {
5279 return error(GL_OUT_OF_MEMORY);
5280 }
5281}
5282
5283void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5284{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005285 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5286 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005287
5288 try
5289 {
5290 if (count < 0 || transpose != GL_FALSE)
5291 {
5292 return error(GL_INVALID_VALUE);
5293 }
5294
5295 if (location == -1)
5296 {
5297 return;
5298 }
5299
5300 gl::Context *context = gl::getContext();
5301
5302 if (context)
5303 {
5304 gl::Program *program = context->getCurrentProgram();
5305
5306 if (!program)
5307 {
5308 return error(GL_INVALID_OPERATION);
5309 }
5310
5311 if (!program->setUniformMatrix4fv(location, count, value))
5312 {
5313 return error(GL_INVALID_OPERATION);
5314 }
5315 }
5316 }
5317 catch(std::bad_alloc&)
5318 {
5319 return error(GL_OUT_OF_MEMORY);
5320 }
5321}
5322
5323void __stdcall glUseProgram(GLuint program)
5324{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005325 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005326
5327 try
5328 {
5329 gl::Context *context = gl::getContext();
5330
5331 if (context)
5332 {
5333 gl::Program *programObject = context->getProgram(program);
5334
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005335 if (!programObject && program != 0)
5336 {
5337 if (context->getShader(program))
5338 {
5339 return error(GL_INVALID_OPERATION);
5340 }
5341 else
5342 {
5343 return error(GL_INVALID_VALUE);
5344 }
5345 }
5346
5347 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005348 {
5349 return error(GL_INVALID_OPERATION);
5350 }
5351
5352 context->useProgram(program);
5353 }
5354 }
5355 catch(std::bad_alloc&)
5356 {
5357 return error(GL_OUT_OF_MEMORY);
5358 }
5359}
5360
5361void __stdcall glValidateProgram(GLuint program)
5362{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005363 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005364
5365 try
5366 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005367 gl::Context *context = gl::getContext();
5368
5369 if (context)
5370 {
5371 gl::Program *programObject = context->getProgram(program);
5372
5373 if (!programObject)
5374 {
5375 if (context->getShader(program))
5376 {
5377 return error(GL_INVALID_OPERATION);
5378 }
5379 else
5380 {
5381 return error(GL_INVALID_VALUE);
5382 }
5383 }
5384
5385 programObject->validate();
5386 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005387 }
5388 catch(std::bad_alloc&)
5389 {
5390 return error(GL_OUT_OF_MEMORY);
5391 }
5392}
5393
5394void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5395{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005396 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005397
5398 try
5399 {
5400 if (index >= gl::MAX_VERTEX_ATTRIBS)
5401 {
5402 return error(GL_INVALID_VALUE);
5403 }
5404
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005405 gl::Context *context = gl::getContext();
5406
5407 if (context)
5408 {
5409 GLfloat vals[4] = { x, 0, 0, 1 };
5410 context->setVertexAttrib(index, vals);
5411 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005412 }
5413 catch(std::bad_alloc&)
5414 {
5415 return error(GL_OUT_OF_MEMORY);
5416 }
5417}
5418
5419void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5420{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005421 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005422
5423 try
5424 {
5425 if (index >= gl::MAX_VERTEX_ATTRIBS)
5426 {
5427 return error(GL_INVALID_VALUE);
5428 }
5429
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005430 gl::Context *context = gl::getContext();
5431
5432 if (context)
5433 {
5434 GLfloat vals[4] = { values[0], 0, 0, 1 };
5435 context->setVertexAttrib(index, vals);
5436 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005437 }
5438 catch(std::bad_alloc&)
5439 {
5440 return error(GL_OUT_OF_MEMORY);
5441 }
5442}
5443
5444void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5445{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005446 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005447
5448 try
5449 {
5450 if (index >= gl::MAX_VERTEX_ATTRIBS)
5451 {
5452 return error(GL_INVALID_VALUE);
5453 }
5454
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005455 gl::Context *context = gl::getContext();
5456
5457 if (context)
5458 {
5459 GLfloat vals[4] = { x, y, 0, 1 };
5460 context->setVertexAttrib(index, vals);
5461 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005462 }
5463 catch(std::bad_alloc&)
5464 {
5465 return error(GL_OUT_OF_MEMORY);
5466 }
5467}
5468
5469void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5470{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005471 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005472
5473 try
5474 {
5475 if (index >= gl::MAX_VERTEX_ATTRIBS)
5476 {
5477 return error(GL_INVALID_VALUE);
5478 }
5479
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005480 gl::Context *context = gl::getContext();
5481
5482 if (context)
5483 {
5484 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5485 context->setVertexAttrib(index, vals);
5486 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005487 }
5488 catch(std::bad_alloc&)
5489 {
5490 return error(GL_OUT_OF_MEMORY);
5491 }
5492}
5493
5494void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5495{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005496 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 +00005497
5498 try
5499 {
5500 if (index >= gl::MAX_VERTEX_ATTRIBS)
5501 {
5502 return error(GL_INVALID_VALUE);
5503 }
5504
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005505 gl::Context *context = gl::getContext();
5506
5507 if (context)
5508 {
5509 GLfloat vals[4] = { x, y, z, 1 };
5510 context->setVertexAttrib(index, vals);
5511 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005512 }
5513 catch(std::bad_alloc&)
5514 {
5515 return error(GL_OUT_OF_MEMORY);
5516 }
5517}
5518
5519void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5520{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005521 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005522
5523 try
5524 {
5525 if (index >= gl::MAX_VERTEX_ATTRIBS)
5526 {
5527 return error(GL_INVALID_VALUE);
5528 }
5529
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005530 gl::Context *context = gl::getContext();
5531
5532 if (context)
5533 {
5534 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5535 context->setVertexAttrib(index, vals);
5536 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005537 }
5538 catch(std::bad_alloc&)
5539 {
5540 return error(GL_OUT_OF_MEMORY);
5541 }
5542}
5543
5544void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5545{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005546 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 +00005547
5548 try
5549 {
5550 if (index >= gl::MAX_VERTEX_ATTRIBS)
5551 {
5552 return error(GL_INVALID_VALUE);
5553 }
5554
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005555 gl::Context *context = gl::getContext();
5556
5557 if (context)
5558 {
5559 GLfloat vals[4] = { x, y, z, w };
5560 context->setVertexAttrib(index, vals);
5561 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005562 }
5563 catch(std::bad_alloc&)
5564 {
5565 return error(GL_OUT_OF_MEMORY);
5566 }
5567}
5568
5569void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5570{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005571 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005572
5573 try
5574 {
5575 if (index >= gl::MAX_VERTEX_ATTRIBS)
5576 {
5577 return error(GL_INVALID_VALUE);
5578 }
5579
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005580 gl::Context *context = gl::getContext();
5581
5582 if (context)
5583 {
5584 context->setVertexAttrib(index, values);
5585 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005586 }
5587 catch(std::bad_alloc&)
5588 {
5589 return error(GL_OUT_OF_MEMORY);
5590 }
5591}
5592
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005593void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005594{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005595 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005596 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005597 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005598
5599 try
5600 {
5601 if (index >= gl::MAX_VERTEX_ATTRIBS)
5602 {
5603 return error(GL_INVALID_VALUE);
5604 }
5605
5606 if (size < 1 || size > 4)
5607 {
5608 return error(GL_INVALID_VALUE);
5609 }
5610
5611 switch (type)
5612 {
5613 case GL_BYTE:
5614 case GL_UNSIGNED_BYTE:
5615 case GL_SHORT:
5616 case GL_UNSIGNED_SHORT:
5617 case GL_FIXED:
5618 case GL_FLOAT:
5619 break;
5620 default:
5621 return error(GL_INVALID_ENUM);
5622 }
5623
5624 if (stride < 0)
5625 {
5626 return error(GL_INVALID_VALUE);
5627 }
5628
5629 gl::Context *context = gl::getContext();
5630
5631 if (context)
5632 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005633 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005634 }
5635 }
5636 catch(std::bad_alloc&)
5637 {
5638 return error(GL_OUT_OF_MEMORY);
5639 }
5640}
5641
5642void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5643{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005644 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 +00005645
5646 try
5647 {
5648 if (width < 0 || height < 0)
5649 {
5650 return error(GL_INVALID_VALUE);
5651 }
5652
5653 gl::Context *context = gl::getContext();
5654
5655 if (context)
5656 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005657 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005658 }
5659 }
5660 catch(std::bad_alloc&)
5661 {
5662 return error(GL_OUT_OF_MEMORY);
5663 }
5664}
5665
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005666void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5667 GLbitfield mask, GLenum filter)
5668{
5669 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5670 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5671 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5672 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5673
5674 try
5675 {
5676 switch (filter)
5677 {
5678 case GL_NEAREST:
5679 break;
5680 default:
5681 return error(GL_INVALID_ENUM);
5682 }
5683
5684 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5685 {
5686 return error(GL_INVALID_VALUE);
5687 }
5688
5689 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5690 {
5691 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5692 return error(GL_INVALID_OPERATION);
5693 }
5694
5695 gl::Context *context = gl::getContext();
5696
5697 if (context)
5698 {
5699 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5700 {
5701 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5702 return error(GL_INVALID_OPERATION);
5703 }
5704
5705 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5706 }
5707 }
5708 catch(std::bad_alloc&)
5709 {
5710 return error(GL_OUT_OF_MEMORY);
5711 }
5712}
5713
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005714void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5715 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005716{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005717 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5718 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005719 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005720 target, level, internalformat, width, height, depth, border, format, type, pixels);
5721
5722 try
5723 {
5724 UNIMPLEMENTED(); // FIXME
5725 }
5726 catch(std::bad_alloc&)
5727 {
5728 return error(GL_OUT_OF_MEMORY);
5729 }
5730}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005731
5732__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5733{
5734 struct Extension
5735 {
5736 const char *name;
5737 __eglMustCastToProperFunctionPointerType address;
5738 };
5739
5740 static const Extension glExtensions[] =
5741 {
5742 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00005743 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005744 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
5745 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
5746 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
5747 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
5748 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
5749 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
5750 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005751 };
5752
5753 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5754 {
5755 if (strcmp(procname, glExtensions[ext].name) == 0)
5756 {
5757 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5758 }
5759 }
5760
5761 return NULL;
5762}
5763
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005764}