blob: 74e2c27954cee87319c4e38d5e04ae207e997ca1 [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.com41430492010-03-11 20:36:18 +0000740 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
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 (target)
751 {
752 case GL_TEXTURE_2D:
753 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
754 {
755 return error(GL_INVALID_VALUE);
756 }
757 break;
758 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
759 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
760 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
761 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
762 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
763 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
764 if (width != height)
765 {
766 return error(GL_INVALID_VALUE);
767 }
768
769 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
770 {
771 return error(GL_INVALID_VALUE);
772 }
773 break;
774 default:
775 return error(GL_INVALID_ENUM);
776 }
777
778 switch (internalformat)
779 {
780 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
781 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
782 break;
783 default:
784 return error(GL_INVALID_ENUM);
785 }
786
787 if (border != 0)
788 {
789 return error(GL_INVALID_VALUE);
790 }
791
792 gl::Context *context = gl::getContext();
793
794 if (context)
795 {
796 if (!context->supportsCompressedTextures())
797 {
798 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
799 }
800
801 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
802 {
803 return error(GL_INVALID_VALUE);
804 }
805
806 if (target == GL_TEXTURE_2D)
807 {
808 gl::Texture2D *texture = context->getTexture2D();
809
810 if (!texture)
811 {
812 return error(GL_INVALID_OPERATION);
813 }
814
815 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
816 }
817 else
818 {
819 gl::TextureCubeMap *texture = context->getTextureCubeMap();
820
821 if (!texture)
822 {
823 return error(GL_INVALID_OPERATION);
824 }
825
826 switch (target)
827 {
828 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
829 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
830 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
831 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
832 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
833 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
834 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
835 break;
836 default: UNREACHABLE();
837 }
838 }
839 }
840
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000841 }
842 catch(std::bad_alloc&)
843 {
844 return error(GL_OUT_OF_MEMORY);
845 }
846}
847
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000848void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
849 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000850{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000851 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
852 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000853 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000854 target, level, xoffset, yoffset, width, height, format, imageSize, data);
855
856 try
857 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000858 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000859 {
860 return error(GL_INVALID_ENUM);
861 }
862
863 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000864 {
865 return error(GL_INVALID_VALUE);
866 }
867
daniel@transgaming.com01868132010-08-24 19:21:17 +0000868 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 ||
869 (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000870 {
871 return error(GL_INVALID_VALUE);
872 }
873
daniel@transgaming.com01868132010-08-24 19:21:17 +0000874 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000875 {
daniel@transgaming.com01868132010-08-24 19:21:17 +0000876 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
877 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
878 break;
879 default:
880 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +0000881 }
882
daniel@transgaming.com01868132010-08-24 19:21:17 +0000883 if (width == 0 || height == 0 || data == NULL)
884 {
885 return;
886 }
887
888 gl::Context *context = gl::getContext();
889
890 if (context)
891 {
892 if (!context->supportsCompressedTextures())
893 {
894 return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
895 }
896
897 if (imageSize != gl::ComputeCompressedSize(width, height, format))
898 {
899 return error(GL_INVALID_VALUE);
900 }
901
902 if (xoffset % 4 != 0 || yoffset % 4 != 0)
903 {
904 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
905 // does not exist unless DXT1 textures are supported.
906 }
907
908 if (target == GL_TEXTURE_2D)
909 {
910 gl::Texture2D *texture = context->getTexture2D();
911
912 if (!texture)
913 {
914 return error(GL_INVALID_OPERATION);
915 }
916
917 if (!texture->isCompressed())
918 {
919 return error(GL_INVALID_OPERATION);
920 }
921
922 if ((width % 4 != 0 && width != texture->getWidth()) ||
923 (height % 4 != 0 && height != texture->getHeight()))
924 {
925 return error(GL_INVALID_OPERATION);
926 }
927
928 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
929 }
930 else if (gl::IsCubemapTextureTarget(target))
931 {
932 gl::TextureCubeMap *texture = context->getTextureCubeMap();
933
934 if (!texture)
935 {
936 return error(GL_INVALID_OPERATION);
937 }
938
939 if (!texture->isCompressed())
940 {
941 return error(GL_INVALID_OPERATION);
942 }
943
944 if ((width % 4 != 0 && width != texture->getWidth()) ||
945 (height % 4 != 0 && height != texture->getHeight()))
946 {
947 return error(GL_INVALID_OPERATION);
948 }
949
950 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
951 }
952 else
953 {
954 UNREACHABLE();
955 }
956 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000957 }
958 catch(std::bad_alloc&)
959 {
960 return error(GL_OUT_OF_MEMORY);
961 }
962}
963
964void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
965{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000966 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
967 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000968 target, level, internalformat, x, y, width, height, border);
969
970 try
971 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000972 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000973 {
974 return error(GL_INVALID_VALUE);
975 }
976
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000977 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
978 {
979 return error(GL_INVALID_VALUE);
980 }
981
982 switch (target)
983 {
984 case GL_TEXTURE_2D:
985 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
986 {
987 return error(GL_INVALID_VALUE);
988 }
989 break;
990 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
991 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
992 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
993 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
994 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
995 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +0000996 if (width != height)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000997 {
998 return error(GL_INVALID_VALUE);
999 }
1000
1001 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
1002 {
1003 return error(GL_INVALID_VALUE);
1004 }
1005 break;
1006 default:
1007 return error(GL_INVALID_ENUM);
1008 }
1009
1010 switch (internalformat)
1011 {
1012 case GL_ALPHA:
1013 case GL_LUMINANCE:
1014 case GL_LUMINANCE_ALPHA:
1015 case GL_RGB:
1016 case GL_RGBA:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001017 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // Compressed textures are not supported here, but if they are unsupported altogether,
1018 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: // a different error is generated than otherwise. That is handled below.
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001019 break;
1020 default:
1021 return error(GL_INVALID_VALUE);
1022 }
1023
1024 if (border != 0)
1025 {
1026 return error(GL_INVALID_VALUE);
1027 }
1028
1029 gl::Context *context = gl::getContext();
1030
1031 if (context)
1032 {
daniel@transgaming.com01868132010-08-24 19:21:17 +00001033 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
1034 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
1035 {
1036 if (context->supportsCompressedTextures())
1037 {
1038 return error(GL_INVALID_OPERATION);
1039 }
1040 else
1041 {
1042 return error(GL_INVALID_ENUM);
1043 }
1044 }
1045
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001046 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001047 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1048 {
1049 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1050 }
1051
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001052 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1053 {
1054 return error(GL_INVALID_OPERATION);
1055 }
1056
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001057 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001058 if (target == GL_TEXTURE_2D)
1059 {
1060 gl::Texture2D *texture = context->getTexture2D();
1061
1062 if (!texture)
1063 {
1064 return error(GL_INVALID_OPERATION);
1065 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001066
1067 if (texture->isCompressed())
1068 {
1069 return error(GL_INVALID_OPERATION);
1070 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001071
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001072 if (texture->isFloatingPoint())
1073 {
1074 return error(GL_INVALID_OPERATION);
1075 }
1076
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001077 texture->copyImage(level, internalformat, x, y, width, height, source);
1078 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001079 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001080 {
1081 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1082
1083 if (!texture)
1084 {
1085 return error(GL_INVALID_OPERATION);
1086 }
1087
daniel@transgaming.com01868132010-08-24 19:21:17 +00001088 if (texture->isCompressed())
1089 {
1090 return error(GL_INVALID_OPERATION);
1091 }
1092
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001093 if (texture->isFloatingPoint())
1094 {
1095 return error(GL_INVALID_OPERATION);
1096 }
1097
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001098 texture->copyImage(target, level, internalformat, x, y, width, height, source);
1099 }
1100 else
1101 {
1102 UNREACHABLE();
1103 }
1104 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001105 }
1106 catch(std::bad_alloc&)
1107 {
1108 return error(GL_OUT_OF_MEMORY);
1109 }
1110}
1111
1112void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1113{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001114 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1115 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001116 target, level, xoffset, yoffset, x, y, width, height);
1117
1118 try
1119 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001120 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001121 {
1122 return error(GL_INVALID_ENUM);
1123 }
1124
1125 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001126 {
1127 return error(GL_INVALID_VALUE);
1128 }
1129
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001130 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1131 {
1132 return error(GL_INVALID_VALUE);
1133 }
1134
1135 if (width == 0 || height == 0)
1136 {
1137 return;
1138 }
1139
1140 gl::Context *context = gl::getContext();
1141
1142 if (context)
1143 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001144 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001145 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1146 {
1147 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1148 }
1149
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001150 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1151 {
1152 return error(GL_INVALID_OPERATION);
1153 }
1154
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001155 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001156 if (target == GL_TEXTURE_2D)
1157 {
1158 gl::Texture2D *texture = context->getTexture2D();
1159
1160 if (!texture)
1161 {
1162 return error(GL_INVALID_OPERATION);
1163 }
1164
daniel@transgaming.com01868132010-08-24 19:21:17 +00001165 if (texture->isCompressed())
1166 {
1167 return error(GL_INVALID_OPERATION);
1168 }
1169
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001170 if (texture->isFloatingPoint())
1171 {
1172 return error(GL_INVALID_OPERATION);
1173 }
1174
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001175 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
1176 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001177 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001178 {
1179 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1180
1181 if (!texture)
1182 {
1183 return error(GL_INVALID_OPERATION);
1184 }
1185
daniel@transgaming.com01868132010-08-24 19:21:17 +00001186 if (texture->isCompressed())
1187 {
1188 return error(GL_INVALID_OPERATION);
1189 }
1190
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001191 if (texture->isFloatingPoint())
1192 {
1193 return error(GL_INVALID_OPERATION);
1194 }
1195
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001196 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
1197 }
1198 else
1199 {
1200 UNREACHABLE();
1201 }
1202 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001203 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001204
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001205 catch(std::bad_alloc&)
1206 {
1207 return error(GL_OUT_OF_MEMORY);
1208 }
1209}
1210
1211GLuint __stdcall glCreateProgram(void)
1212{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001213 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001214
1215 try
1216 {
1217 gl::Context *context = gl::getContext();
1218
1219 if (context)
1220 {
1221 return context->createProgram();
1222 }
1223 }
1224 catch(std::bad_alloc&)
1225 {
1226 return error(GL_OUT_OF_MEMORY, 0);
1227 }
1228
1229 return 0;
1230}
1231
1232GLuint __stdcall glCreateShader(GLenum type)
1233{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001234 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001235
1236 try
1237 {
1238 gl::Context *context = gl::getContext();
1239
1240 if (context)
1241 {
1242 switch (type)
1243 {
1244 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001245 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001246 return context->createShader(type);
1247 default:
1248 return error(GL_INVALID_ENUM, 0);
1249 }
1250 }
1251 }
1252 catch(std::bad_alloc&)
1253 {
1254 return error(GL_OUT_OF_MEMORY, 0);
1255 }
1256
1257 return 0;
1258}
1259
1260void __stdcall glCullFace(GLenum mode)
1261{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001262 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001263
1264 try
1265 {
1266 switch (mode)
1267 {
1268 case GL_FRONT:
1269 case GL_BACK:
1270 case GL_FRONT_AND_BACK:
1271 {
1272 gl::Context *context = gl::getContext();
1273
1274 if (context)
1275 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001276 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001277 }
1278 }
1279 break;
1280 default:
1281 return error(GL_INVALID_ENUM);
1282 }
1283 }
1284 catch(std::bad_alloc&)
1285 {
1286 return error(GL_OUT_OF_MEMORY);
1287 }
1288}
1289
1290void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1291{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001292 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001293
1294 try
1295 {
1296 if (n < 0)
1297 {
1298 return error(GL_INVALID_VALUE);
1299 }
1300
1301 gl::Context *context = gl::getContext();
1302
1303 if (context)
1304 {
1305 for (int i = 0; i < n; i++)
1306 {
1307 context->deleteBuffer(buffers[i]);
1308 }
1309 }
1310 }
1311 catch(std::bad_alloc&)
1312 {
1313 return error(GL_OUT_OF_MEMORY);
1314 }
1315}
1316
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001317void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1318{
1319 TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
1320
1321 try
1322 {
1323 if (n < 0)
1324 {
1325 return error(GL_INVALID_VALUE);
1326 }
1327
1328 gl::Context *context = gl::getContext();
1329
1330 if (context)
1331 {
1332 for (int i = 0; i < n; i++)
1333 {
1334 context->deleteFence(fences[i]);
1335 }
1336 }
1337 }
1338 catch(std::bad_alloc&)
1339 {
1340 return error(GL_OUT_OF_MEMORY);
1341 }
1342}
1343
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001344void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1345{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001346 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001347
1348 try
1349 {
1350 if (n < 0)
1351 {
1352 return error(GL_INVALID_VALUE);
1353 }
1354
1355 gl::Context *context = gl::getContext();
1356
1357 if (context)
1358 {
1359 for (int i = 0; i < n; i++)
1360 {
1361 if (framebuffers[i] != 0)
1362 {
1363 context->deleteFramebuffer(framebuffers[i]);
1364 }
1365 }
1366 }
1367 }
1368 catch(std::bad_alloc&)
1369 {
1370 return error(GL_OUT_OF_MEMORY);
1371 }
1372}
1373
1374void __stdcall glDeleteProgram(GLuint program)
1375{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001376 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001377
1378 try
1379 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001380 if (program == 0)
1381 {
1382 return;
1383 }
1384
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001385 gl::Context *context = gl::getContext();
1386
1387 if (context)
1388 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001389 if (!context->getProgram(program))
1390 {
1391 if(context->getShader(program))
1392 {
1393 return error(GL_INVALID_OPERATION);
1394 }
1395 else
1396 {
1397 return error(GL_INVALID_VALUE);
1398 }
1399 }
1400
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001401 context->deleteProgram(program);
1402 }
1403 }
1404 catch(std::bad_alloc&)
1405 {
1406 return error(GL_OUT_OF_MEMORY);
1407 }
1408}
1409
1410void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1411{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001412 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001413
1414 try
1415 {
1416 if (n < 0)
1417 {
1418 return error(GL_INVALID_VALUE);
1419 }
1420
1421 gl::Context *context = gl::getContext();
1422
1423 if (context)
1424 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001425 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001426 {
1427 context->deleteRenderbuffer(renderbuffers[i]);
1428 }
1429 }
1430 }
1431 catch(std::bad_alloc&)
1432 {
1433 return error(GL_OUT_OF_MEMORY);
1434 }
1435}
1436
1437void __stdcall glDeleteShader(GLuint shader)
1438{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001439 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001440
1441 try
1442 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001443 if (shader == 0)
1444 {
1445 return;
1446 }
1447
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001448 gl::Context *context = gl::getContext();
1449
1450 if (context)
1451 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001452 if (!context->getShader(shader))
1453 {
1454 if(context->getProgram(shader))
1455 {
1456 return error(GL_INVALID_OPERATION);
1457 }
1458 else
1459 {
1460 return error(GL_INVALID_VALUE);
1461 }
1462 }
1463
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001464 context->deleteShader(shader);
1465 }
1466 }
1467 catch(std::bad_alloc&)
1468 {
1469 return error(GL_OUT_OF_MEMORY);
1470 }
1471}
1472
1473void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1474{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001475 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001476
1477 try
1478 {
1479 if (n < 0)
1480 {
1481 return error(GL_INVALID_VALUE);
1482 }
1483
1484 gl::Context *context = gl::getContext();
1485
1486 if (context)
1487 {
1488 for (int i = 0; i < n; i++)
1489 {
1490 if (textures[i] != 0)
1491 {
1492 context->deleteTexture(textures[i]);
1493 }
1494 }
1495 }
1496 }
1497 catch(std::bad_alloc&)
1498 {
1499 return error(GL_OUT_OF_MEMORY);
1500 }
1501}
1502
1503void __stdcall glDepthFunc(GLenum func)
1504{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001505 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001506
1507 try
1508 {
1509 switch (func)
1510 {
1511 case GL_NEVER:
1512 case GL_ALWAYS:
1513 case GL_LESS:
1514 case GL_LEQUAL:
1515 case GL_EQUAL:
1516 case GL_GREATER:
1517 case GL_GEQUAL:
1518 case GL_NOTEQUAL:
1519 break;
1520 default:
1521 return error(GL_INVALID_ENUM);
1522 }
1523
1524 gl::Context *context = gl::getContext();
1525
1526 if (context)
1527 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001528 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001529 }
1530 }
1531 catch(std::bad_alloc&)
1532 {
1533 return error(GL_OUT_OF_MEMORY);
1534 }
1535}
1536
1537void __stdcall glDepthMask(GLboolean flag)
1538{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001539 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001540
1541 try
1542 {
1543 gl::Context *context = gl::getContext();
1544
1545 if (context)
1546 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001547 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001548 }
1549 }
1550 catch(std::bad_alloc&)
1551 {
1552 return error(GL_OUT_OF_MEMORY);
1553 }
1554}
1555
1556void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1557{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001558 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001559
1560 try
1561 {
1562 gl::Context *context = gl::getContext();
1563
1564 if (context)
1565 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001566 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001567 }
1568 }
1569 catch(std::bad_alloc&)
1570 {
1571 return error(GL_OUT_OF_MEMORY);
1572 }
1573}
1574
1575void __stdcall glDetachShader(GLuint program, GLuint shader)
1576{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001577 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001578
1579 try
1580 {
1581 gl::Context *context = gl::getContext();
1582
1583 if (context)
1584 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001585
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001586 gl::Program *programObject = context->getProgram(program);
1587 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001588
1589 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001590 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001591 gl::Shader *shaderByProgramHandle;
1592 shaderByProgramHandle = context->getShader(program);
1593 if (!shaderByProgramHandle)
1594 {
1595 return error(GL_INVALID_VALUE);
1596 }
1597 else
1598 {
1599 return error(GL_INVALID_OPERATION);
1600 }
1601 }
1602
1603 if (!shaderObject)
1604 {
1605 gl::Program *programByShaderHandle = context->getProgram(shader);
1606 if (!programByShaderHandle)
1607 {
1608 return error(GL_INVALID_VALUE);
1609 }
1610 else
1611 {
1612 return error(GL_INVALID_OPERATION);
1613 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001614 }
1615
1616 if (!programObject->detachShader(shaderObject))
1617 {
1618 return error(GL_INVALID_OPERATION);
1619 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001620 }
1621 }
1622 catch(std::bad_alloc&)
1623 {
1624 return error(GL_OUT_OF_MEMORY);
1625 }
1626}
1627
1628void __stdcall glDisable(GLenum cap)
1629{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001630 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001631
1632 try
1633 {
1634 gl::Context *context = gl::getContext();
1635
1636 if (context)
1637 {
1638 switch (cap)
1639 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001640 case GL_CULL_FACE: context->setCullFace(false); break;
1641 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1642 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1643 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1644 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1645 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1646 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1647 case GL_BLEND: context->setBlend(false); break;
1648 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001649 default:
1650 return error(GL_INVALID_ENUM);
1651 }
1652 }
1653 }
1654 catch(std::bad_alloc&)
1655 {
1656 return error(GL_OUT_OF_MEMORY);
1657 }
1658}
1659
1660void __stdcall glDisableVertexAttribArray(GLuint index)
1661{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001662 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001663
1664 try
1665 {
1666 if (index >= gl::MAX_VERTEX_ATTRIBS)
1667 {
1668 return error(GL_INVALID_VALUE);
1669 }
1670
1671 gl::Context *context = gl::getContext();
1672
1673 if (context)
1674 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001675 context->setVertexAttribEnabled(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001676 }
1677 }
1678 catch(std::bad_alloc&)
1679 {
1680 return error(GL_OUT_OF_MEMORY);
1681 }
1682}
1683
1684void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1685{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001686 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001687
1688 try
1689 {
1690 if (count < 0 || first < 0)
1691 {
1692 return error(GL_INVALID_VALUE);
1693 }
1694
1695 gl::Context *context = gl::getContext();
1696
1697 if (context)
1698 {
1699 context->drawArrays(mode, first, count);
1700 }
1701 }
1702 catch(std::bad_alloc&)
1703 {
1704 return error(GL_OUT_OF_MEMORY);
1705 }
1706}
1707
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001708void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001709{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001710 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 +00001711 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001712
1713 try
1714 {
1715 if (count < 0)
1716 {
1717 return error(GL_INVALID_VALUE);
1718 }
1719
1720 switch (type)
1721 {
1722 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001723 case GL_UNSIGNED_SHORT:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00001724 case GL_UNSIGNED_INT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001725 break;
1726 default:
1727 return error(GL_INVALID_ENUM);
1728 }
1729
1730 gl::Context *context = gl::getContext();
1731
1732 if (context)
1733 {
1734 context->drawElements(mode, count, type, indices);
1735 }
1736 }
1737 catch(std::bad_alloc&)
1738 {
1739 return error(GL_OUT_OF_MEMORY);
1740 }
1741}
1742
1743void __stdcall glEnable(GLenum cap)
1744{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001745 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001746
1747 try
1748 {
1749 gl::Context *context = gl::getContext();
1750
1751 if (context)
1752 {
1753 switch (cap)
1754 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001755 case GL_CULL_FACE: context->setCullFace(true); break;
1756 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1757 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1758 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1759 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1760 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1761 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1762 case GL_BLEND: context->setBlend(true); break;
1763 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001764 default:
1765 return error(GL_INVALID_ENUM);
1766 }
1767 }
1768 }
1769 catch(std::bad_alloc&)
1770 {
1771 return error(GL_OUT_OF_MEMORY);
1772 }
1773}
1774
1775void __stdcall glEnableVertexAttribArray(GLuint index)
1776{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001777 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001778
1779 try
1780 {
1781 if (index >= gl::MAX_VERTEX_ATTRIBS)
1782 {
1783 return error(GL_INVALID_VALUE);
1784 }
1785
1786 gl::Context *context = gl::getContext();
1787
1788 if (context)
1789 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001790 context->setVertexAttribEnabled(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001791 }
1792 }
1793 catch(std::bad_alloc&)
1794 {
1795 return error(GL_OUT_OF_MEMORY);
1796 }
1797}
1798
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001799void __stdcall glFinishFenceNV(GLuint fence)
1800{
1801 TRACE("(GLuint fence = %d)", fence);
1802
1803 try
1804 {
1805 gl::Context *context = gl::getContext();
1806
1807 if (context)
1808 {
1809 gl::Fence* fenceObject = context->getFence(fence);
1810
1811 if (fenceObject == NULL)
1812 {
1813 return error(GL_INVALID_OPERATION);
1814 }
1815
1816 fenceObject->finishFence();
1817 }
1818 }
1819 catch(std::bad_alloc&)
1820 {
1821 return error(GL_OUT_OF_MEMORY);
1822 }
1823}
1824
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001825void __stdcall glFinish(void)
1826{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001827 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001828
1829 try
1830 {
1831 gl::Context *context = gl::getContext();
1832
1833 if (context)
1834 {
1835 context->finish();
1836 }
1837 }
1838 catch(std::bad_alloc&)
1839 {
1840 return error(GL_OUT_OF_MEMORY);
1841 }
1842}
1843
1844void __stdcall glFlush(void)
1845{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001846 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001847
1848 try
1849 {
1850 gl::Context *context = gl::getContext();
1851
1852 if (context)
1853 {
1854 context->flush();
1855 }
1856 }
1857 catch(std::bad_alloc&)
1858 {
1859 return error(GL_OUT_OF_MEMORY);
1860 }
1861}
1862
1863void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1864{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001865 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1866 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001867
1868 try
1869 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001870 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1871 || renderbuffertarget != GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001872 {
1873 return error(GL_INVALID_ENUM);
1874 }
1875
1876 gl::Context *context = gl::getContext();
1877
1878 if (context)
1879 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001880 gl::Framebuffer *framebuffer = NULL;
1881 GLuint framebufferHandle = 0;
1882 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1883 {
1884 framebuffer = context->getReadFramebuffer();
1885 framebufferHandle = context->getReadFramebufferHandle();
1886 }
1887 else
1888 {
1889 framebuffer = context->getDrawFramebuffer();
1890 framebufferHandle = context->getDrawFramebufferHandle();
1891 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001892
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001893 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001894 {
1895 return error(GL_INVALID_OPERATION);
1896 }
1897
1898 switch (attachment)
1899 {
1900 case GL_COLOR_ATTACHMENT0:
1901 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1902 break;
1903 case GL_DEPTH_ATTACHMENT:
1904 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1905 break;
1906 case GL_STENCIL_ATTACHMENT:
1907 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1908 break;
1909 default:
1910 return error(GL_INVALID_ENUM);
1911 }
1912 }
1913 }
1914 catch(std::bad_alloc&)
1915 {
1916 return error(GL_OUT_OF_MEMORY);
1917 }
1918}
1919
1920void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1921{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001922 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1923 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001924
1925 try
1926 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001927 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001928 {
1929 return error(GL_INVALID_ENUM);
1930 }
1931
1932 switch (attachment)
1933 {
1934 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001935 case GL_DEPTH_ATTACHMENT:
1936 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001937 break;
1938 default:
1939 return error(GL_INVALID_ENUM);
1940 }
1941
1942 gl::Context *context = gl::getContext();
1943
1944 if (context)
1945 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001946 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001947 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001948 textarget = GL_NONE;
1949 }
1950 else
1951 {
1952 gl::Texture *tex = context->getTexture(texture);
1953
1954 if (tex == NULL)
1955 {
1956 return error(GL_INVALID_OPERATION);
1957 }
1958
daniel@transgaming.com01868132010-08-24 19:21:17 +00001959 if (tex->isCompressed())
1960 {
1961 return error(GL_INVALID_OPERATION);
1962 }
1963
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001964 switch (textarget)
1965 {
1966 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001967 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001968 {
1969 return error(GL_INVALID_OPERATION);
1970 }
1971 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001972
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001973 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001974 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001975 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001976 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001977 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001978 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001979 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1980 {
1981 return error(GL_INVALID_OPERATION);
1982 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001983 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001984
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001985 default:
1986 return error(GL_INVALID_ENUM);
1987 }
1988
1989 if (level != 0)
1990 {
1991 return error(GL_INVALID_VALUE);
1992 }
1993 }
1994
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001995 gl::Framebuffer *framebuffer = NULL;
1996 GLuint framebufferHandle = 0;
1997 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1998 {
1999 framebuffer = context->getReadFramebuffer();
2000 framebufferHandle = context->getReadFramebufferHandle();
2001 }
2002 else
2003 {
2004 framebuffer = context->getDrawFramebuffer();
2005 framebufferHandle = context->getDrawFramebufferHandle();
2006 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002007
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002008 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002009 {
2010 return error(GL_INVALID_OPERATION);
2011 }
2012
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002013 switch (attachment)
2014 {
2015 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2016 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2017 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2018 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002019 }
2020 }
2021 catch(std::bad_alloc&)
2022 {
2023 return error(GL_OUT_OF_MEMORY);
2024 }
2025}
2026
2027void __stdcall glFrontFace(GLenum mode)
2028{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002029 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002030
2031 try
2032 {
2033 switch (mode)
2034 {
2035 case GL_CW:
2036 case GL_CCW:
2037 {
2038 gl::Context *context = gl::getContext();
2039
2040 if (context)
2041 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002042 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002043 }
2044 }
2045 break;
2046 default:
2047 return error(GL_INVALID_ENUM);
2048 }
2049 }
2050 catch(std::bad_alloc&)
2051 {
2052 return error(GL_OUT_OF_MEMORY);
2053 }
2054}
2055
2056void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2057{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002058 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002059
2060 try
2061 {
2062 if (n < 0)
2063 {
2064 return error(GL_INVALID_VALUE);
2065 }
2066
2067 gl::Context *context = gl::getContext();
2068
2069 if (context)
2070 {
2071 for (int i = 0; i < n; i++)
2072 {
2073 buffers[i] = context->createBuffer();
2074 }
2075 }
2076 }
2077 catch(std::bad_alloc&)
2078 {
2079 return error(GL_OUT_OF_MEMORY);
2080 }
2081}
2082
2083void __stdcall glGenerateMipmap(GLenum target)
2084{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002085 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002086
2087 try
2088 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002089 gl::Context *context = gl::getContext();
2090
2091 if (context)
2092 {
2093 gl::Texture *texture;
2094
2095 switch (target)
2096 {
2097 case GL_TEXTURE_2D:
2098 texture = context->getTexture2D();
2099 break;
2100
2101 case GL_TEXTURE_CUBE_MAP:
2102 texture = context->getTextureCubeMap();
2103 break;
2104
2105 default:
2106 return error(GL_INVALID_ENUM);
2107 }
2108
daniel@transgaming.com01868132010-08-24 19:21:17 +00002109 if (texture->isCompressed())
2110 {
2111 return error(GL_INVALID_OPERATION);
2112 }
2113
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002114 texture->generateMipmaps();
2115 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002116 }
2117 catch(std::bad_alloc&)
2118 {
2119 return error(GL_OUT_OF_MEMORY);
2120 }
2121}
2122
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002123void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2124{
2125 TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
2126
2127 try
2128 {
2129 if (n < 0)
2130 {
2131 return error(GL_INVALID_VALUE);
2132 }
2133
2134 gl::Context *context = gl::getContext();
2135
2136 if (context)
2137 {
2138 for (int i = 0; i < n; i++)
2139 {
2140 fences[i] = context->createFence();
2141 }
2142 }
2143 }
2144 catch(std::bad_alloc&)
2145 {
2146 return error(GL_OUT_OF_MEMORY);
2147 }
2148}
2149
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002150void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2151{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002152 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002153
2154 try
2155 {
2156 if (n < 0)
2157 {
2158 return error(GL_INVALID_VALUE);
2159 }
2160
2161 gl::Context *context = gl::getContext();
2162
2163 if (context)
2164 {
2165 for (int i = 0; i < n; i++)
2166 {
2167 framebuffers[i] = context->createFramebuffer();
2168 }
2169 }
2170 }
2171 catch(std::bad_alloc&)
2172 {
2173 return error(GL_OUT_OF_MEMORY);
2174 }
2175}
2176
2177void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2178{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002179 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002180
2181 try
2182 {
2183 if (n < 0)
2184 {
2185 return error(GL_INVALID_VALUE);
2186 }
2187
2188 gl::Context *context = gl::getContext();
2189
2190 if (context)
2191 {
2192 for (int i = 0; i < n; i++)
2193 {
2194 renderbuffers[i] = context->createRenderbuffer();
2195 }
2196 }
2197 }
2198 catch(std::bad_alloc&)
2199 {
2200 return error(GL_OUT_OF_MEMORY);
2201 }
2202}
2203
2204void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2205{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002206 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002207
2208 try
2209 {
2210 if (n < 0)
2211 {
2212 return error(GL_INVALID_VALUE);
2213 }
2214
2215 gl::Context *context = gl::getContext();
2216
2217 if (context)
2218 {
2219 for (int i = 0; i < n; i++)
2220 {
2221 textures[i] = context->createTexture();
2222 }
2223 }
2224 }
2225 catch(std::bad_alloc&)
2226 {
2227 return error(GL_OUT_OF_MEMORY);
2228 }
2229}
2230
daniel@transgaming.com85423182010-04-22 13:35:27 +00002231void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002232{
daniel@transgaming.com85423182010-04-22 13:35:27 +00002233 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2234 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002235 program, index, bufsize, length, size, type, name);
2236
2237 try
2238 {
2239 if (bufsize < 0)
2240 {
2241 return error(GL_INVALID_VALUE);
2242 }
2243
daniel@transgaming.com85423182010-04-22 13:35:27 +00002244 gl::Context *context = gl::getContext();
2245
2246 if (context)
2247 {
2248 gl::Program *programObject = context->getProgram(program);
2249
2250 if (!programObject)
2251 {
2252 if (context->getShader(program))
2253 {
2254 return error(GL_INVALID_OPERATION);
2255 }
2256 else
2257 {
2258 return error(GL_INVALID_VALUE);
2259 }
2260 }
2261
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002262 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002263 {
2264 return error(GL_INVALID_VALUE);
2265 }
2266
2267 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2268 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002269 }
2270 catch(std::bad_alloc&)
2271 {
2272 return error(GL_OUT_OF_MEMORY);
2273 }
2274}
2275
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002276void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002277{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002278 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002279 "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 +00002280 program, index, bufsize, length, size, type, name);
2281
2282 try
2283 {
2284 if (bufsize < 0)
2285 {
2286 return error(GL_INVALID_VALUE);
2287 }
2288
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002289 gl::Context *context = gl::getContext();
2290
2291 if (context)
2292 {
2293 gl::Program *programObject = context->getProgram(program);
2294
2295 if (!programObject)
2296 {
2297 if (context->getShader(program))
2298 {
2299 return error(GL_INVALID_OPERATION);
2300 }
2301 else
2302 {
2303 return error(GL_INVALID_VALUE);
2304 }
2305 }
2306
2307 if (index >= (GLuint)programObject->getActiveUniformCount())
2308 {
2309 return error(GL_INVALID_VALUE);
2310 }
2311
2312 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2313 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002314 }
2315 catch(std::bad_alloc&)
2316 {
2317 return error(GL_OUT_OF_MEMORY);
2318 }
2319}
2320
2321void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2322{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002323 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2324 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002325
2326 try
2327 {
2328 if (maxcount < 0)
2329 {
2330 return error(GL_INVALID_VALUE);
2331 }
2332
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002333 gl::Context *context = gl::getContext();
2334
2335 if (context)
2336 {
2337 gl::Program *programObject = context->getProgram(program);
2338
2339 if (!programObject)
2340 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002341 if (context->getShader(program))
2342 {
2343 return error(GL_INVALID_OPERATION);
2344 }
2345 else
2346 {
2347 return error(GL_INVALID_VALUE);
2348 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002349 }
2350
2351 return programObject->getAttachedShaders(maxcount, count, shaders);
2352 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002353 }
2354 catch(std::bad_alloc&)
2355 {
2356 return error(GL_OUT_OF_MEMORY);
2357 }
2358}
2359
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002360int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002361{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002362 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002363
2364 try
2365 {
2366 gl::Context *context = gl::getContext();
2367
2368 if (context)
2369 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002370
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002371 gl::Program *programObject = context->getProgram(program);
2372
2373 if (!programObject)
2374 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002375 if (context->getShader(program))
2376 {
2377 return error(GL_INVALID_OPERATION, -1);
2378 }
2379 else
2380 {
2381 return error(GL_INVALID_VALUE, -1);
2382 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002383 }
2384
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002385 if (!programObject->isLinked())
2386 {
2387 return error(GL_INVALID_OPERATION, -1);
2388 }
2389
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002390 return programObject->getAttributeLocation(name);
2391 }
2392 }
2393 catch(std::bad_alloc&)
2394 {
2395 return error(GL_OUT_OF_MEMORY, -1);
2396 }
2397
2398 return -1;
2399}
2400
2401void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2402{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002403 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002404
2405 try
2406 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002407 gl::Context *context = gl::getContext();
2408
2409 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002410 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002411 if (!(context->getBooleanv(pname, params)))
2412 {
2413 GLenum nativeType;
2414 unsigned int numParams = 0;
2415 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2416 return error(GL_INVALID_ENUM);
2417
2418 if (numParams == 0)
2419 return; // it is known that the pname is valid, but there are no parameters to return
2420
2421 if (nativeType == GL_FLOAT)
2422 {
2423 GLfloat *floatParams = NULL;
2424 floatParams = new GLfloat[numParams];
2425
2426 context->getFloatv(pname, floatParams);
2427
2428 for (unsigned int i = 0; i < numParams; ++i)
2429 {
2430 if (floatParams[i] == 0.0f)
2431 params[i] = GL_FALSE;
2432 else
2433 params[i] = GL_TRUE;
2434 }
2435
2436 delete [] floatParams;
2437 }
2438 else if (nativeType == GL_INT)
2439 {
2440 GLint *intParams = NULL;
2441 intParams = new GLint[numParams];
2442
2443 context->getIntegerv(pname, intParams);
2444
2445 for (unsigned int i = 0; i < numParams; ++i)
2446 {
2447 if (intParams[i] == 0)
2448 params[i] = GL_FALSE;
2449 else
2450 params[i] = GL_TRUE;
2451 }
2452
2453 delete [] intParams;
2454 }
2455 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002456 }
2457 }
2458 catch(std::bad_alloc&)
2459 {
2460 return error(GL_OUT_OF_MEMORY);
2461 }
2462}
2463
2464void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2465{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002466 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 +00002467
2468 try
2469 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002470 gl::Context *context = gl::getContext();
2471
2472 if (context)
2473 {
2474 gl::Buffer *buffer;
2475
2476 switch (target)
2477 {
2478 case GL_ARRAY_BUFFER:
2479 buffer = context->getArrayBuffer();
2480 break;
2481 case GL_ELEMENT_ARRAY_BUFFER:
2482 buffer = context->getElementArrayBuffer();
2483 break;
2484 default: return error(GL_INVALID_ENUM);
2485 }
2486
2487 if (!buffer)
2488 {
2489 // A null buffer means that "0" is bound to the requested buffer target
2490 return error(GL_INVALID_OPERATION);
2491 }
2492
2493 switch (pname)
2494 {
2495 case GL_BUFFER_USAGE:
2496 *params = buffer->usage();
2497 break;
2498 case GL_BUFFER_SIZE:
2499 *params = buffer->size();
2500 break;
2501 default: return error(GL_INVALID_ENUM);
2502 }
2503 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002504 }
2505 catch(std::bad_alloc&)
2506 {
2507 return error(GL_OUT_OF_MEMORY);
2508 }
2509}
2510
2511GLenum __stdcall glGetError(void)
2512{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002513 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002514
2515 gl::Context *context = gl::getContext();
2516
2517 if (context)
2518 {
2519 return context->getError();
2520 }
2521
2522 return GL_NO_ERROR;
2523}
2524
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002525void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2526{
2527 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
2528
2529 try
2530 {
2531
2532 gl::Context *context = gl::getContext();
2533
2534 if (context)
2535 {
2536 gl::Fence *fenceObject = context->getFence(fence);
2537
2538 if (fenceObject == NULL)
2539 {
2540 return error(GL_INVALID_OPERATION);
2541 }
2542
2543 fenceObject->getFenceiv(pname, params);
2544 }
2545 }
2546 catch(std::bad_alloc&)
2547 {
2548 return error(GL_OUT_OF_MEMORY);
2549 }
2550}
2551
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002552void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2553{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002554 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002555
2556 try
2557 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002558 gl::Context *context = gl::getContext();
2559
2560 if (context)
2561 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002562 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002563 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002564 GLenum nativeType;
2565 unsigned int numParams = 0;
2566 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2567 return error(GL_INVALID_ENUM);
2568
2569 if (numParams == 0)
2570 return; // it is known that the pname is valid, but that there are no parameters to return.
2571
2572 if (nativeType == GL_BOOL)
2573 {
2574 GLboolean *boolParams = NULL;
2575 boolParams = new GLboolean[numParams];
2576
2577 context->getBooleanv(pname, boolParams);
2578
2579 for (unsigned int i = 0; i < numParams; ++i)
2580 {
2581 if (boolParams[i] == GL_FALSE)
2582 params[i] = 0.0f;
2583 else
2584 params[i] = 1.0f;
2585 }
2586
2587 delete [] boolParams;
2588 }
2589 else if (nativeType == GL_INT)
2590 {
2591 GLint *intParams = NULL;
2592 intParams = new GLint[numParams];
2593
2594 context->getIntegerv(pname, intParams);
2595
2596 for (unsigned int i = 0; i < numParams; ++i)
2597 {
2598 params[i] = (GLfloat)intParams[i];
2599 }
2600
2601 delete [] intParams;
2602 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002603 }
2604 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002605 }
2606 catch(std::bad_alloc&)
2607 {
2608 return error(GL_OUT_OF_MEMORY);
2609 }
2610}
2611
2612void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2613{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002614 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2615 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002616
2617 try
2618 {
2619 gl::Context *context = gl::getContext();
2620
2621 if (context)
2622 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002623 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002624 {
2625 return error(GL_INVALID_ENUM);
2626 }
2627
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002628 gl::Framebuffer *framebuffer = NULL;
2629 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2630 {
2631 if(context->getReadFramebufferHandle() == 0)
2632 {
2633 return error(GL_INVALID_OPERATION);
2634 }
2635
2636 framebuffer = context->getReadFramebuffer();
2637 }
2638 else
2639 {
2640 if (context->getDrawFramebufferHandle() == 0)
2641 {
2642 return error(GL_INVALID_OPERATION);
2643 }
2644
2645 framebuffer = context->getDrawFramebuffer();
2646 }
2647
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002648 GLenum attachmentType;
2649 GLuint attachmentHandle;
2650 switch (attachment)
2651 {
2652 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002653 attachmentType = framebuffer->getColorbufferType();
2654 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002655 break;
2656 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002657 attachmentType = framebuffer->getDepthbufferType();
2658 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002659 break;
2660 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002661 attachmentType = framebuffer->getStencilbufferType();
2662 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002663 break;
2664 default: return error(GL_INVALID_ENUM);
2665 }
2666
2667 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002668 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002669 {
2670 attachmentObjectType = attachmentType;
2671 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002672 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002673 {
2674 attachmentObjectType = GL_TEXTURE;
2675 }
2676 else UNREACHABLE();
2677
2678 switch (pname)
2679 {
2680 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2681 *params = attachmentObjectType;
2682 break;
2683 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2684 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2685 {
2686 *params = attachmentHandle;
2687 }
2688 else
2689 {
2690 return error(GL_INVALID_ENUM);
2691 }
2692 break;
2693 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2694 if (attachmentObjectType == GL_TEXTURE)
2695 {
2696 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2697 }
2698 else
2699 {
2700 return error(GL_INVALID_ENUM);
2701 }
2702 break;
2703 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2704 if (attachmentObjectType == GL_TEXTURE)
2705 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002706 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002707 {
2708 *params = attachmentType;
2709 }
2710 else
2711 {
2712 *params = 0;
2713 }
2714 }
2715 else
2716 {
2717 return error(GL_INVALID_ENUM);
2718 }
2719 break;
2720 default:
2721 return error(GL_INVALID_ENUM);
2722 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002723 }
2724 }
2725 catch(std::bad_alloc&)
2726 {
2727 return error(GL_OUT_OF_MEMORY);
2728 }
2729}
2730
2731void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2732{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002733 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002734
2735 try
2736 {
2737 gl::Context *context = gl::getContext();
2738
2739 if (context)
2740 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002741 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002742 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002743 GLenum nativeType;
2744 unsigned int numParams = 0;
2745 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2746 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002747
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002748 if (numParams == 0)
2749 return; // it is known that pname is valid, but there are no parameters to return
2750
2751 if (nativeType == GL_BOOL)
2752 {
2753 GLboolean *boolParams = NULL;
2754 boolParams = new GLboolean[numParams];
2755
2756 context->getBooleanv(pname, boolParams);
2757
2758 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002759 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002760 if (boolParams[i] == GL_FALSE)
2761 params[i] = 0;
2762 else
2763 params[i] = 1;
2764 }
2765
2766 delete [] boolParams;
2767 }
2768 else if (nativeType == GL_FLOAT)
2769 {
2770 GLfloat *floatParams = NULL;
2771 floatParams = new GLfloat[numParams];
2772
2773 context->getFloatv(pname, floatParams);
2774
2775 for (unsigned int i = 0; i < numParams; ++i)
2776 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002777 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 +00002778 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002779 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002780 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002781 else
2782 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 +00002783 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002784
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002785 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002786 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002787 }
2788 }
2789 }
2790 catch(std::bad_alloc&)
2791 {
2792 return error(GL_OUT_OF_MEMORY);
2793 }
2794}
2795
2796void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2797{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002798 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002799
2800 try
2801 {
2802 gl::Context *context = gl::getContext();
2803
2804 if (context)
2805 {
2806 gl::Program *programObject = context->getProgram(program);
2807
2808 if (!programObject)
2809 {
2810 return error(GL_INVALID_VALUE);
2811 }
2812
2813 switch (pname)
2814 {
2815 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002816 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002817 return;
2818 case GL_LINK_STATUS:
2819 *params = programObject->isLinked();
2820 return;
2821 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002822 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002823 return;
2824 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002825 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002826 return;
2827 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002828 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002829 return;
2830 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002831 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002832 return;
2833 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002834 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002835 return;
2836 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002837 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002838 return;
2839 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002840 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002841 return;
2842 default:
2843 return error(GL_INVALID_ENUM);
2844 }
2845 }
2846 }
2847 catch(std::bad_alloc&)
2848 {
2849 return error(GL_OUT_OF_MEMORY);
2850 }
2851}
2852
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002853void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002854{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002855 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 +00002856 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002857
2858 try
2859 {
2860 if (bufsize < 0)
2861 {
2862 return error(GL_INVALID_VALUE);
2863 }
2864
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002865 gl::Context *context = gl::getContext();
2866
2867 if (context)
2868 {
2869 gl::Program *programObject = context->getProgram(program);
2870
2871 if (!programObject)
2872 {
2873 return error(GL_INVALID_VALUE);
2874 }
2875
2876 programObject->getInfoLog(bufsize, length, infolog);
2877 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002878 }
2879 catch(std::bad_alloc&)
2880 {
2881 return error(GL_OUT_OF_MEMORY);
2882 }
2883}
2884
2885void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2886{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002887 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 +00002888
2889 try
2890 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002891 gl::Context *context = gl::getContext();
2892
2893 if (context)
2894 {
2895 if (target != GL_RENDERBUFFER)
2896 {
2897 return error(GL_INVALID_ENUM);
2898 }
2899
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002900 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002901 {
2902 return error(GL_INVALID_OPERATION);
2903 }
2904
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002905 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002906
2907 switch (pname)
2908 {
2909 case GL_RENDERBUFFER_WIDTH:
2910 *params = renderbuffer->getWidth();
2911 break;
2912 case GL_RENDERBUFFER_HEIGHT:
2913 *params = renderbuffer->getHeight();
2914 break;
2915 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2916 *params = renderbuffer->getFormat();
2917 break;
2918 case GL_RENDERBUFFER_RED_SIZE:
2919 if (renderbuffer->isColorbuffer())
2920 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002921 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002922 }
2923 else
2924 {
2925 *params = 0;
2926 }
2927 break;
2928 case GL_RENDERBUFFER_GREEN_SIZE:
2929 if (renderbuffer->isColorbuffer())
2930 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002931 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002932 }
2933 else
2934 {
2935 *params = 0;
2936 }
2937 break;
2938 case GL_RENDERBUFFER_BLUE_SIZE:
2939 if (renderbuffer->isColorbuffer())
2940 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002941 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002942 }
2943 else
2944 {
2945 *params = 0;
2946 }
2947 break;
2948 case GL_RENDERBUFFER_ALPHA_SIZE:
2949 if (renderbuffer->isColorbuffer())
2950 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002951 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002952 }
2953 else
2954 {
2955 *params = 0;
2956 }
2957 break;
2958 case GL_RENDERBUFFER_DEPTH_SIZE:
2959 if (renderbuffer->isDepthbuffer())
2960 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002961 *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002962 }
2963 else
2964 {
2965 *params = 0;
2966 }
2967 break;
2968 case GL_RENDERBUFFER_STENCIL_SIZE:
2969 if (renderbuffer->isStencilbuffer())
2970 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002971 *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002972 }
2973 else
2974 {
2975 *params = 0;
2976 }
2977 break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002978 case GL_RENDERBUFFER_SAMPLES_ANGLE:
2979 {
2980 if (context->getMaxSupportedSamples() != 0)
2981 {
2982 *params = renderbuffer->getStorage()->getSamples();
2983 }
2984 else
2985 {
2986 return error(GL_INVALID_ENUM);
2987 }
2988 }
2989 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002990 default:
2991 return error(GL_INVALID_ENUM);
2992 }
2993 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002994 }
2995 catch(std::bad_alloc&)
2996 {
2997 return error(GL_OUT_OF_MEMORY);
2998 }
2999}
3000
3001void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3002{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003003 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003004
3005 try
3006 {
3007 gl::Context *context = gl::getContext();
3008
3009 if (context)
3010 {
3011 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003012
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003013 if (!shaderObject)
3014 {
3015 return error(GL_INVALID_VALUE);
3016 }
3017
3018 switch (pname)
3019 {
3020 case GL_SHADER_TYPE:
3021 *params = shaderObject->getType();
3022 return;
3023 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003024 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003025 return;
3026 case GL_COMPILE_STATUS:
3027 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3028 return;
3029 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003030 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003031 return;
3032 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003033 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003034 return;
3035 default:
3036 return error(GL_INVALID_ENUM);
3037 }
3038 }
3039 }
3040 catch(std::bad_alloc&)
3041 {
3042 return error(GL_OUT_OF_MEMORY);
3043 }
3044}
3045
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003046void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003047{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003048 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 +00003049 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003050
3051 try
3052 {
3053 if (bufsize < 0)
3054 {
3055 return error(GL_INVALID_VALUE);
3056 }
3057
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003058 gl::Context *context = gl::getContext();
3059
3060 if (context)
3061 {
3062 gl::Shader *shaderObject = context->getShader(shader);
3063
3064 if (!shaderObject)
3065 {
3066 return error(GL_INVALID_VALUE);
3067 }
3068
3069 shaderObject->getInfoLog(bufsize, length, infolog);
3070 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003071 }
3072 catch(std::bad_alloc&)
3073 {
3074 return error(GL_OUT_OF_MEMORY);
3075 }
3076}
3077
3078void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3079{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003080 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
3081 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003082
3083 try
3084 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003085 switch (shadertype)
3086 {
3087 case GL_VERTEX_SHADER:
3088 case GL_FRAGMENT_SHADER:
3089 break;
3090 default:
3091 return error(GL_INVALID_ENUM);
3092 }
3093
3094 switch (precisiontype)
3095 {
3096 case GL_LOW_FLOAT:
3097 case GL_MEDIUM_FLOAT:
3098 case GL_HIGH_FLOAT:
3099 // Assume IEEE 754 precision
3100 range[0] = 127;
3101 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003102 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003103 break;
3104 case GL_LOW_INT:
3105 case GL_MEDIUM_INT:
3106 case GL_HIGH_INT:
3107 // Some (most) hardware only supports single-precision floating-point numbers,
3108 // which can accurately represent integers up to +/-16777216
3109 range[0] = 24;
3110 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003111 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003112 break;
3113 default:
3114 return error(GL_INVALID_ENUM);
3115 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003116 }
3117 catch(std::bad_alloc&)
3118 {
3119 return error(GL_OUT_OF_MEMORY);
3120 }
3121}
3122
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003123void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003124{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003125 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 +00003126 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003127
3128 try
3129 {
3130 if (bufsize < 0)
3131 {
3132 return error(GL_INVALID_VALUE);
3133 }
3134
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003135 gl::Context *context = gl::getContext();
3136
3137 if (context)
3138 {
3139 gl::Shader *shaderObject = context->getShader(shader);
3140
3141 if (!shaderObject)
3142 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003143 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003144 }
3145
3146 shaderObject->getSource(bufsize, length, source);
3147 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003148 }
3149 catch(std::bad_alloc&)
3150 {
3151 return error(GL_OUT_OF_MEMORY);
3152 }
3153}
3154
3155const GLubyte* __stdcall glGetString(GLenum name)
3156{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003157 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003158
3159 try
3160 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003161 gl::Context *context = gl::getContext();
3162
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003163 switch (name)
3164 {
3165 case GL_VENDOR:
3166 return (GLubyte*)"TransGaming Inc.";
3167 case GL_RENDERER:
3168 return (GLubyte*)"ANGLE";
3169 case GL_VERSION:
3170 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
3171 case GL_SHADING_LANGUAGE_VERSION:
3172 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
3173 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003174 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003175 default:
3176 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3177 }
3178 }
3179 catch(std::bad_alloc&)
3180 {
3181 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3182 }
3183
3184 return NULL;
3185}
3186
3187void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3188{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003189 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 +00003190
3191 try
3192 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003193 gl::Context *context = gl::getContext();
3194
3195 if (context)
3196 {
3197 gl::Texture *texture;
3198
3199 switch (target)
3200 {
3201 case GL_TEXTURE_2D:
3202 texture = context->getTexture2D();
3203 break;
3204 case GL_TEXTURE_CUBE_MAP:
3205 texture = context->getTextureCubeMap();
3206 break;
3207 default:
3208 return error(GL_INVALID_ENUM);
3209 }
3210
3211 switch (pname)
3212 {
3213 case GL_TEXTURE_MAG_FILTER:
3214 *params = (GLfloat)texture->getMagFilter();
3215 break;
3216 case GL_TEXTURE_MIN_FILTER:
3217 *params = (GLfloat)texture->getMinFilter();
3218 break;
3219 case GL_TEXTURE_WRAP_S:
3220 *params = (GLfloat)texture->getWrapS();
3221 break;
3222 case GL_TEXTURE_WRAP_T:
3223 *params = (GLfloat)texture->getWrapT();
3224 break;
3225 default:
3226 return error(GL_INVALID_ENUM);
3227 }
3228 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003229 }
3230 catch(std::bad_alloc&)
3231 {
3232 return error(GL_OUT_OF_MEMORY);
3233 }
3234}
3235
3236void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3237{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003238 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 +00003239
3240 try
3241 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003242 gl::Context *context = gl::getContext();
3243
3244 if (context)
3245 {
3246 gl::Texture *texture;
3247
3248 switch (target)
3249 {
3250 case GL_TEXTURE_2D:
3251 texture = context->getTexture2D();
3252 break;
3253 case GL_TEXTURE_CUBE_MAP:
3254 texture = context->getTextureCubeMap();
3255 break;
3256 default:
3257 return error(GL_INVALID_ENUM);
3258 }
3259
3260 switch (pname)
3261 {
3262 case GL_TEXTURE_MAG_FILTER:
3263 *params = texture->getMagFilter();
3264 break;
3265 case GL_TEXTURE_MIN_FILTER:
3266 *params = texture->getMinFilter();
3267 break;
3268 case GL_TEXTURE_WRAP_S:
3269 *params = texture->getWrapS();
3270 break;
3271 case GL_TEXTURE_WRAP_T:
3272 *params = texture->getWrapT();
3273 break;
3274 default:
3275 return error(GL_INVALID_ENUM);
3276 }
3277 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003278 }
3279 catch(std::bad_alloc&)
3280 {
3281 return error(GL_OUT_OF_MEMORY);
3282 }
3283}
3284
3285void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3286{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003287 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003288
3289 try
3290 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003291 gl::Context *context = gl::getContext();
3292
3293 if (context)
3294 {
3295 if (program == 0)
3296 {
3297 return error(GL_INVALID_VALUE);
3298 }
3299
3300 gl::Program *programObject = context->getProgram(program);
3301
3302 if (!programObject || !programObject->isLinked())
3303 {
3304 return error(GL_INVALID_OPERATION);
3305 }
3306
3307 if (!programObject->getUniformfv(location, params))
3308 {
3309 return error(GL_INVALID_OPERATION);
3310 }
3311 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003312 }
3313 catch(std::bad_alloc&)
3314 {
3315 return error(GL_OUT_OF_MEMORY);
3316 }
3317}
3318
3319void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3320{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003321 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003322
3323 try
3324 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003325 gl::Context *context = gl::getContext();
3326
3327 if (context)
3328 {
3329 if (program == 0)
3330 {
3331 return error(GL_INVALID_VALUE);
3332 }
3333
3334 gl::Program *programObject = context->getProgram(program);
3335
3336 if (!programObject || !programObject->isLinked())
3337 {
3338 return error(GL_INVALID_OPERATION);
3339 }
3340
3341 if (!programObject)
3342 {
3343 return error(GL_INVALID_OPERATION);
3344 }
3345
3346 if (!programObject->getUniformiv(location, params))
3347 {
3348 return error(GL_INVALID_OPERATION);
3349 }
3350 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003351 }
3352 catch(std::bad_alloc&)
3353 {
3354 return error(GL_OUT_OF_MEMORY);
3355 }
3356}
3357
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003358int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003359{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003360 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003361
3362 try
3363 {
3364 gl::Context *context = gl::getContext();
3365
3366 if (strstr(name, "gl_") == name)
3367 {
3368 return -1;
3369 }
3370
3371 if (context)
3372 {
3373 gl::Program *programObject = context->getProgram(program);
3374
3375 if (!programObject)
3376 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003377 if (context->getShader(program))
3378 {
3379 return error(GL_INVALID_OPERATION, -1);
3380 }
3381 else
3382 {
3383 return error(GL_INVALID_VALUE, -1);
3384 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003385 }
3386
3387 if (!programObject->isLinked())
3388 {
3389 return error(GL_INVALID_OPERATION, -1);
3390 }
3391
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003392 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003393 }
3394 }
3395 catch(std::bad_alloc&)
3396 {
3397 return error(GL_OUT_OF_MEMORY, -1);
3398 }
3399
3400 return -1;
3401}
3402
3403void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3404{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003405 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003406
3407 try
3408 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003409 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003410
daniel@transgaming.come0078962010-04-15 20:45:08 +00003411 if (context)
3412 {
3413 if (index >= gl::MAX_VERTEX_ATTRIBS)
3414 {
3415 return error(GL_INVALID_VALUE);
3416 }
3417
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003418 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003419
daniel@transgaming.come0078962010-04-15 20:45:08 +00003420 switch (pname)
3421 {
3422 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003423 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003424 break;
3425 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003426 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003427 break;
3428 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003429 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003430 break;
3431 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003432 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003433 break;
3434 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003435 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003436 break;
3437 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003438 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003439 break;
3440 case GL_CURRENT_VERTEX_ATTRIB:
3441 for (int i = 0; i < 4; ++i)
3442 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003443 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003444 }
3445 break;
3446 default: return error(GL_INVALID_ENUM);
3447 }
3448 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003449 }
3450 catch(std::bad_alloc&)
3451 {
3452 return error(GL_OUT_OF_MEMORY);
3453 }
3454}
3455
3456void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3457{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003458 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003459
3460 try
3461 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003462 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003463
daniel@transgaming.come0078962010-04-15 20:45:08 +00003464 if (context)
3465 {
3466 if (index >= gl::MAX_VERTEX_ATTRIBS)
3467 {
3468 return error(GL_INVALID_VALUE);
3469 }
3470
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003471 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003472
daniel@transgaming.come0078962010-04-15 20:45:08 +00003473 switch (pname)
3474 {
3475 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003476 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003477 break;
3478 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003479 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003480 break;
3481 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003482 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003483 break;
3484 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003485 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003486 break;
3487 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003488 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003489 break;
3490 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003491 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003492 break;
3493 case GL_CURRENT_VERTEX_ATTRIB:
3494 for (int i = 0; i < 4; ++i)
3495 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003496 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003497 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3498 }
3499 break;
3500 default: return error(GL_INVALID_ENUM);
3501 }
3502 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003503 }
3504 catch(std::bad_alloc&)
3505 {
3506 return error(GL_OUT_OF_MEMORY);
3507 }
3508}
3509
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003510void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003511{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003512 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003513
3514 try
3515 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003516 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003517
daniel@transgaming.come0078962010-04-15 20:45:08 +00003518 if (context)
3519 {
3520 if (index >= gl::MAX_VERTEX_ATTRIBS)
3521 {
3522 return error(GL_INVALID_VALUE);
3523 }
3524
3525 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3526 {
3527 return error(GL_INVALID_ENUM);
3528 }
3529
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003530 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003531 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003532 }
3533 catch(std::bad_alloc&)
3534 {
3535 return error(GL_OUT_OF_MEMORY);
3536 }
3537}
3538
3539void __stdcall glHint(GLenum target, GLenum mode)
3540{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003541 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003542
3543 try
3544 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003545 switch (target)
3546 {
3547 case GL_GENERATE_MIPMAP_HINT:
3548 switch (mode)
3549 {
3550 case GL_FASTEST:
3551 case GL_NICEST:
3552 case GL_DONT_CARE:
3553 break;
3554 default:
3555 return error(GL_INVALID_ENUM);
3556 }
3557 break;
3558 default:
3559 return error(GL_INVALID_ENUM);
3560 }
3561
3562 gl::Context *context = gl::getContext();
3563 if (context)
3564 {
3565 if (target == GL_GENERATE_MIPMAP_HINT)
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003566 context->setGenerateMipmapHint(mode);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003567 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003568 }
3569 catch(std::bad_alloc&)
3570 {
3571 return error(GL_OUT_OF_MEMORY);
3572 }
3573}
3574
3575GLboolean __stdcall glIsBuffer(GLuint buffer)
3576{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003577 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003578
3579 try
3580 {
3581 gl::Context *context = gl::getContext();
3582
3583 if (context && buffer)
3584 {
3585 gl::Buffer *bufferObject = context->getBuffer(buffer);
3586
3587 if (bufferObject)
3588 {
3589 return GL_TRUE;
3590 }
3591 }
3592 }
3593 catch(std::bad_alloc&)
3594 {
3595 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3596 }
3597
3598 return GL_FALSE;
3599}
3600
3601GLboolean __stdcall glIsEnabled(GLenum cap)
3602{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003603 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003604
3605 try
3606 {
3607 gl::Context *context = gl::getContext();
3608
3609 if (context)
3610 {
3611 switch (cap)
3612 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003613 case GL_CULL_FACE: return context->isCullFaceEnabled();
3614 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3615 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3616 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3617 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3618 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3619 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3620 case GL_BLEND: return context->isBlendEnabled();
3621 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003622 default:
3623 return error(GL_INVALID_ENUM, false);
3624 }
3625 }
3626 }
3627 catch(std::bad_alloc&)
3628 {
3629 return error(GL_OUT_OF_MEMORY, false);
3630 }
3631
3632 return false;
3633}
3634
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003635GLboolean __stdcall glIsFenceNV(GLuint fence)
3636{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003637 TRACE("(GLuint fence = %d)", fence);
3638
3639 try
3640 {
3641 gl::Context *context = gl::getContext();
3642
3643 if (context)
3644 {
3645 gl::Fence *fenceObject = context->getFence(fence);
3646
3647 if (fenceObject == NULL)
3648 {
3649 return GL_FALSE;
3650 }
3651
3652 return fenceObject->isFence();
3653 }
3654 }
3655 catch(std::bad_alloc&)
3656 {
3657 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3658 }
3659
3660 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003661}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003662
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003663GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3664{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003665 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003666
3667 try
3668 {
3669 gl::Context *context = gl::getContext();
3670
3671 if (context && framebuffer)
3672 {
3673 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3674
3675 if (framebufferObject)
3676 {
3677 return GL_TRUE;
3678 }
3679 }
3680 }
3681 catch(std::bad_alloc&)
3682 {
3683 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3684 }
3685
3686 return GL_FALSE;
3687}
3688
3689GLboolean __stdcall glIsProgram(GLuint program)
3690{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003691 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003692
3693 try
3694 {
3695 gl::Context *context = gl::getContext();
3696
3697 if (context && program)
3698 {
3699 gl::Program *programObject = context->getProgram(program);
3700
3701 if (programObject)
3702 {
3703 return GL_TRUE;
3704 }
3705 }
3706 }
3707 catch(std::bad_alloc&)
3708 {
3709 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3710 }
3711
3712 return GL_FALSE;
3713}
3714
3715GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3716{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003717 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003718
3719 try
3720 {
3721 gl::Context *context = gl::getContext();
3722
3723 if (context && renderbuffer)
3724 {
3725 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3726
3727 if (renderbufferObject)
3728 {
3729 return GL_TRUE;
3730 }
3731 }
3732 }
3733 catch(std::bad_alloc&)
3734 {
3735 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3736 }
3737
3738 return GL_FALSE;
3739}
3740
3741GLboolean __stdcall glIsShader(GLuint shader)
3742{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003743 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003744
3745 try
3746 {
3747 gl::Context *context = gl::getContext();
3748
3749 if (context && shader)
3750 {
3751 gl::Shader *shaderObject = context->getShader(shader);
3752
3753 if (shaderObject)
3754 {
3755 return GL_TRUE;
3756 }
3757 }
3758 }
3759 catch(std::bad_alloc&)
3760 {
3761 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3762 }
3763
3764 return GL_FALSE;
3765}
3766
3767GLboolean __stdcall glIsTexture(GLuint texture)
3768{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003769 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003770
3771 try
3772 {
3773 gl::Context *context = gl::getContext();
3774
3775 if (context && texture)
3776 {
3777 gl::Texture *textureObject = context->getTexture(texture);
3778
3779 if (textureObject)
3780 {
3781 return GL_TRUE;
3782 }
3783 }
3784 }
3785 catch(std::bad_alloc&)
3786 {
3787 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3788 }
3789
3790 return GL_FALSE;
3791}
3792
3793void __stdcall glLineWidth(GLfloat width)
3794{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003795 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003796
3797 try
3798 {
3799 if (width <= 0.0f)
3800 {
3801 return error(GL_INVALID_VALUE);
3802 }
3803
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003804 gl::Context *context = gl::getContext();
3805
3806 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003807 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003808 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003809 }
3810 }
3811 catch(std::bad_alloc&)
3812 {
3813 return error(GL_OUT_OF_MEMORY);
3814 }
3815}
3816
3817void __stdcall glLinkProgram(GLuint program)
3818{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003819 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003820
3821 try
3822 {
3823 gl::Context *context = gl::getContext();
3824
3825 if (context)
3826 {
3827 gl::Program *programObject = context->getProgram(program);
3828
3829 if (!programObject)
3830 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003831 if (context->getShader(program))
3832 {
3833 return error(GL_INVALID_OPERATION);
3834 }
3835 else
3836 {
3837 return error(GL_INVALID_VALUE);
3838 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003839 }
3840
3841 programObject->link();
3842 }
3843 }
3844 catch(std::bad_alloc&)
3845 {
3846 return error(GL_OUT_OF_MEMORY);
3847 }
3848}
3849
3850void __stdcall glPixelStorei(GLenum pname, GLint param)
3851{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003852 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003853
3854 try
3855 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003856 gl::Context *context = gl::getContext();
3857
3858 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003859 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003860 switch (pname)
3861 {
3862 case GL_UNPACK_ALIGNMENT:
3863 if (param != 1 && param != 2 && param != 4 && param != 8)
3864 {
3865 return error(GL_INVALID_VALUE);
3866 }
3867
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003868 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003869 break;
3870
3871 case GL_PACK_ALIGNMENT:
3872 if (param != 1 && param != 2 && param != 4 && param != 8)
3873 {
3874 return error(GL_INVALID_VALUE);
3875 }
3876
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003877 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003878 break;
3879
3880 default:
3881 return error(GL_INVALID_ENUM);
3882 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003883 }
3884 }
3885 catch(std::bad_alloc&)
3886 {
3887 return error(GL_OUT_OF_MEMORY);
3888 }
3889}
3890
3891void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3892{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003893 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003894
3895 try
3896 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003897 gl::Context *context = gl::getContext();
3898
3899 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003900 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003901 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003902 }
3903 }
3904 catch(std::bad_alloc&)
3905 {
3906 return error(GL_OUT_OF_MEMORY);
3907 }
3908}
3909
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003910void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003911{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003912 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003913 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003914 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003915
3916 try
3917 {
3918 if (width < 0 || height < 0)
3919 {
3920 return error(GL_INVALID_VALUE);
3921 }
3922
3923 switch (format)
3924 {
3925 case GL_RGBA:
3926 switch (type)
3927 {
3928 case GL_UNSIGNED_BYTE:
3929 break;
3930 default:
3931 return error(GL_INVALID_OPERATION);
3932 }
3933 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003934 case GL_BGRA_EXT:
3935 switch (type)
3936 {
3937 case GL_UNSIGNED_BYTE:
3938 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3939 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3940 break;
3941 default:
3942 return error(GL_INVALID_OPERATION);
3943 }
3944 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003945 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3946 switch (type)
3947 {
3948 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3949 break;
3950 default:
3951 return error(GL_INVALID_OPERATION);
3952 }
3953 break;
3954 default:
3955 return error(GL_INVALID_OPERATION);
3956 }
3957
3958 gl::Context *context = gl::getContext();
3959
3960 if (context)
3961 {
3962 context->readPixels(x, y, width, height, format, type, pixels);
3963 }
3964 }
3965 catch(std::bad_alloc&)
3966 {
3967 return error(GL_OUT_OF_MEMORY);
3968 }
3969}
3970
3971void __stdcall glReleaseShaderCompiler(void)
3972{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003973 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003974
3975 try
3976 {
3977 gl::Shader::releaseCompiler();
3978 }
3979 catch(std::bad_alloc&)
3980 {
3981 return error(GL_OUT_OF_MEMORY);
3982 }
3983}
3984
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003985void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003986{
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003987 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3988 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003989
3990 try
3991 {
3992 switch (target)
3993 {
3994 case GL_RENDERBUFFER:
3995 break;
3996 default:
3997 return error(GL_INVALID_ENUM);
3998 }
3999
4000 switch (internalformat)
4001 {
4002 case GL_DEPTH_COMPONENT16:
4003 case GL_RGBA4:
4004 case GL_RGB5_A1:
4005 case GL_RGB565:
4006 case GL_STENCIL_INDEX8:
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004007 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004008 case GL_RGB8_OES:
4009 case GL_RGBA8_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004010 break;
4011 default:
4012 return error(GL_INVALID_ENUM);
4013 }
4014
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004015 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004016 {
4017 return error(GL_INVALID_VALUE);
4018 }
4019
4020 gl::Context *context = gl::getContext();
4021
4022 if (context)
4023 {
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004024 if (samples > context->getMaxSupportedSamples())
4025 {
4026 return error(GL_INVALID_VALUE);
4027 }
4028
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004029 GLuint handle = context->getRenderbufferHandle();
4030 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004031 {
4032 return error(GL_INVALID_OPERATION);
4033 }
4034
4035 switch (internalformat)
4036 {
4037 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004038 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004039 break;
4040 case GL_RGBA4:
4041 case GL_RGB5_A1:
4042 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004043 case GL_RGB8_OES:
4044 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004045 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004046 break;
4047 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004048 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004049 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004050 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004051 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004052 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004053 default:
4054 return error(GL_INVALID_ENUM);
4055 }
4056 }
4057 }
4058 catch(std::bad_alloc&)
4059 {
4060 return error(GL_OUT_OF_MEMORY);
4061 }
4062}
4063
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004064void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4065{
4066 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4067}
4068
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004069void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4070{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004071 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004072
4073 try
4074 {
4075 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004076
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004077 if (context)
4078 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004079 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004080 }
4081 }
4082 catch(std::bad_alloc&)
4083 {
4084 return error(GL_OUT_OF_MEMORY);
4085 }
4086}
4087
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004088void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4089{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004090 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
4091
4092 try
4093 {
4094 if (condition != GL_ALL_COMPLETED_NV)
4095 {
4096 return error(GL_INVALID_ENUM);
4097 }
4098
4099 gl::Context *context = gl::getContext();
4100
4101 if (context)
4102 {
4103 gl::Fence *fenceObject = context->getFence(fence);
4104
4105 if (fenceObject == NULL)
4106 {
4107 return error(GL_INVALID_OPERATION);
4108 }
4109
4110 fenceObject->setFence(condition);
4111 }
4112 }
4113 catch(std::bad_alloc&)
4114 {
4115 return error(GL_OUT_OF_MEMORY);
4116 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004117}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004118
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004119void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4120{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004121 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 +00004122
4123 try
4124 {
4125 if (width < 0 || height < 0)
4126 {
4127 return error(GL_INVALID_VALUE);
4128 }
4129
4130 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004131
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004132 if (context)
4133 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004134 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004135 }
4136 }
4137 catch(std::bad_alloc&)
4138 {
4139 return error(GL_OUT_OF_MEMORY);
4140 }
4141}
4142
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004143void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004144{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004145 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004146 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004147 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004148
4149 try
4150 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004151 // No binary shader formats are supported.
4152 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004153 }
4154 catch(std::bad_alloc&)
4155 {
4156 return error(GL_OUT_OF_MEMORY);
4157 }
4158}
4159
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004160void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004161{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004162 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 +00004163 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004164
4165 try
4166 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004167 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004168 {
4169 return error(GL_INVALID_VALUE);
4170 }
4171
4172 gl::Context *context = gl::getContext();
4173
4174 if (context)
4175 {
4176 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004177
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004178 if (!shaderObject)
4179 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004180 if (context->getProgram(shader))
4181 {
4182 return error(GL_INVALID_OPERATION);
4183 }
4184 else
4185 {
4186 return error(GL_INVALID_VALUE);
4187 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004188 }
4189
4190 shaderObject->setSource(count, string, length);
4191 }
4192 }
4193 catch(std::bad_alloc&)
4194 {
4195 return error(GL_OUT_OF_MEMORY);
4196 }
4197}
4198
4199void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4200{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004201 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004202}
4203
4204void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4205{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004206 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 +00004207
4208 try
4209 {
4210 switch (face)
4211 {
4212 case GL_FRONT:
4213 case GL_BACK:
4214 case GL_FRONT_AND_BACK:
4215 break;
4216 default:
4217 return error(GL_INVALID_ENUM);
4218 }
4219
4220 switch (func)
4221 {
4222 case GL_NEVER:
4223 case GL_ALWAYS:
4224 case GL_LESS:
4225 case GL_LEQUAL:
4226 case GL_EQUAL:
4227 case GL_GEQUAL:
4228 case GL_GREATER:
4229 case GL_NOTEQUAL:
4230 break;
4231 default:
4232 return error(GL_INVALID_ENUM);
4233 }
4234
4235 gl::Context *context = gl::getContext();
4236
4237 if (context)
4238 {
4239 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4240 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004241 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004242 }
4243
4244 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4245 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004246 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004247 }
4248 }
4249 }
4250 catch(std::bad_alloc&)
4251 {
4252 return error(GL_OUT_OF_MEMORY);
4253 }
4254}
4255
4256void __stdcall glStencilMask(GLuint mask)
4257{
4258 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4259}
4260
4261void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4262{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004263 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004264
4265 try
4266 {
4267 switch (face)
4268 {
4269 case GL_FRONT:
4270 case GL_BACK:
4271 case GL_FRONT_AND_BACK:
4272 break;
4273 default:
4274 return error(GL_INVALID_ENUM);
4275 }
4276
4277 gl::Context *context = gl::getContext();
4278
4279 if (context)
4280 {
4281 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4282 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004283 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004284 }
4285
4286 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4287 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004288 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004289 }
4290 }
4291 }
4292 catch(std::bad_alloc&)
4293 {
4294 return error(GL_OUT_OF_MEMORY);
4295 }
4296}
4297
4298void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4299{
4300 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4301}
4302
4303void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4304{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004305 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4306 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004307
4308 try
4309 {
4310 switch (face)
4311 {
4312 case GL_FRONT:
4313 case GL_BACK:
4314 case GL_FRONT_AND_BACK:
4315 break;
4316 default:
4317 return error(GL_INVALID_ENUM);
4318 }
4319
4320 switch (fail)
4321 {
4322 case GL_ZERO:
4323 case GL_KEEP:
4324 case GL_REPLACE:
4325 case GL_INCR:
4326 case GL_DECR:
4327 case GL_INVERT:
4328 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004329 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004330 break;
4331 default:
4332 return error(GL_INVALID_ENUM);
4333 }
4334
4335 switch (zfail)
4336 {
4337 case GL_ZERO:
4338 case GL_KEEP:
4339 case GL_REPLACE:
4340 case GL_INCR:
4341 case GL_DECR:
4342 case GL_INVERT:
4343 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004344 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004345 break;
4346 default:
4347 return error(GL_INVALID_ENUM);
4348 }
4349
4350 switch (zpass)
4351 {
4352 case GL_ZERO:
4353 case GL_KEEP:
4354 case GL_REPLACE:
4355 case GL_INCR:
4356 case GL_DECR:
4357 case GL_INVERT:
4358 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004359 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004360 break;
4361 default:
4362 return error(GL_INVALID_ENUM);
4363 }
4364
4365 gl::Context *context = gl::getContext();
4366
4367 if (context)
4368 {
4369 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4370 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004371 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004372 }
4373
4374 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4375 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004376 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004377 }
4378 }
4379 }
4380 catch(std::bad_alloc&)
4381 {
4382 return error(GL_OUT_OF_MEMORY);
4383 }
4384}
4385
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004386GLboolean __stdcall glTestFenceNV(GLuint fence)
4387{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004388 TRACE("(GLuint fence = %d)", fence);
4389
4390 try
4391 {
4392 gl::Context *context = gl::getContext();
4393
4394 if (context)
4395 {
4396 gl::Fence *fenceObject = context->getFence(fence);
4397
4398 if (fenceObject == NULL)
4399 {
4400 return error(GL_INVALID_OPERATION, GL_TRUE);
4401 }
4402
4403 return fenceObject->testFence();
4404 }
4405 }
4406 catch(std::bad_alloc&)
4407 {
4408 error(GL_OUT_OF_MEMORY);
4409 }
4410
4411 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004412}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004413
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004414void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4415 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004416{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004417 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 +00004418 "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 +00004419 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004420
4421 try
4422 {
4423 if (level < 0 || width < 0 || height < 0)
4424 {
4425 return error(GL_INVALID_VALUE);
4426 }
4427
4428 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
4429 {
4430 return error(GL_INVALID_VALUE);
4431 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004432
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004433 switch (target)
4434 {
4435 case GL_TEXTURE_2D:
4436 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
4437 {
4438 return error(GL_INVALID_VALUE);
4439 }
4440 break;
4441 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4442 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4443 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4444 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4445 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4446 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00004447 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004448 {
4449 return error(GL_INVALID_VALUE);
4450 }
4451
4452 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
4453 {
4454 return error(GL_INVALID_VALUE);
4455 }
4456 break;
4457 default:
4458 return error(GL_INVALID_ENUM);
4459 }
4460
4461 if (internalformat != format)
4462 {
4463 return error(GL_INVALID_OPERATION);
4464 }
4465
4466 switch (internalformat)
4467 {
4468 case GL_ALPHA:
4469 case GL_LUMINANCE:
4470 case GL_LUMINANCE_ALPHA:
4471 switch (type)
4472 {
4473 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004474 case GL_FLOAT:
4475 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004476 break;
4477 default:
4478 return error(GL_INVALID_ENUM);
4479 }
4480 break;
4481 case GL_RGB:
4482 switch (type)
4483 {
4484 case GL_UNSIGNED_BYTE:
4485 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004486 case GL_FLOAT:
4487 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004488 break;
4489 default:
4490 return error(GL_INVALID_ENUM);
4491 }
4492 break;
4493 case GL_RGBA:
4494 switch (type)
4495 {
4496 case GL_UNSIGNED_BYTE:
4497 case GL_UNSIGNED_SHORT_4_4_4_4:
4498 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004499 case GL_FLOAT:
4500 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004501 break;
4502 default:
4503 return error(GL_INVALID_ENUM);
4504 }
4505 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004506 case GL_BGRA_EXT:
4507 switch (type)
4508 {
4509 case GL_UNSIGNED_BYTE:
4510 break;
4511 default:
4512 return error(GL_INVALID_ENUM);
4513 }
4514 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004515 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4516 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4517 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004518 default:
4519 return error(GL_INVALID_VALUE);
4520 }
4521
4522 if (border != 0)
4523 {
4524 return error(GL_INVALID_VALUE);
4525 }
4526
4527 gl::Context *context = gl::getContext();
4528
4529 if (context)
4530 {
daniel@transgaming.com01868132010-08-24 19:21:17 +00004531 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4532 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
4533 {
4534 if (context->supportsCompressedTextures())
4535 {
4536 return error(GL_INVALID_OPERATION);
4537 }
4538 else
4539 {
4540 return error(GL_INVALID_ENUM);
4541 }
4542 }
4543
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004544 if (type == GL_FLOAT)
4545 {
4546 if (!context->supportsFloatTextures())
4547 {
4548 return error(GL_INVALID_ENUM);
4549 }
4550 }
4551 else if (type == GL_HALF_FLOAT_OES)
4552 {
4553 if (!context->supportsHalfFloatTextures())
4554 {
4555 return error(GL_INVALID_ENUM);
4556 }
4557 }
4558
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004559 if (target == GL_TEXTURE_2D)
4560 {
4561 gl::Texture2D *texture = context->getTexture2D();
4562
4563 if (!texture)
4564 {
4565 return error(GL_INVALID_OPERATION);
4566 }
4567
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004568 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004569 }
4570 else
4571 {
4572 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4573
4574 if (!texture)
4575 {
4576 return error(GL_INVALID_OPERATION);
4577 }
4578
4579 switch (target)
4580 {
4581 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004582 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004583 break;
4584 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004585 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004586 break;
4587 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004588 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004589 break;
4590 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004591 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004592 break;
4593 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004594 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004595 break;
4596 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004597 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004598 break;
4599 default: UNREACHABLE();
4600 }
4601 }
4602 }
4603 }
4604 catch(std::bad_alloc&)
4605 {
4606 return error(GL_OUT_OF_MEMORY);
4607 }
4608}
4609
4610void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4611{
4612 glTexParameteri(target, pname, (GLint)param);
4613}
4614
4615void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4616{
4617 glTexParameteri(target, pname, (GLint)*params);
4618}
4619
4620void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4621{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004622 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004623
4624 try
4625 {
4626 gl::Context *context = gl::getContext();
4627
4628 if (context)
4629 {
4630 gl::Texture *texture;
4631
4632 switch (target)
4633 {
4634 case GL_TEXTURE_2D:
4635 texture = context->getTexture2D();
4636 break;
4637 case GL_TEXTURE_CUBE_MAP:
4638 texture = context->getTextureCubeMap();
4639 break;
4640 default:
4641 return error(GL_INVALID_ENUM);
4642 }
4643
4644 switch (pname)
4645 {
4646 case GL_TEXTURE_WRAP_S:
4647 if (!texture->setWrapS((GLenum)param))
4648 {
4649 return error(GL_INVALID_ENUM);
4650 }
4651 break;
4652 case GL_TEXTURE_WRAP_T:
4653 if (!texture->setWrapT((GLenum)param))
4654 {
4655 return error(GL_INVALID_ENUM);
4656 }
4657 break;
4658 case GL_TEXTURE_MIN_FILTER:
4659 if (!texture->setMinFilter((GLenum)param))
4660 {
4661 return error(GL_INVALID_ENUM);
4662 }
4663 break;
4664 case GL_TEXTURE_MAG_FILTER:
4665 if (!texture->setMagFilter((GLenum)param))
4666 {
4667 return error(GL_INVALID_ENUM);
4668 }
4669 break;
4670 default:
4671 return error(GL_INVALID_ENUM);
4672 }
4673 }
4674 }
4675 catch(std::bad_alloc&)
4676 {
4677 return error(GL_OUT_OF_MEMORY);
4678 }
4679}
4680
4681void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4682{
4683 glTexParameteri(target, pname, *params);
4684}
4685
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004686void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4687 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004688{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004689 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4690 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004691 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004692 target, level, xoffset, yoffset, width, height, format, type, pixels);
4693
4694 try
4695 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004696 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004697 {
4698 return error(GL_INVALID_ENUM);
4699 }
4700
4701 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004702 {
4703 return error(GL_INVALID_VALUE);
4704 }
4705
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004706 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4707 {
4708 return error(GL_INVALID_VALUE);
4709 }
4710
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004711 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004712 {
4713 return error(GL_INVALID_ENUM);
4714 }
4715
4716 if (width == 0 || height == 0 || pixels == NULL)
4717 {
4718 return;
4719 }
4720
4721 gl::Context *context = gl::getContext();
4722
4723 if (context)
4724 {
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004725 if (format == GL_FLOAT)
4726 {
4727 if (!context->supportsFloatTextures())
4728 {
4729 return error(GL_INVALID_ENUM);
4730 }
4731 }
4732 else if (format == GL_HALF_FLOAT_OES)
4733 {
4734 if (!context->supportsHalfFloatTextures())
4735 {
4736 return error(GL_INVALID_ENUM);
4737 }
4738 }
4739
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004740 if (target == GL_TEXTURE_2D)
4741 {
4742 gl::Texture2D *texture = context->getTexture2D();
4743
4744 if (!texture)
4745 {
4746 return error(GL_INVALID_OPERATION);
4747 }
4748
daniel@transgaming.com01868132010-08-24 19:21:17 +00004749 if (texture->isCompressed())
4750 {
4751 return error(GL_INVALID_OPERATION);
4752 }
4753
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004754 if (format != texture->getFormat())
4755 {
4756 return error(GL_INVALID_OPERATION);
4757 }
4758
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004759 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004760 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004761 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004762 {
4763 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4764
4765 if (!texture)
4766 {
4767 return error(GL_INVALID_OPERATION);
4768 }
4769
daniel@transgaming.com01868132010-08-24 19:21:17 +00004770 if (texture->isCompressed())
4771 {
4772 return error(GL_INVALID_OPERATION);
4773 }
4774
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004775 if (format != texture->getFormat())
4776 {
4777 return error(GL_INVALID_OPERATION);
4778 }
4779
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004780 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004781 }
4782 else
4783 {
4784 UNREACHABLE();
4785 }
4786 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004787 }
4788 catch(std::bad_alloc&)
4789 {
4790 return error(GL_OUT_OF_MEMORY);
4791 }
4792}
4793
4794void __stdcall glUniform1f(GLint location, GLfloat x)
4795{
4796 glUniform1fv(location, 1, &x);
4797}
4798
4799void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4800{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004801 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004802
4803 try
4804 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004805 if (count < 0)
4806 {
4807 return error(GL_INVALID_VALUE);
4808 }
4809
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004810 if (location == -1)
4811 {
4812 return;
4813 }
4814
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004815 gl::Context *context = gl::getContext();
4816
4817 if (context)
4818 {
4819 gl::Program *program = context->getCurrentProgram();
4820
4821 if (!program)
4822 {
4823 return error(GL_INVALID_OPERATION);
4824 }
4825
4826 if (!program->setUniform1fv(location, count, v))
4827 {
4828 return error(GL_INVALID_OPERATION);
4829 }
4830 }
4831 }
4832 catch(std::bad_alloc&)
4833 {
4834 return error(GL_OUT_OF_MEMORY);
4835 }
4836}
4837
4838void __stdcall glUniform1i(GLint location, GLint x)
4839{
4840 glUniform1iv(location, 1, &x);
4841}
4842
4843void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4844{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004845 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004846
4847 try
4848 {
4849 if (count < 0)
4850 {
4851 return error(GL_INVALID_VALUE);
4852 }
4853
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004854 if (location == -1)
4855 {
4856 return;
4857 }
4858
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004859 gl::Context *context = gl::getContext();
4860
4861 if (context)
4862 {
4863 gl::Program *program = context->getCurrentProgram();
4864
4865 if (!program)
4866 {
4867 return error(GL_INVALID_OPERATION);
4868 }
4869
4870 if (!program->setUniform1iv(location, count, v))
4871 {
4872 return error(GL_INVALID_OPERATION);
4873 }
4874 }
4875 }
4876 catch(std::bad_alloc&)
4877 {
4878 return error(GL_OUT_OF_MEMORY);
4879 }
4880}
4881
4882void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4883{
4884 GLfloat xy[2] = {x, y};
4885
4886 glUniform2fv(location, 1, (GLfloat*)&xy);
4887}
4888
4889void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4890{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004891 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004892
4893 try
4894 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004895 if (count < 0)
4896 {
4897 return error(GL_INVALID_VALUE);
4898 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004899
4900 if (location == -1)
4901 {
4902 return;
4903 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004904
4905 gl::Context *context = gl::getContext();
4906
4907 if (context)
4908 {
4909 gl::Program *program = context->getCurrentProgram();
4910
4911 if (!program)
4912 {
4913 return error(GL_INVALID_OPERATION);
4914 }
4915
4916 if (!program->setUniform2fv(location, count, v))
4917 {
4918 return error(GL_INVALID_OPERATION);
4919 }
4920 }
4921 }
4922 catch(std::bad_alloc&)
4923 {
4924 return error(GL_OUT_OF_MEMORY);
4925 }
4926}
4927
4928void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4929{
4930 GLint xy[4] = {x, y};
4931
4932 glUniform2iv(location, 1, (GLint*)&xy);
4933}
4934
4935void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4936{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004937 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004938
4939 try
4940 {
4941 if (count < 0)
4942 {
4943 return error(GL_INVALID_VALUE);
4944 }
4945
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004946 if (location == -1)
4947 {
4948 return;
4949 }
4950
4951 gl::Context *context = gl::getContext();
4952
4953 if (context)
4954 {
4955 gl::Program *program = context->getCurrentProgram();
4956
4957 if (!program)
4958 {
4959 return error(GL_INVALID_OPERATION);
4960 }
4961
4962 if (!program->setUniform2iv(location, count, v))
4963 {
4964 return error(GL_INVALID_OPERATION);
4965 }
4966 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004967 }
4968 catch(std::bad_alloc&)
4969 {
4970 return error(GL_OUT_OF_MEMORY);
4971 }
4972}
4973
4974void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4975{
4976 GLfloat xyz[3] = {x, y, z};
4977
4978 glUniform3fv(location, 1, (GLfloat*)&xyz);
4979}
4980
4981void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4982{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004983 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004984
4985 try
4986 {
4987 if (count < 0)
4988 {
4989 return error(GL_INVALID_VALUE);
4990 }
4991
4992 if (location == -1)
4993 {
4994 return;
4995 }
4996
4997 gl::Context *context = gl::getContext();
4998
4999 if (context)
5000 {
5001 gl::Program *program = context->getCurrentProgram();
5002
5003 if (!program)
5004 {
5005 return error(GL_INVALID_OPERATION);
5006 }
5007
5008 if (!program->setUniform3fv(location, count, v))
5009 {
5010 return error(GL_INVALID_OPERATION);
5011 }
5012 }
5013 }
5014 catch(std::bad_alloc&)
5015 {
5016 return error(GL_OUT_OF_MEMORY);
5017 }
5018}
5019
5020void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5021{
5022 GLint xyz[3] = {x, y, z};
5023
5024 glUniform3iv(location, 1, (GLint*)&xyz);
5025}
5026
5027void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5028{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005029 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005030
5031 try
5032 {
5033 if (count < 0)
5034 {
5035 return error(GL_INVALID_VALUE);
5036 }
5037
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005038 if (location == -1)
5039 {
5040 return;
5041 }
5042
5043 gl::Context *context = gl::getContext();
5044
5045 if (context)
5046 {
5047 gl::Program *program = context->getCurrentProgram();
5048
5049 if (!program)
5050 {
5051 return error(GL_INVALID_OPERATION);
5052 }
5053
5054 if (!program->setUniform3iv(location, count, v))
5055 {
5056 return error(GL_INVALID_OPERATION);
5057 }
5058 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005059 }
5060 catch(std::bad_alloc&)
5061 {
5062 return error(GL_OUT_OF_MEMORY);
5063 }
5064}
5065
5066void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5067{
5068 GLfloat xyzw[4] = {x, y, z, w};
5069
5070 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5071}
5072
5073void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5074{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005075 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005076
5077 try
5078 {
5079 if (count < 0)
5080 {
5081 return error(GL_INVALID_VALUE);
5082 }
5083
5084 if (location == -1)
5085 {
5086 return;
5087 }
5088
5089 gl::Context *context = gl::getContext();
5090
5091 if (context)
5092 {
5093 gl::Program *program = context->getCurrentProgram();
5094
5095 if (!program)
5096 {
5097 return error(GL_INVALID_OPERATION);
5098 }
5099
5100 if (!program->setUniform4fv(location, count, v))
5101 {
5102 return error(GL_INVALID_OPERATION);
5103 }
5104 }
5105 }
5106 catch(std::bad_alloc&)
5107 {
5108 return error(GL_OUT_OF_MEMORY);
5109 }
5110}
5111
5112void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5113{
5114 GLint xyzw[4] = {x, y, z, w};
5115
5116 glUniform4iv(location, 1, (GLint*)&xyzw);
5117}
5118
5119void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5120{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005121 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005122
5123 try
5124 {
5125 if (count < 0)
5126 {
5127 return error(GL_INVALID_VALUE);
5128 }
5129
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005130 if (location == -1)
5131 {
5132 return;
5133 }
5134
5135 gl::Context *context = gl::getContext();
5136
5137 if (context)
5138 {
5139 gl::Program *program = context->getCurrentProgram();
5140
5141 if (!program)
5142 {
5143 return error(GL_INVALID_OPERATION);
5144 }
5145
5146 if (!program->setUniform4iv(location, count, v))
5147 {
5148 return error(GL_INVALID_OPERATION);
5149 }
5150 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005151 }
5152 catch(std::bad_alloc&)
5153 {
5154 return error(GL_OUT_OF_MEMORY);
5155 }
5156}
5157
5158void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5159{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005160 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5161 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005162
5163 try
5164 {
5165 if (count < 0 || transpose != GL_FALSE)
5166 {
5167 return error(GL_INVALID_VALUE);
5168 }
5169
5170 if (location == -1)
5171 {
5172 return;
5173 }
5174
5175 gl::Context *context = gl::getContext();
5176
5177 if (context)
5178 {
5179 gl::Program *program = context->getCurrentProgram();
5180
5181 if (!program)
5182 {
5183 return error(GL_INVALID_OPERATION);
5184 }
5185
5186 if (!program->setUniformMatrix2fv(location, count, value))
5187 {
5188 return error(GL_INVALID_OPERATION);
5189 }
5190 }
5191 }
5192 catch(std::bad_alloc&)
5193 {
5194 return error(GL_OUT_OF_MEMORY);
5195 }
5196}
5197
5198void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5199{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005200 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5201 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005202
5203 try
5204 {
5205 if (count < 0 || transpose != GL_FALSE)
5206 {
5207 return error(GL_INVALID_VALUE);
5208 }
5209
5210 if (location == -1)
5211 {
5212 return;
5213 }
5214
5215 gl::Context *context = gl::getContext();
5216
5217 if (context)
5218 {
5219 gl::Program *program = context->getCurrentProgram();
5220
5221 if (!program)
5222 {
5223 return error(GL_INVALID_OPERATION);
5224 }
5225
5226 if (!program->setUniformMatrix3fv(location, count, value))
5227 {
5228 return error(GL_INVALID_OPERATION);
5229 }
5230 }
5231 }
5232 catch(std::bad_alloc&)
5233 {
5234 return error(GL_OUT_OF_MEMORY);
5235 }
5236}
5237
5238void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5239{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005240 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5241 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005242
5243 try
5244 {
5245 if (count < 0 || transpose != GL_FALSE)
5246 {
5247 return error(GL_INVALID_VALUE);
5248 }
5249
5250 if (location == -1)
5251 {
5252 return;
5253 }
5254
5255 gl::Context *context = gl::getContext();
5256
5257 if (context)
5258 {
5259 gl::Program *program = context->getCurrentProgram();
5260
5261 if (!program)
5262 {
5263 return error(GL_INVALID_OPERATION);
5264 }
5265
5266 if (!program->setUniformMatrix4fv(location, count, value))
5267 {
5268 return error(GL_INVALID_OPERATION);
5269 }
5270 }
5271 }
5272 catch(std::bad_alloc&)
5273 {
5274 return error(GL_OUT_OF_MEMORY);
5275 }
5276}
5277
5278void __stdcall glUseProgram(GLuint program)
5279{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005280 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005281
5282 try
5283 {
5284 gl::Context *context = gl::getContext();
5285
5286 if (context)
5287 {
5288 gl::Program *programObject = context->getProgram(program);
5289
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005290 if (!programObject && program != 0)
5291 {
5292 if (context->getShader(program))
5293 {
5294 return error(GL_INVALID_OPERATION);
5295 }
5296 else
5297 {
5298 return error(GL_INVALID_VALUE);
5299 }
5300 }
5301
5302 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005303 {
5304 return error(GL_INVALID_OPERATION);
5305 }
5306
5307 context->useProgram(program);
5308 }
5309 }
5310 catch(std::bad_alloc&)
5311 {
5312 return error(GL_OUT_OF_MEMORY);
5313 }
5314}
5315
5316void __stdcall glValidateProgram(GLuint program)
5317{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005318 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005319
5320 try
5321 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005322 gl::Context *context = gl::getContext();
5323
5324 if (context)
5325 {
5326 gl::Program *programObject = context->getProgram(program);
5327
5328 if (!programObject)
5329 {
5330 if (context->getShader(program))
5331 {
5332 return error(GL_INVALID_OPERATION);
5333 }
5334 else
5335 {
5336 return error(GL_INVALID_VALUE);
5337 }
5338 }
5339
5340 programObject->validate();
5341 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005342 }
5343 catch(std::bad_alloc&)
5344 {
5345 return error(GL_OUT_OF_MEMORY);
5346 }
5347}
5348
5349void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5350{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005351 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005352
5353 try
5354 {
5355 if (index >= gl::MAX_VERTEX_ATTRIBS)
5356 {
5357 return error(GL_INVALID_VALUE);
5358 }
5359
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005360 gl::Context *context = gl::getContext();
5361
5362 if (context)
5363 {
5364 GLfloat vals[4] = { x, 0, 0, 1 };
5365 context->setVertexAttrib(index, vals);
5366 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005367 }
5368 catch(std::bad_alloc&)
5369 {
5370 return error(GL_OUT_OF_MEMORY);
5371 }
5372}
5373
5374void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5375{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005376 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005377
5378 try
5379 {
5380 if (index >= gl::MAX_VERTEX_ATTRIBS)
5381 {
5382 return error(GL_INVALID_VALUE);
5383 }
5384
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005385 gl::Context *context = gl::getContext();
5386
5387 if (context)
5388 {
5389 GLfloat vals[4] = { values[0], 0, 0, 1 };
5390 context->setVertexAttrib(index, vals);
5391 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005392 }
5393 catch(std::bad_alloc&)
5394 {
5395 return error(GL_OUT_OF_MEMORY);
5396 }
5397}
5398
5399void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5400{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005401 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005402
5403 try
5404 {
5405 if (index >= gl::MAX_VERTEX_ATTRIBS)
5406 {
5407 return error(GL_INVALID_VALUE);
5408 }
5409
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005410 gl::Context *context = gl::getContext();
5411
5412 if (context)
5413 {
5414 GLfloat vals[4] = { x, y, 0, 1 };
5415 context->setVertexAttrib(index, vals);
5416 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005417 }
5418 catch(std::bad_alloc&)
5419 {
5420 return error(GL_OUT_OF_MEMORY);
5421 }
5422}
5423
5424void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5425{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005426 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005427
5428 try
5429 {
5430 if (index >= gl::MAX_VERTEX_ATTRIBS)
5431 {
5432 return error(GL_INVALID_VALUE);
5433 }
5434
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005435 gl::Context *context = gl::getContext();
5436
5437 if (context)
5438 {
5439 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5440 context->setVertexAttrib(index, vals);
5441 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005442 }
5443 catch(std::bad_alloc&)
5444 {
5445 return error(GL_OUT_OF_MEMORY);
5446 }
5447}
5448
5449void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5450{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005451 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 +00005452
5453 try
5454 {
5455 if (index >= gl::MAX_VERTEX_ATTRIBS)
5456 {
5457 return error(GL_INVALID_VALUE);
5458 }
5459
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005460 gl::Context *context = gl::getContext();
5461
5462 if (context)
5463 {
5464 GLfloat vals[4] = { x, y, z, 1 };
5465 context->setVertexAttrib(index, vals);
5466 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005467 }
5468 catch(std::bad_alloc&)
5469 {
5470 return error(GL_OUT_OF_MEMORY);
5471 }
5472}
5473
5474void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5475{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005476 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005477
5478 try
5479 {
5480 if (index >= gl::MAX_VERTEX_ATTRIBS)
5481 {
5482 return error(GL_INVALID_VALUE);
5483 }
5484
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005485 gl::Context *context = gl::getContext();
5486
5487 if (context)
5488 {
5489 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5490 context->setVertexAttrib(index, vals);
5491 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005492 }
5493 catch(std::bad_alloc&)
5494 {
5495 return error(GL_OUT_OF_MEMORY);
5496 }
5497}
5498
5499void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5500{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005501 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 +00005502
5503 try
5504 {
5505 if (index >= gl::MAX_VERTEX_ATTRIBS)
5506 {
5507 return error(GL_INVALID_VALUE);
5508 }
5509
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005510 gl::Context *context = gl::getContext();
5511
5512 if (context)
5513 {
5514 GLfloat vals[4] = { x, y, z, w };
5515 context->setVertexAttrib(index, vals);
5516 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005517 }
5518 catch(std::bad_alloc&)
5519 {
5520 return error(GL_OUT_OF_MEMORY);
5521 }
5522}
5523
5524void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5525{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005526 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005527
5528 try
5529 {
5530 if (index >= gl::MAX_VERTEX_ATTRIBS)
5531 {
5532 return error(GL_INVALID_VALUE);
5533 }
5534
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005535 gl::Context *context = gl::getContext();
5536
5537 if (context)
5538 {
5539 context->setVertexAttrib(index, values);
5540 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005541 }
5542 catch(std::bad_alloc&)
5543 {
5544 return error(GL_OUT_OF_MEMORY);
5545 }
5546}
5547
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005548void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005549{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005550 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005551 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005552 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005553
5554 try
5555 {
5556 if (index >= gl::MAX_VERTEX_ATTRIBS)
5557 {
5558 return error(GL_INVALID_VALUE);
5559 }
5560
5561 if (size < 1 || size > 4)
5562 {
5563 return error(GL_INVALID_VALUE);
5564 }
5565
5566 switch (type)
5567 {
5568 case GL_BYTE:
5569 case GL_UNSIGNED_BYTE:
5570 case GL_SHORT:
5571 case GL_UNSIGNED_SHORT:
5572 case GL_FIXED:
5573 case GL_FLOAT:
5574 break;
5575 default:
5576 return error(GL_INVALID_ENUM);
5577 }
5578
5579 if (stride < 0)
5580 {
5581 return error(GL_INVALID_VALUE);
5582 }
5583
5584 gl::Context *context = gl::getContext();
5585
5586 if (context)
5587 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005588 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005589 }
5590 }
5591 catch(std::bad_alloc&)
5592 {
5593 return error(GL_OUT_OF_MEMORY);
5594 }
5595}
5596
5597void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5598{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005599 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 +00005600
5601 try
5602 {
5603 if (width < 0 || height < 0)
5604 {
5605 return error(GL_INVALID_VALUE);
5606 }
5607
5608 gl::Context *context = gl::getContext();
5609
5610 if (context)
5611 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005612 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005613 }
5614 }
5615 catch(std::bad_alloc&)
5616 {
5617 return error(GL_OUT_OF_MEMORY);
5618 }
5619}
5620
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005621void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5622 GLbitfield mask, GLenum filter)
5623{
5624 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5625 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5626 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5627 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5628
5629 try
5630 {
5631 switch (filter)
5632 {
5633 case GL_NEAREST:
5634 break;
5635 default:
5636 return error(GL_INVALID_ENUM);
5637 }
5638
5639 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5640 {
5641 return error(GL_INVALID_VALUE);
5642 }
5643
5644 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5645 {
5646 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5647 return error(GL_INVALID_OPERATION);
5648 }
5649
5650 gl::Context *context = gl::getContext();
5651
5652 if (context)
5653 {
5654 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5655 {
5656 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5657 return error(GL_INVALID_OPERATION);
5658 }
5659
5660 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5661 }
5662 }
5663 catch(std::bad_alloc&)
5664 {
5665 return error(GL_OUT_OF_MEMORY);
5666 }
5667}
5668
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005669void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5670 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005671{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005672 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5673 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005674 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005675 target, level, internalformat, width, height, depth, border, format, type, pixels);
5676
5677 try
5678 {
5679 UNIMPLEMENTED(); // FIXME
5680 }
5681 catch(std::bad_alloc&)
5682 {
5683 return error(GL_OUT_OF_MEMORY);
5684 }
5685}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005686
5687__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5688{
5689 struct Extension
5690 {
5691 const char *name;
5692 __eglMustCastToProperFunctionPointerType address;
5693 };
5694
5695 static const Extension glExtensions[] =
5696 {
5697 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00005698 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005699 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
5700 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
5701 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
5702 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
5703 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
5704 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
5705 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005706 };
5707
5708 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5709 {
5710 if (strcmp(procname, glExtensions[ext].name) == 0)
5711 {
5712 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5713 }
5714 }
5715
5716 return NULL;
5717}
5718
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005719}