blob: c986b5e7a14f37ca15587bb50891438d4cde82c4 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000017
18#include "libGLESv2/main.h"
19#include "libGLESv2/mathutil.h"
20#include "libGLESv2/utilities.h"
21#include "libGLESv2/Buffer.h"
22#include "libGLESv2/Context.h"
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +000023#include "libGLESv2/Fence.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000024#include "libGLESv2/Framebuffer.h"
25#include "libGLESv2/Program.h"
26#include "libGLESv2/Renderbuffer.h"
27#include "libGLESv2/Shader.h"
28#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000029
30extern "C"
31{
32
33void __stdcall glActiveTexture(GLenum texture)
34{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000035 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000036
37 try
38 {
39 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
40 {
41 return error(GL_INVALID_ENUM);
42 }
43
44 gl::Context *context = gl::getContext();
45
46 if (context)
47 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +000048 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000049 }
50 }
51 catch(std::bad_alloc&)
52 {
53 return error(GL_OUT_OF_MEMORY);
54 }
55}
56
57void __stdcall glAttachShader(GLuint program, GLuint shader)
58{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000059 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000060
61 try
62 {
63 gl::Context *context = gl::getContext();
64
65 if (context)
66 {
67 gl::Program *programObject = context->getProgram(program);
68 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000069
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000070 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000071 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000072 if (context->getShader(program))
73 {
74 return error(GL_INVALID_OPERATION);
75 }
76 else
77 {
78 return error(GL_INVALID_VALUE);
79 }
80 }
81
82 if (!shaderObject)
83 {
84 if (context->getProgram(shader))
85 {
86 return error(GL_INVALID_OPERATION);
87 }
88 else
89 {
90 return error(GL_INVALID_VALUE);
91 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000092 }
93
94 if (!programObject->attachShader(shaderObject))
95 {
96 return error(GL_INVALID_OPERATION);
97 }
98 }
99 }
100 catch(std::bad_alloc&)
101 {
102 return error(GL_OUT_OF_MEMORY);
103 }
104}
105
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000106void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000108 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000109
110 try
111 {
112 if (index >= gl::MAX_VERTEX_ATTRIBS)
113 {
114 return error(GL_INVALID_VALUE);
115 }
116
117 gl::Context *context = gl::getContext();
118
119 if (context)
120 {
121 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000122
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000123 if (!programObject)
124 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000125 if (context->getShader(program))
126 {
127 return error(GL_INVALID_OPERATION);
128 }
129 else
130 {
131 return error(GL_INVALID_VALUE);
132 }
133 }
134
135 if (strncmp(name, "gl_", 3) == 0)
136 {
137 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000138 }
139
140 programObject->bindAttributeLocation(index, name);
141 }
142 }
143 catch(std::bad_alloc&)
144 {
145 return error(GL_OUT_OF_MEMORY);
146 }
147}
148
149void __stdcall glBindBuffer(GLenum target, GLuint buffer)
150{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000151 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000152
153 try
154 {
155 gl::Context *context = gl::getContext();
156
157 if (context)
158 {
159 switch (target)
160 {
161 case GL_ARRAY_BUFFER:
162 context->bindArrayBuffer(buffer);
163 return;
164 case GL_ELEMENT_ARRAY_BUFFER:
165 context->bindElementArrayBuffer(buffer);
166 return;
167 default:
168 return error(GL_INVALID_ENUM);
169 }
170 }
171 }
172 catch(std::bad_alloc&)
173 {
174 return error(GL_OUT_OF_MEMORY);
175 }
176}
177
178void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
179{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000180 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000181
182 try
183 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000184 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000185 {
186 return error(GL_INVALID_ENUM);
187 }
188
189 gl::Context *context = gl::getContext();
190
191 if (context)
192 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000193 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
194 {
195 context->bindReadFramebuffer(framebuffer);
196 }
197
198 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
199 {
200 context->bindDrawFramebuffer(framebuffer);
201 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000202 }
203 }
204 catch(std::bad_alloc&)
205 {
206 return error(GL_OUT_OF_MEMORY);
207 }
208}
209
210void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
211{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000212 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000213
214 try
215 {
216 if (target != GL_RENDERBUFFER)
217 {
218 return error(GL_INVALID_ENUM);
219 }
220
221 gl::Context *context = gl::getContext();
222
223 if (context)
224 {
225 context->bindRenderbuffer(renderbuffer);
226 }
227 }
228 catch(std::bad_alloc&)
229 {
230 return error(GL_OUT_OF_MEMORY);
231 }
232}
233
234void __stdcall glBindTexture(GLenum target, GLuint texture)
235{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000236 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000237
238 try
239 {
240 gl::Context *context = gl::getContext();
241
242 if (context)
243 {
244 gl::Texture *textureObject = context->getTexture(texture);
245
246 if (textureObject && textureObject->getTarget() != target && texture != 0)
247 {
248 return error(GL_INVALID_OPERATION);
249 }
250
251 switch (target)
252 {
253 case GL_TEXTURE_2D:
254 context->bindTexture2D(texture);
255 return;
256 case GL_TEXTURE_CUBE_MAP:
257 context->bindTextureCubeMap(texture);
258 return;
259 default:
260 return error(GL_INVALID_ENUM);
261 }
262 }
263 }
264 catch(std::bad_alloc&)
265 {
266 return error(GL_OUT_OF_MEMORY);
267 }
268}
269
270void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
271{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000272 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
273 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000274
275 try
276 {
277 gl::Context* context = gl::getContext();
278
279 if (context)
280 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000281 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000282 }
283 }
284 catch(std::bad_alloc&)
285 {
286 return error(GL_OUT_OF_MEMORY);
287 }
288}
289
290void __stdcall glBlendEquation(GLenum mode)
291{
292 glBlendEquationSeparate(mode, mode);
293}
294
295void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
296{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000297 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000298
299 try
300 {
301 switch (modeRGB)
302 {
303 case GL_FUNC_ADD:
304 case GL_FUNC_SUBTRACT:
305 case GL_FUNC_REVERSE_SUBTRACT:
306 break;
307 default:
308 return error(GL_INVALID_ENUM);
309 }
310
311 switch (modeAlpha)
312 {
313 case GL_FUNC_ADD:
314 case GL_FUNC_SUBTRACT:
315 case GL_FUNC_REVERSE_SUBTRACT:
316 break;
317 default:
318 return error(GL_INVALID_ENUM);
319 }
320
321 gl::Context *context = gl::getContext();
322
323 if (context)
324 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000325 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000326 }
327 }
328 catch(std::bad_alloc&)
329 {
330 return error(GL_OUT_OF_MEMORY);
331 }
332}
333
334void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
335{
336 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
337}
338
339void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
340{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000341 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
342 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000343
344 try
345 {
346 switch (srcRGB)
347 {
348 case GL_ZERO:
349 case GL_ONE:
350 case GL_SRC_COLOR:
351 case GL_ONE_MINUS_SRC_COLOR:
352 case GL_DST_COLOR:
353 case GL_ONE_MINUS_DST_COLOR:
354 case GL_SRC_ALPHA:
355 case GL_ONE_MINUS_SRC_ALPHA:
356 case GL_DST_ALPHA:
357 case GL_ONE_MINUS_DST_ALPHA:
358 case GL_CONSTANT_COLOR:
359 case GL_ONE_MINUS_CONSTANT_COLOR:
360 case GL_CONSTANT_ALPHA:
361 case GL_ONE_MINUS_CONSTANT_ALPHA:
362 case GL_SRC_ALPHA_SATURATE:
363 break;
364 default:
365 return error(GL_INVALID_ENUM);
366 }
367
368 switch (dstRGB)
369 {
370 case GL_ZERO:
371 case GL_ONE:
372 case GL_SRC_COLOR:
373 case GL_ONE_MINUS_SRC_COLOR:
374 case GL_DST_COLOR:
375 case GL_ONE_MINUS_DST_COLOR:
376 case GL_SRC_ALPHA:
377 case GL_ONE_MINUS_SRC_ALPHA:
378 case GL_DST_ALPHA:
379 case GL_ONE_MINUS_DST_ALPHA:
380 case GL_CONSTANT_COLOR:
381 case GL_ONE_MINUS_CONSTANT_COLOR:
382 case GL_CONSTANT_ALPHA:
383 case GL_ONE_MINUS_CONSTANT_ALPHA:
384 break;
385 default:
386 return error(GL_INVALID_ENUM);
387 }
388
389 switch (srcAlpha)
390 {
391 case GL_ZERO:
392 case GL_ONE:
393 case GL_SRC_COLOR:
394 case GL_ONE_MINUS_SRC_COLOR:
395 case GL_DST_COLOR:
396 case GL_ONE_MINUS_DST_COLOR:
397 case GL_SRC_ALPHA:
398 case GL_ONE_MINUS_SRC_ALPHA:
399 case GL_DST_ALPHA:
400 case GL_ONE_MINUS_DST_ALPHA:
401 case GL_CONSTANT_COLOR:
402 case GL_ONE_MINUS_CONSTANT_COLOR:
403 case GL_CONSTANT_ALPHA:
404 case GL_ONE_MINUS_CONSTANT_ALPHA:
405 case GL_SRC_ALPHA_SATURATE:
406 break;
407 default:
408 return error(GL_INVALID_ENUM);
409 }
410
411 switch (dstAlpha)
412 {
413 case GL_ZERO:
414 case GL_ONE:
415 case GL_SRC_COLOR:
416 case GL_ONE_MINUS_SRC_COLOR:
417 case GL_DST_COLOR:
418 case GL_ONE_MINUS_DST_COLOR:
419 case GL_SRC_ALPHA:
420 case GL_ONE_MINUS_SRC_ALPHA:
421 case GL_DST_ALPHA:
422 case GL_ONE_MINUS_DST_ALPHA:
423 case GL_CONSTANT_COLOR:
424 case GL_ONE_MINUS_CONSTANT_COLOR:
425 case GL_CONSTANT_ALPHA:
426 case GL_ONE_MINUS_CONSTANT_ALPHA:
427 break;
428 default:
429 return error(GL_INVALID_ENUM);
430 }
431
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000432 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
433 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
434
435 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
436 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
437
438 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000439 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000440 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
441 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000442 }
443
444 gl::Context *context = gl::getContext();
445
446 if (context)
447 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000448 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000449 }
450 }
451 catch(std::bad_alloc&)
452 {
453 return error(GL_OUT_OF_MEMORY);
454 }
455}
456
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000457void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000458{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000459 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000460 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000461
462 try
463 {
464 if (size < 0)
465 {
466 return error(GL_INVALID_VALUE);
467 }
468
469 switch (usage)
470 {
471 case GL_STREAM_DRAW:
472 case GL_STATIC_DRAW:
473 case GL_DYNAMIC_DRAW:
474 break;
475 default:
476 return error(GL_INVALID_ENUM);
477 }
478
479 gl::Context *context = gl::getContext();
480
481 if (context)
482 {
483 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000484
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000485 switch (target)
486 {
487 case GL_ARRAY_BUFFER:
488 buffer = context->getArrayBuffer();
489 break;
490 case GL_ELEMENT_ARRAY_BUFFER:
491 buffer = context->getElementArrayBuffer();
492 break;
493 default:
494 return error(GL_INVALID_ENUM);
495 }
496
497 if (!buffer)
498 {
499 return error(GL_INVALID_OPERATION);
500 }
501
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000502 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000503 }
504 }
505 catch(std::bad_alloc&)
506 {
507 return error(GL_OUT_OF_MEMORY);
508 }
509}
510
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000511void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000513 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000514 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000515
516 try
517 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000518 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000519 {
520 return error(GL_INVALID_VALUE);
521 }
522
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000523 if (data == NULL)
524 {
525 return;
526 }
527
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000528 gl::Context *context = gl::getContext();
529
530 if (context)
531 {
532 gl::Buffer *buffer;
533
534 switch (target)
535 {
536 case GL_ARRAY_BUFFER:
537 buffer = context->getArrayBuffer();
538 break;
539 case GL_ELEMENT_ARRAY_BUFFER:
540 buffer = context->getElementArrayBuffer();
541 break;
542 default:
543 return error(GL_INVALID_ENUM);
544 }
545
546 if (!buffer)
547 {
548 return error(GL_INVALID_OPERATION);
549 }
550
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000551 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000552 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000553 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000554 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000555
556 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000557 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000558 }
559 catch(std::bad_alloc&)
560 {
561 return error(GL_OUT_OF_MEMORY);
562 }
563}
564
565GLenum __stdcall glCheckFramebufferStatus(GLenum target)
566{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000567 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000568
569 try
570 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000571 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000572 {
573 return error(GL_INVALID_ENUM, 0);
574 }
575
576 gl::Context *context = gl::getContext();
577
578 if (context)
579 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000580 gl::Framebuffer *framebuffer = NULL;
581 if (target == GL_READ_FRAMEBUFFER_ANGLE)
582 {
583 framebuffer = context->getReadFramebuffer();
584 }
585 else
586 {
587 framebuffer = context->getDrawFramebuffer();
588 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000589
590 return framebuffer->completeness();
591 }
592 }
593 catch(std::bad_alloc&)
594 {
595 return error(GL_OUT_OF_MEMORY, 0);
596 }
597
598 return 0;
599}
600
601void __stdcall glClear(GLbitfield mask)
602{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000603 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000604
605 try
606 {
607 gl::Context *context = gl::getContext();
608
609 if (context)
610 {
611 context->clear(mask);
612 }
613 }
614 catch(std::bad_alloc&)
615 {
616 return error(GL_OUT_OF_MEMORY);
617 }
618}
619
620void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
621{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000622 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
623 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000624
625 try
626 {
627 gl::Context *context = gl::getContext();
628
629 if (context)
630 {
631 context->setClearColor(red, green, blue, alpha);
632 }
633 }
634 catch(std::bad_alloc&)
635 {
636 return error(GL_OUT_OF_MEMORY);
637 }
638}
639
640void __stdcall glClearDepthf(GLclampf depth)
641{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000642 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000643
644 try
645 {
646 gl::Context *context = gl::getContext();
647
648 if (context)
649 {
650 context->setClearDepth(depth);
651 }
652 }
653 catch(std::bad_alloc&)
654 {
655 return error(GL_OUT_OF_MEMORY);
656 }
657}
658
659void __stdcall glClearStencil(GLint s)
660{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000661 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000662
663 try
664 {
665 gl::Context *context = gl::getContext();
666
667 if (context)
668 {
669 context->setClearStencil(s);
670 }
671 }
672 catch(std::bad_alloc&)
673 {
674 return error(GL_OUT_OF_MEMORY);
675 }
676}
677
678void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
679{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000680 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
681 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000682
683 try
684 {
685 gl::Context *context = gl::getContext();
686
687 if (context)
688 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000689 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000690 }
691 }
692 catch(std::bad_alloc&)
693 {
694 return error(GL_OUT_OF_MEMORY);
695 }
696}
697
698void __stdcall glCompileShader(GLuint shader)
699{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000700 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000701
702 try
703 {
704 gl::Context *context = gl::getContext();
705
706 if (context)
707 {
708 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000709
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000710 if (!shaderObject)
711 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000712 if (context->getProgram(shader))
713 {
714 return error(GL_INVALID_OPERATION);
715 }
716 else
717 {
718 return error(GL_INVALID_VALUE);
719 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000720 }
721
722 shaderObject->compile();
723 }
724 }
725 catch(std::bad_alloc&)
726 {
727 return error(GL_OUT_OF_MEMORY);
728 }
729}
730
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000731void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
732 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000733{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000734 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000735 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000736 target, level, internalformat, width, height, border, imageSize, data);
737
738 try
739 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000740 if (level < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000741 {
742 return error(GL_INVALID_VALUE);
743 }
744
daniel@transgaming.com41430492010-03-11 20:36:18 +0000745 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
746 {
747 return error(GL_INVALID_VALUE);
748 }
749
daniel@transgaming.com01868132010-08-24 19:21:17 +0000750 switch (internalformat)
751 {
752 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
753 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
754 break;
755 default:
756 return error(GL_INVALID_ENUM);
757 }
758
759 if (border != 0)
760 {
761 return error(GL_INVALID_VALUE);
762 }
763
764 gl::Context *context = gl::getContext();
765
766 if (context)
767 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000768 if (level > context->getMaximumTextureLevel())
769 {
770 return error(GL_INVALID_VALUE);
771 }
772
773 switch (target)
774 {
775 case GL_TEXTURE_2D:
776 if (width > (context->getMaximumTextureDimension() >> level) ||
777 height > (context->getMaximumTextureDimension() >> level))
778 {
779 return error(GL_INVALID_VALUE);
780 }
781 break;
782 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
783 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
784 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
785 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
786 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
787 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
788 if (width != height)
789 {
790 return error(GL_INVALID_VALUE);
791 }
792
793 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
794 height > (context->getMaximumCubeTextureDimension() >> level))
795 {
796 return error(GL_INVALID_VALUE);
797 }
798 break;
799 default:
800 return error(GL_INVALID_ENUM);
801 }
802
daniel@transgaming.com01868132010-08-24 19:21:17 +0000803 if (!context->supportsCompressedTextures())
804 {
805 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
806 }
807
808 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
809 {
810 return error(GL_INVALID_VALUE);
811 }
812
813 if (target == GL_TEXTURE_2D)
814 {
815 gl::Texture2D *texture = context->getTexture2D();
816
817 if (!texture)
818 {
819 return error(GL_INVALID_OPERATION);
820 }
821
822 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
823 }
824 else
825 {
826 gl::TextureCubeMap *texture = context->getTextureCubeMap();
827
828 if (!texture)
829 {
830 return error(GL_INVALID_OPERATION);
831 }
832
833 switch (target)
834 {
835 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
836 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
837 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
838 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
839 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
840 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
841 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
842 break;
843 default: UNREACHABLE();
844 }
845 }
846 }
847
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000848 }
849 catch(std::bad_alloc&)
850 {
851 return error(GL_OUT_OF_MEMORY);
852 }
853}
854
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000855void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
856 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000857{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000858 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
859 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000860 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000861 target, level, xoffset, yoffset, width, height, format, imageSize, data);
862
863 try
864 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000865 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000866 {
867 return error(GL_INVALID_ENUM);
868 }
869
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000870 if (level < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000871 {
872 return error(GL_INVALID_VALUE);
873 }
874
daniel@transgaming.com01868132010-08-24 19:21:17 +0000875 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 ||
876 (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000877 {
878 return error(GL_INVALID_VALUE);
879 }
880
daniel@transgaming.com01868132010-08-24 19:21:17 +0000881 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000882 {
daniel@transgaming.com01868132010-08-24 19:21:17 +0000883 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
884 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
885 break;
886 default:
887 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +0000888 }
889
daniel@transgaming.com01868132010-08-24 19:21:17 +0000890 if (width == 0 || height == 0 || data == NULL)
891 {
892 return;
893 }
894
895 gl::Context *context = gl::getContext();
896
897 if (context)
898 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +0000899 if (level > context->getMaximumTextureLevel())
900 {
901 return error(GL_INVALID_VALUE);
902 }
903
daniel@transgaming.com01868132010-08-24 19:21:17 +0000904 if (!context->supportsCompressedTextures())
905 {
906 return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
907 }
908
909 if (imageSize != gl::ComputeCompressedSize(width, height, format))
910 {
911 return error(GL_INVALID_VALUE);
912 }
913
914 if (xoffset % 4 != 0 || yoffset % 4 != 0)
915 {
916 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
917 // does not exist unless DXT1 textures are supported.
918 }
919
920 if (target == GL_TEXTURE_2D)
921 {
922 gl::Texture2D *texture = context->getTexture2D();
923
924 if (!texture)
925 {
926 return error(GL_INVALID_OPERATION);
927 }
928
929 if (!texture->isCompressed())
930 {
931 return error(GL_INVALID_OPERATION);
932 }
933
934 if ((width % 4 != 0 && width != texture->getWidth()) ||
935 (height % 4 != 0 && height != texture->getHeight()))
936 {
937 return error(GL_INVALID_OPERATION);
938 }
939
940 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
941 }
942 else if (gl::IsCubemapTextureTarget(target))
943 {
944 gl::TextureCubeMap *texture = context->getTextureCubeMap();
945
946 if (!texture)
947 {
948 return error(GL_INVALID_OPERATION);
949 }
950
951 if (!texture->isCompressed())
952 {
953 return error(GL_INVALID_OPERATION);
954 }
955
956 if ((width % 4 != 0 && width != texture->getWidth()) ||
957 (height % 4 != 0 && height != texture->getHeight()))
958 {
959 return error(GL_INVALID_OPERATION);
960 }
961
962 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
963 }
964 else
965 {
966 UNREACHABLE();
967 }
968 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000969 }
970 catch(std::bad_alloc&)
971 {
972 return error(GL_OUT_OF_MEMORY);
973 }
974}
975
976void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
977{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000978 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
979 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000980 target, level, internalformat, x, y, width, height, border);
981
982 try
983 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000984 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000985 {
986 return error(GL_INVALID_VALUE);
987 }
988
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000989 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
990 {
991 return error(GL_INVALID_VALUE);
992 }
993
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000994 switch (internalformat)
995 {
996 case GL_ALPHA:
997 case GL_LUMINANCE:
998 case GL_LUMINANCE_ALPHA:
999 case GL_RGB:
1000 case GL_RGBA:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001001 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // Compressed textures are not supported here, but if they are unsupported altogether,
1002 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 +00001003 break;
1004 default:
1005 return error(GL_INVALID_VALUE);
1006 }
1007
1008 if (border != 0)
1009 {
1010 return error(GL_INVALID_VALUE);
1011 }
1012
1013 gl::Context *context = gl::getContext();
1014
1015 if (context)
1016 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001017 switch (target)
1018 {
1019 case GL_TEXTURE_2D:
1020 if (width > (context->getMaximumTextureDimension() >> level) ||
1021 height > (context->getMaximumTextureDimension() >> level))
1022 {
1023 return error(GL_INVALID_VALUE);
1024 }
1025 break;
1026 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1027 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1028 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1029 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1030 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1031 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1032 if (width != height)
1033 {
1034 return error(GL_INVALID_VALUE);
1035 }
1036
1037 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1038 height > (context->getMaximumCubeTextureDimension() >> level))
1039 {
1040 return error(GL_INVALID_VALUE);
1041 }
1042 break;
1043 default:
1044 return error(GL_INVALID_ENUM);
1045 }
1046
daniel@transgaming.com01868132010-08-24 19:21:17 +00001047 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
1048 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
1049 {
1050 if (context->supportsCompressedTextures())
1051 {
1052 return error(GL_INVALID_OPERATION);
1053 }
1054 else
1055 {
1056 return error(GL_INVALID_ENUM);
1057 }
1058 }
1059
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001060 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001061 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1062 {
1063 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1064 }
1065
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001066 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1067 {
1068 return error(GL_INVALID_OPERATION);
1069 }
1070
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001071 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001072 if (target == GL_TEXTURE_2D)
1073 {
1074 gl::Texture2D *texture = context->getTexture2D();
1075
1076 if (!texture)
1077 {
1078 return error(GL_INVALID_OPERATION);
1079 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001080
1081 if (texture->isCompressed())
1082 {
1083 return error(GL_INVALID_OPERATION);
1084 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001085
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001086 if (texture->isFloatingPoint())
1087 {
1088 return error(GL_INVALID_OPERATION);
1089 }
1090
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001091 texture->copyImage(level, internalformat, x, y, width, height, source);
1092 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001093 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001094 {
1095 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1096
1097 if (!texture)
1098 {
1099 return error(GL_INVALID_OPERATION);
1100 }
1101
daniel@transgaming.com01868132010-08-24 19:21:17 +00001102 if (texture->isCompressed())
1103 {
1104 return error(GL_INVALID_OPERATION);
1105 }
1106
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001107 if (texture->isFloatingPoint())
1108 {
1109 return error(GL_INVALID_OPERATION);
1110 }
1111
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001112 texture->copyImage(target, level, internalformat, x, y, width, height, source);
1113 }
1114 else
1115 {
1116 UNREACHABLE();
1117 }
1118 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001119 }
1120 catch(std::bad_alloc&)
1121 {
1122 return error(GL_OUT_OF_MEMORY);
1123 }
1124}
1125
1126void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1127{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001128 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1129 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001130 target, level, xoffset, yoffset, x, y, width, height);
1131
1132 try
1133 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001134 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001135 {
1136 return error(GL_INVALID_ENUM);
1137 }
1138
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001139 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001140 {
1141 return error(GL_INVALID_VALUE);
1142 }
1143
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001144 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1145 {
1146 return error(GL_INVALID_VALUE);
1147 }
1148
1149 if (width == 0 || height == 0)
1150 {
1151 return;
1152 }
1153
1154 gl::Context *context = gl::getContext();
1155
1156 if (context)
1157 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00001158 if (level > context->getMaximumTextureLevel())
1159 {
1160 return error(GL_INVALID_VALUE);
1161 }
1162
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001163 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001164 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1165 {
1166 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1167 }
1168
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001169 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1170 {
1171 return error(GL_INVALID_OPERATION);
1172 }
1173
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001174 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001175 if (target == GL_TEXTURE_2D)
1176 {
1177 gl::Texture2D *texture = context->getTexture2D();
1178
1179 if (!texture)
1180 {
1181 return error(GL_INVALID_OPERATION);
1182 }
1183
daniel@transgaming.com01868132010-08-24 19:21:17 +00001184 if (texture->isCompressed())
1185 {
1186 return error(GL_INVALID_OPERATION);
1187 }
1188
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001189 if (texture->isFloatingPoint())
1190 {
1191 return error(GL_INVALID_OPERATION);
1192 }
1193
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001194 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
1195 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001196 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001197 {
1198 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1199
1200 if (!texture)
1201 {
1202 return error(GL_INVALID_OPERATION);
1203 }
1204
daniel@transgaming.com01868132010-08-24 19:21:17 +00001205 if (texture->isCompressed())
1206 {
1207 return error(GL_INVALID_OPERATION);
1208 }
1209
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001210 if (texture->isFloatingPoint())
1211 {
1212 return error(GL_INVALID_OPERATION);
1213 }
1214
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001215 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
1216 }
1217 else
1218 {
1219 UNREACHABLE();
1220 }
1221 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001222 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001223
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001224 catch(std::bad_alloc&)
1225 {
1226 return error(GL_OUT_OF_MEMORY);
1227 }
1228}
1229
1230GLuint __stdcall glCreateProgram(void)
1231{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001232 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001233
1234 try
1235 {
1236 gl::Context *context = gl::getContext();
1237
1238 if (context)
1239 {
1240 return context->createProgram();
1241 }
1242 }
1243 catch(std::bad_alloc&)
1244 {
1245 return error(GL_OUT_OF_MEMORY, 0);
1246 }
1247
1248 return 0;
1249}
1250
1251GLuint __stdcall glCreateShader(GLenum type)
1252{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001253 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001254
1255 try
1256 {
1257 gl::Context *context = gl::getContext();
1258
1259 if (context)
1260 {
1261 switch (type)
1262 {
1263 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001264 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001265 return context->createShader(type);
1266 default:
1267 return error(GL_INVALID_ENUM, 0);
1268 }
1269 }
1270 }
1271 catch(std::bad_alloc&)
1272 {
1273 return error(GL_OUT_OF_MEMORY, 0);
1274 }
1275
1276 return 0;
1277}
1278
1279void __stdcall glCullFace(GLenum mode)
1280{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001281 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001282
1283 try
1284 {
1285 switch (mode)
1286 {
1287 case GL_FRONT:
1288 case GL_BACK:
1289 case GL_FRONT_AND_BACK:
1290 {
1291 gl::Context *context = gl::getContext();
1292
1293 if (context)
1294 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001295 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001296 }
1297 }
1298 break;
1299 default:
1300 return error(GL_INVALID_ENUM);
1301 }
1302 }
1303 catch(std::bad_alloc&)
1304 {
1305 return error(GL_OUT_OF_MEMORY);
1306 }
1307}
1308
1309void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1310{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001311 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001312
1313 try
1314 {
1315 if (n < 0)
1316 {
1317 return error(GL_INVALID_VALUE);
1318 }
1319
1320 gl::Context *context = gl::getContext();
1321
1322 if (context)
1323 {
1324 for (int i = 0; i < n; i++)
1325 {
1326 context->deleteBuffer(buffers[i]);
1327 }
1328 }
1329 }
1330 catch(std::bad_alloc&)
1331 {
1332 return error(GL_OUT_OF_MEMORY);
1333 }
1334}
1335
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001336void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1337{
1338 TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
1339
1340 try
1341 {
1342 if (n < 0)
1343 {
1344 return error(GL_INVALID_VALUE);
1345 }
1346
1347 gl::Context *context = gl::getContext();
1348
1349 if (context)
1350 {
1351 for (int i = 0; i < n; i++)
1352 {
1353 context->deleteFence(fences[i]);
1354 }
1355 }
1356 }
1357 catch(std::bad_alloc&)
1358 {
1359 return error(GL_OUT_OF_MEMORY);
1360 }
1361}
1362
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001363void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1364{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001365 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001366
1367 try
1368 {
1369 if (n < 0)
1370 {
1371 return error(GL_INVALID_VALUE);
1372 }
1373
1374 gl::Context *context = gl::getContext();
1375
1376 if (context)
1377 {
1378 for (int i = 0; i < n; i++)
1379 {
1380 if (framebuffers[i] != 0)
1381 {
1382 context->deleteFramebuffer(framebuffers[i]);
1383 }
1384 }
1385 }
1386 }
1387 catch(std::bad_alloc&)
1388 {
1389 return error(GL_OUT_OF_MEMORY);
1390 }
1391}
1392
1393void __stdcall glDeleteProgram(GLuint program)
1394{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001395 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001396
1397 try
1398 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001399 if (program == 0)
1400 {
1401 return;
1402 }
1403
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001404 gl::Context *context = gl::getContext();
1405
1406 if (context)
1407 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001408 if (!context->getProgram(program))
1409 {
1410 if(context->getShader(program))
1411 {
1412 return error(GL_INVALID_OPERATION);
1413 }
1414 else
1415 {
1416 return error(GL_INVALID_VALUE);
1417 }
1418 }
1419
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001420 context->deleteProgram(program);
1421 }
1422 }
1423 catch(std::bad_alloc&)
1424 {
1425 return error(GL_OUT_OF_MEMORY);
1426 }
1427}
1428
1429void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1430{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001431 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001432
1433 try
1434 {
1435 if (n < 0)
1436 {
1437 return error(GL_INVALID_VALUE);
1438 }
1439
1440 gl::Context *context = gl::getContext();
1441
1442 if (context)
1443 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001444 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001445 {
1446 context->deleteRenderbuffer(renderbuffers[i]);
1447 }
1448 }
1449 }
1450 catch(std::bad_alloc&)
1451 {
1452 return error(GL_OUT_OF_MEMORY);
1453 }
1454}
1455
1456void __stdcall glDeleteShader(GLuint shader)
1457{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001458 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001459
1460 try
1461 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001462 if (shader == 0)
1463 {
1464 return;
1465 }
1466
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001467 gl::Context *context = gl::getContext();
1468
1469 if (context)
1470 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001471 if (!context->getShader(shader))
1472 {
1473 if(context->getProgram(shader))
1474 {
1475 return error(GL_INVALID_OPERATION);
1476 }
1477 else
1478 {
1479 return error(GL_INVALID_VALUE);
1480 }
1481 }
1482
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001483 context->deleteShader(shader);
1484 }
1485 }
1486 catch(std::bad_alloc&)
1487 {
1488 return error(GL_OUT_OF_MEMORY);
1489 }
1490}
1491
1492void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1493{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001494 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001495
1496 try
1497 {
1498 if (n < 0)
1499 {
1500 return error(GL_INVALID_VALUE);
1501 }
1502
1503 gl::Context *context = gl::getContext();
1504
1505 if (context)
1506 {
1507 for (int i = 0; i < n; i++)
1508 {
1509 if (textures[i] != 0)
1510 {
1511 context->deleteTexture(textures[i]);
1512 }
1513 }
1514 }
1515 }
1516 catch(std::bad_alloc&)
1517 {
1518 return error(GL_OUT_OF_MEMORY);
1519 }
1520}
1521
1522void __stdcall glDepthFunc(GLenum func)
1523{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001524 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001525
1526 try
1527 {
1528 switch (func)
1529 {
1530 case GL_NEVER:
1531 case GL_ALWAYS:
1532 case GL_LESS:
1533 case GL_LEQUAL:
1534 case GL_EQUAL:
1535 case GL_GREATER:
1536 case GL_GEQUAL:
1537 case GL_NOTEQUAL:
1538 break;
1539 default:
1540 return error(GL_INVALID_ENUM);
1541 }
1542
1543 gl::Context *context = gl::getContext();
1544
1545 if (context)
1546 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001547 context->setDepthFunc(func);
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 glDepthMask(GLboolean flag)
1557{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001558 TRACE("(GLboolean flag = %d)", flag);
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->setDepthMask(flag != GL_FALSE);
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 glDepthRangef(GLclampf zNear, GLclampf zFar)
1576{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001577 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
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.com428d1582010-05-04 03:35:25 +00001585 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001586 }
1587 }
1588 catch(std::bad_alloc&)
1589 {
1590 return error(GL_OUT_OF_MEMORY);
1591 }
1592}
1593
1594void __stdcall glDetachShader(GLuint program, GLuint shader)
1595{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001596 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001597
1598 try
1599 {
1600 gl::Context *context = gl::getContext();
1601
1602 if (context)
1603 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001604
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001605 gl::Program *programObject = context->getProgram(program);
1606 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001607
1608 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001609 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001610 gl::Shader *shaderByProgramHandle;
1611 shaderByProgramHandle = context->getShader(program);
1612 if (!shaderByProgramHandle)
1613 {
1614 return error(GL_INVALID_VALUE);
1615 }
1616 else
1617 {
1618 return error(GL_INVALID_OPERATION);
1619 }
1620 }
1621
1622 if (!shaderObject)
1623 {
1624 gl::Program *programByShaderHandle = context->getProgram(shader);
1625 if (!programByShaderHandle)
1626 {
1627 return error(GL_INVALID_VALUE);
1628 }
1629 else
1630 {
1631 return error(GL_INVALID_OPERATION);
1632 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001633 }
1634
1635 if (!programObject->detachShader(shaderObject))
1636 {
1637 return error(GL_INVALID_OPERATION);
1638 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001639 }
1640 }
1641 catch(std::bad_alloc&)
1642 {
1643 return error(GL_OUT_OF_MEMORY);
1644 }
1645}
1646
1647void __stdcall glDisable(GLenum cap)
1648{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001649 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001650
1651 try
1652 {
1653 gl::Context *context = gl::getContext();
1654
1655 if (context)
1656 {
1657 switch (cap)
1658 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001659 case GL_CULL_FACE: context->setCullFace(false); break;
1660 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1661 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1662 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1663 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1664 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1665 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1666 case GL_BLEND: context->setBlend(false); break;
1667 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001668 default:
1669 return error(GL_INVALID_ENUM);
1670 }
1671 }
1672 }
1673 catch(std::bad_alloc&)
1674 {
1675 return error(GL_OUT_OF_MEMORY);
1676 }
1677}
1678
1679void __stdcall glDisableVertexAttribArray(GLuint index)
1680{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001681 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001682
1683 try
1684 {
1685 if (index >= gl::MAX_VERTEX_ATTRIBS)
1686 {
1687 return error(GL_INVALID_VALUE);
1688 }
1689
1690 gl::Context *context = gl::getContext();
1691
1692 if (context)
1693 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001694 context->setVertexAttribEnabled(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001695 }
1696 }
1697 catch(std::bad_alloc&)
1698 {
1699 return error(GL_OUT_OF_MEMORY);
1700 }
1701}
1702
1703void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1704{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001705 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001706
1707 try
1708 {
1709 if (count < 0 || first < 0)
1710 {
1711 return error(GL_INVALID_VALUE);
1712 }
1713
1714 gl::Context *context = gl::getContext();
1715
1716 if (context)
1717 {
1718 context->drawArrays(mode, first, count);
1719 }
1720 }
1721 catch(std::bad_alloc&)
1722 {
1723 return error(GL_OUT_OF_MEMORY);
1724 }
1725}
1726
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001727void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001728{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001729 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 +00001730 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001731
1732 try
1733 {
1734 if (count < 0)
1735 {
1736 return error(GL_INVALID_VALUE);
1737 }
1738
1739 switch (type)
1740 {
1741 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001742 case GL_UNSIGNED_SHORT:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00001743 case GL_UNSIGNED_INT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001744 break;
1745 default:
1746 return error(GL_INVALID_ENUM);
1747 }
1748
1749 gl::Context *context = gl::getContext();
1750
1751 if (context)
1752 {
1753 context->drawElements(mode, count, type, indices);
1754 }
1755 }
1756 catch(std::bad_alloc&)
1757 {
1758 return error(GL_OUT_OF_MEMORY);
1759 }
1760}
1761
1762void __stdcall glEnable(GLenum cap)
1763{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001764 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001765
1766 try
1767 {
1768 gl::Context *context = gl::getContext();
1769
1770 if (context)
1771 {
1772 switch (cap)
1773 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001774 case GL_CULL_FACE: context->setCullFace(true); break;
1775 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1776 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1777 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1778 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1779 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1780 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1781 case GL_BLEND: context->setBlend(true); break;
1782 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001783 default:
1784 return error(GL_INVALID_ENUM);
1785 }
1786 }
1787 }
1788 catch(std::bad_alloc&)
1789 {
1790 return error(GL_OUT_OF_MEMORY);
1791 }
1792}
1793
1794void __stdcall glEnableVertexAttribArray(GLuint index)
1795{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001796 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001797
1798 try
1799 {
1800 if (index >= gl::MAX_VERTEX_ATTRIBS)
1801 {
1802 return error(GL_INVALID_VALUE);
1803 }
1804
1805 gl::Context *context = gl::getContext();
1806
1807 if (context)
1808 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001809 context->setVertexAttribEnabled(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001810 }
1811 }
1812 catch(std::bad_alloc&)
1813 {
1814 return error(GL_OUT_OF_MEMORY);
1815 }
1816}
1817
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00001818void __stdcall glFinishFenceNV(GLuint fence)
1819{
1820 TRACE("(GLuint fence = %d)", fence);
1821
1822 try
1823 {
1824 gl::Context *context = gl::getContext();
1825
1826 if (context)
1827 {
1828 gl::Fence* fenceObject = context->getFence(fence);
1829
1830 if (fenceObject == NULL)
1831 {
1832 return error(GL_INVALID_OPERATION);
1833 }
1834
1835 fenceObject->finishFence();
1836 }
1837 }
1838 catch(std::bad_alloc&)
1839 {
1840 return error(GL_OUT_OF_MEMORY);
1841 }
1842}
1843
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001844void __stdcall glFinish(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->finish();
1855 }
1856 }
1857 catch(std::bad_alloc&)
1858 {
1859 return error(GL_OUT_OF_MEMORY);
1860 }
1861}
1862
1863void __stdcall glFlush(void)
1864{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001865 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001866
1867 try
1868 {
1869 gl::Context *context = gl::getContext();
1870
1871 if (context)
1872 {
1873 context->flush();
1874 }
1875 }
1876 catch(std::bad_alloc&)
1877 {
1878 return error(GL_OUT_OF_MEMORY);
1879 }
1880}
1881
1882void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1883{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001884 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1885 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001886
1887 try
1888 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001889 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1890 || renderbuffertarget != GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001891 {
1892 return error(GL_INVALID_ENUM);
1893 }
1894
1895 gl::Context *context = gl::getContext();
1896
1897 if (context)
1898 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001899 gl::Framebuffer *framebuffer = NULL;
1900 GLuint framebufferHandle = 0;
1901 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1902 {
1903 framebuffer = context->getReadFramebuffer();
1904 framebufferHandle = context->getReadFramebufferHandle();
1905 }
1906 else
1907 {
1908 framebuffer = context->getDrawFramebuffer();
1909 framebufferHandle = context->getDrawFramebufferHandle();
1910 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001911
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001912 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001913 {
1914 return error(GL_INVALID_OPERATION);
1915 }
1916
1917 switch (attachment)
1918 {
1919 case GL_COLOR_ATTACHMENT0:
1920 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1921 break;
1922 case GL_DEPTH_ATTACHMENT:
1923 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1924 break;
1925 case GL_STENCIL_ATTACHMENT:
1926 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1927 break;
1928 default:
1929 return error(GL_INVALID_ENUM);
1930 }
1931 }
1932 }
1933 catch(std::bad_alloc&)
1934 {
1935 return error(GL_OUT_OF_MEMORY);
1936 }
1937}
1938
1939void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1940{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001941 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1942 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001943
1944 try
1945 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001946 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001947 {
1948 return error(GL_INVALID_ENUM);
1949 }
1950
1951 switch (attachment)
1952 {
1953 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001954 case GL_DEPTH_ATTACHMENT:
1955 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001956 break;
1957 default:
1958 return error(GL_INVALID_ENUM);
1959 }
1960
1961 gl::Context *context = gl::getContext();
1962
1963 if (context)
1964 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001965 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001966 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001967 textarget = GL_NONE;
1968 }
1969 else
1970 {
1971 gl::Texture *tex = context->getTexture(texture);
1972
1973 if (tex == NULL)
1974 {
1975 return error(GL_INVALID_OPERATION);
1976 }
1977
daniel@transgaming.com01868132010-08-24 19:21:17 +00001978 if (tex->isCompressed())
1979 {
1980 return error(GL_INVALID_OPERATION);
1981 }
1982
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001983 switch (textarget)
1984 {
1985 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001986 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001987 {
1988 return error(GL_INVALID_OPERATION);
1989 }
1990 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001991
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001992 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001993 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001994 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001995 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001996 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001997 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001998 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1999 {
2000 return error(GL_INVALID_OPERATION);
2001 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002002 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00002003
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002004 default:
2005 return error(GL_INVALID_ENUM);
2006 }
2007
2008 if (level != 0)
2009 {
2010 return error(GL_INVALID_VALUE);
2011 }
2012 }
2013
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002014 gl::Framebuffer *framebuffer = NULL;
2015 GLuint framebufferHandle = 0;
2016 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2017 {
2018 framebuffer = context->getReadFramebuffer();
2019 framebufferHandle = context->getReadFramebufferHandle();
2020 }
2021 else
2022 {
2023 framebuffer = context->getDrawFramebuffer();
2024 framebufferHandle = context->getDrawFramebufferHandle();
2025 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002026
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002027 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002028 {
2029 return error(GL_INVALID_OPERATION);
2030 }
2031
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002032 switch (attachment)
2033 {
2034 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
2035 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
2036 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2037 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002038 }
2039 }
2040 catch(std::bad_alloc&)
2041 {
2042 return error(GL_OUT_OF_MEMORY);
2043 }
2044}
2045
2046void __stdcall glFrontFace(GLenum mode)
2047{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002048 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002049
2050 try
2051 {
2052 switch (mode)
2053 {
2054 case GL_CW:
2055 case GL_CCW:
2056 {
2057 gl::Context *context = gl::getContext();
2058
2059 if (context)
2060 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002061 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002062 }
2063 }
2064 break;
2065 default:
2066 return error(GL_INVALID_ENUM);
2067 }
2068 }
2069 catch(std::bad_alloc&)
2070 {
2071 return error(GL_OUT_OF_MEMORY);
2072 }
2073}
2074
2075void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2076{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002077 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002078
2079 try
2080 {
2081 if (n < 0)
2082 {
2083 return error(GL_INVALID_VALUE);
2084 }
2085
2086 gl::Context *context = gl::getContext();
2087
2088 if (context)
2089 {
2090 for (int i = 0; i < n; i++)
2091 {
2092 buffers[i] = context->createBuffer();
2093 }
2094 }
2095 }
2096 catch(std::bad_alloc&)
2097 {
2098 return error(GL_OUT_OF_MEMORY);
2099 }
2100}
2101
2102void __stdcall glGenerateMipmap(GLenum target)
2103{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002104 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002105
2106 try
2107 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002108 gl::Context *context = gl::getContext();
2109
2110 if (context)
2111 {
2112 gl::Texture *texture;
2113
2114 switch (target)
2115 {
2116 case GL_TEXTURE_2D:
2117 texture = context->getTexture2D();
2118 break;
2119
2120 case GL_TEXTURE_CUBE_MAP:
2121 texture = context->getTextureCubeMap();
2122 break;
2123
2124 default:
2125 return error(GL_INVALID_ENUM);
2126 }
2127
daniel@transgaming.com01868132010-08-24 19:21:17 +00002128 if (texture->isCompressed())
2129 {
2130 return error(GL_INVALID_OPERATION);
2131 }
2132
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002133 texture->generateMipmaps();
2134 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002135 }
2136 catch(std::bad_alloc&)
2137 {
2138 return error(GL_OUT_OF_MEMORY);
2139 }
2140}
2141
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002142void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2143{
2144 TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
2145
2146 try
2147 {
2148 if (n < 0)
2149 {
2150 return error(GL_INVALID_VALUE);
2151 }
2152
2153 gl::Context *context = gl::getContext();
2154
2155 if (context)
2156 {
2157 for (int i = 0; i < n; i++)
2158 {
2159 fences[i] = context->createFence();
2160 }
2161 }
2162 }
2163 catch(std::bad_alloc&)
2164 {
2165 return error(GL_OUT_OF_MEMORY);
2166 }
2167}
2168
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002169void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2170{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002171 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002172
2173 try
2174 {
2175 if (n < 0)
2176 {
2177 return error(GL_INVALID_VALUE);
2178 }
2179
2180 gl::Context *context = gl::getContext();
2181
2182 if (context)
2183 {
2184 for (int i = 0; i < n; i++)
2185 {
2186 framebuffers[i] = context->createFramebuffer();
2187 }
2188 }
2189 }
2190 catch(std::bad_alloc&)
2191 {
2192 return error(GL_OUT_OF_MEMORY);
2193 }
2194}
2195
2196void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2197{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002198 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002199
2200 try
2201 {
2202 if (n < 0)
2203 {
2204 return error(GL_INVALID_VALUE);
2205 }
2206
2207 gl::Context *context = gl::getContext();
2208
2209 if (context)
2210 {
2211 for (int i = 0; i < n; i++)
2212 {
2213 renderbuffers[i] = context->createRenderbuffer();
2214 }
2215 }
2216 }
2217 catch(std::bad_alloc&)
2218 {
2219 return error(GL_OUT_OF_MEMORY);
2220 }
2221}
2222
2223void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2224{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002225 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002226
2227 try
2228 {
2229 if (n < 0)
2230 {
2231 return error(GL_INVALID_VALUE);
2232 }
2233
2234 gl::Context *context = gl::getContext();
2235
2236 if (context)
2237 {
2238 for (int i = 0; i < n; i++)
2239 {
2240 textures[i] = context->createTexture();
2241 }
2242 }
2243 }
2244 catch(std::bad_alloc&)
2245 {
2246 return error(GL_OUT_OF_MEMORY);
2247 }
2248}
2249
daniel@transgaming.com85423182010-04-22 13:35:27 +00002250void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002251{
daniel@transgaming.com85423182010-04-22 13:35:27 +00002252 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2253 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002254 program, index, bufsize, length, size, type, name);
2255
2256 try
2257 {
2258 if (bufsize < 0)
2259 {
2260 return error(GL_INVALID_VALUE);
2261 }
2262
daniel@transgaming.com85423182010-04-22 13:35:27 +00002263 gl::Context *context = gl::getContext();
2264
2265 if (context)
2266 {
2267 gl::Program *programObject = context->getProgram(program);
2268
2269 if (!programObject)
2270 {
2271 if (context->getShader(program))
2272 {
2273 return error(GL_INVALID_OPERATION);
2274 }
2275 else
2276 {
2277 return error(GL_INVALID_VALUE);
2278 }
2279 }
2280
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002281 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002282 {
2283 return error(GL_INVALID_VALUE);
2284 }
2285
2286 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2287 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002288 }
2289 catch(std::bad_alloc&)
2290 {
2291 return error(GL_OUT_OF_MEMORY);
2292 }
2293}
2294
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002295void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002296{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002297 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002298 "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 +00002299 program, index, bufsize, length, size, type, name);
2300
2301 try
2302 {
2303 if (bufsize < 0)
2304 {
2305 return error(GL_INVALID_VALUE);
2306 }
2307
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002308 gl::Context *context = gl::getContext();
2309
2310 if (context)
2311 {
2312 gl::Program *programObject = context->getProgram(program);
2313
2314 if (!programObject)
2315 {
2316 if (context->getShader(program))
2317 {
2318 return error(GL_INVALID_OPERATION);
2319 }
2320 else
2321 {
2322 return error(GL_INVALID_VALUE);
2323 }
2324 }
2325
2326 if (index >= (GLuint)programObject->getActiveUniformCount())
2327 {
2328 return error(GL_INVALID_VALUE);
2329 }
2330
2331 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2332 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002333 }
2334 catch(std::bad_alloc&)
2335 {
2336 return error(GL_OUT_OF_MEMORY);
2337 }
2338}
2339
2340void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2341{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002342 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2343 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002344
2345 try
2346 {
2347 if (maxcount < 0)
2348 {
2349 return error(GL_INVALID_VALUE);
2350 }
2351
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002352 gl::Context *context = gl::getContext();
2353
2354 if (context)
2355 {
2356 gl::Program *programObject = context->getProgram(program);
2357
2358 if (!programObject)
2359 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002360 if (context->getShader(program))
2361 {
2362 return error(GL_INVALID_OPERATION);
2363 }
2364 else
2365 {
2366 return error(GL_INVALID_VALUE);
2367 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002368 }
2369
2370 return programObject->getAttachedShaders(maxcount, count, shaders);
2371 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002372 }
2373 catch(std::bad_alloc&)
2374 {
2375 return error(GL_OUT_OF_MEMORY);
2376 }
2377}
2378
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002379int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002380{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002381 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002382
2383 try
2384 {
2385 gl::Context *context = gl::getContext();
2386
2387 if (context)
2388 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002389
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002390 gl::Program *programObject = context->getProgram(program);
2391
2392 if (!programObject)
2393 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002394 if (context->getShader(program))
2395 {
2396 return error(GL_INVALID_OPERATION, -1);
2397 }
2398 else
2399 {
2400 return error(GL_INVALID_VALUE, -1);
2401 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002402 }
2403
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002404 if (!programObject->isLinked())
2405 {
2406 return error(GL_INVALID_OPERATION, -1);
2407 }
2408
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002409 return programObject->getAttributeLocation(name);
2410 }
2411 }
2412 catch(std::bad_alloc&)
2413 {
2414 return error(GL_OUT_OF_MEMORY, -1);
2415 }
2416
2417 return -1;
2418}
2419
2420void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2421{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002422 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002423
2424 try
2425 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002426 gl::Context *context = gl::getContext();
2427
2428 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002429 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002430 if (!(context->getBooleanv(pname, params)))
2431 {
2432 GLenum nativeType;
2433 unsigned int numParams = 0;
2434 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2435 return error(GL_INVALID_ENUM);
2436
2437 if (numParams == 0)
2438 return; // it is known that the pname is valid, but there are no parameters to return
2439
2440 if (nativeType == GL_FLOAT)
2441 {
2442 GLfloat *floatParams = NULL;
2443 floatParams = new GLfloat[numParams];
2444
2445 context->getFloatv(pname, floatParams);
2446
2447 for (unsigned int i = 0; i < numParams; ++i)
2448 {
2449 if (floatParams[i] == 0.0f)
2450 params[i] = GL_FALSE;
2451 else
2452 params[i] = GL_TRUE;
2453 }
2454
2455 delete [] floatParams;
2456 }
2457 else if (nativeType == GL_INT)
2458 {
2459 GLint *intParams = NULL;
2460 intParams = new GLint[numParams];
2461
2462 context->getIntegerv(pname, intParams);
2463
2464 for (unsigned int i = 0; i < numParams; ++i)
2465 {
2466 if (intParams[i] == 0)
2467 params[i] = GL_FALSE;
2468 else
2469 params[i] = GL_TRUE;
2470 }
2471
2472 delete [] intParams;
2473 }
2474 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002475 }
2476 }
2477 catch(std::bad_alloc&)
2478 {
2479 return error(GL_OUT_OF_MEMORY);
2480 }
2481}
2482
2483void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2484{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002485 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 +00002486
2487 try
2488 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002489 gl::Context *context = gl::getContext();
2490
2491 if (context)
2492 {
2493 gl::Buffer *buffer;
2494
2495 switch (target)
2496 {
2497 case GL_ARRAY_BUFFER:
2498 buffer = context->getArrayBuffer();
2499 break;
2500 case GL_ELEMENT_ARRAY_BUFFER:
2501 buffer = context->getElementArrayBuffer();
2502 break;
2503 default: return error(GL_INVALID_ENUM);
2504 }
2505
2506 if (!buffer)
2507 {
2508 // A null buffer means that "0" is bound to the requested buffer target
2509 return error(GL_INVALID_OPERATION);
2510 }
2511
2512 switch (pname)
2513 {
2514 case GL_BUFFER_USAGE:
2515 *params = buffer->usage();
2516 break;
2517 case GL_BUFFER_SIZE:
2518 *params = buffer->size();
2519 break;
2520 default: return error(GL_INVALID_ENUM);
2521 }
2522 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002523 }
2524 catch(std::bad_alloc&)
2525 {
2526 return error(GL_OUT_OF_MEMORY);
2527 }
2528}
2529
2530GLenum __stdcall glGetError(void)
2531{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002532 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002533
2534 gl::Context *context = gl::getContext();
2535
2536 if (context)
2537 {
2538 return context->getError();
2539 }
2540
2541 return GL_NO_ERROR;
2542}
2543
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00002544void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2545{
2546 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
2547
2548 try
2549 {
2550
2551 gl::Context *context = gl::getContext();
2552
2553 if (context)
2554 {
2555 gl::Fence *fenceObject = context->getFence(fence);
2556
2557 if (fenceObject == NULL)
2558 {
2559 return error(GL_INVALID_OPERATION);
2560 }
2561
2562 fenceObject->getFenceiv(pname, params);
2563 }
2564 }
2565 catch(std::bad_alloc&)
2566 {
2567 return error(GL_OUT_OF_MEMORY);
2568 }
2569}
2570
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002571void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2572{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002573 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002574
2575 try
2576 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002577 gl::Context *context = gl::getContext();
2578
2579 if (context)
2580 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002581 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002582 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002583 GLenum nativeType;
2584 unsigned int numParams = 0;
2585 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2586 return error(GL_INVALID_ENUM);
2587
2588 if (numParams == 0)
2589 return; // it is known that the pname is valid, but that there are no parameters to return.
2590
2591 if (nativeType == GL_BOOL)
2592 {
2593 GLboolean *boolParams = NULL;
2594 boolParams = new GLboolean[numParams];
2595
2596 context->getBooleanv(pname, boolParams);
2597
2598 for (unsigned int i = 0; i < numParams; ++i)
2599 {
2600 if (boolParams[i] == GL_FALSE)
2601 params[i] = 0.0f;
2602 else
2603 params[i] = 1.0f;
2604 }
2605
2606 delete [] boolParams;
2607 }
2608 else if (nativeType == GL_INT)
2609 {
2610 GLint *intParams = NULL;
2611 intParams = new GLint[numParams];
2612
2613 context->getIntegerv(pname, intParams);
2614
2615 for (unsigned int i = 0; i < numParams; ++i)
2616 {
2617 params[i] = (GLfloat)intParams[i];
2618 }
2619
2620 delete [] intParams;
2621 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002622 }
2623 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002624 }
2625 catch(std::bad_alloc&)
2626 {
2627 return error(GL_OUT_OF_MEMORY);
2628 }
2629}
2630
2631void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2632{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002633 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2634 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002635
2636 try
2637 {
2638 gl::Context *context = gl::getContext();
2639
2640 if (context)
2641 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002642 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002643 {
2644 return error(GL_INVALID_ENUM);
2645 }
2646
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002647 gl::Framebuffer *framebuffer = NULL;
2648 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2649 {
2650 if(context->getReadFramebufferHandle() == 0)
2651 {
2652 return error(GL_INVALID_OPERATION);
2653 }
2654
2655 framebuffer = context->getReadFramebuffer();
2656 }
2657 else
2658 {
2659 if (context->getDrawFramebufferHandle() == 0)
2660 {
2661 return error(GL_INVALID_OPERATION);
2662 }
2663
2664 framebuffer = context->getDrawFramebuffer();
2665 }
2666
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002667 GLenum attachmentType;
2668 GLuint attachmentHandle;
2669 switch (attachment)
2670 {
2671 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002672 attachmentType = framebuffer->getColorbufferType();
2673 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002674 break;
2675 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002676 attachmentType = framebuffer->getDepthbufferType();
2677 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002678 break;
2679 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002680 attachmentType = framebuffer->getStencilbufferType();
2681 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002682 break;
2683 default: return error(GL_INVALID_ENUM);
2684 }
2685
2686 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002687 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002688 {
2689 attachmentObjectType = attachmentType;
2690 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002691 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002692 {
2693 attachmentObjectType = GL_TEXTURE;
2694 }
2695 else UNREACHABLE();
2696
2697 switch (pname)
2698 {
2699 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2700 *params = attachmentObjectType;
2701 break;
2702 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2703 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2704 {
2705 *params = attachmentHandle;
2706 }
2707 else
2708 {
2709 return error(GL_INVALID_ENUM);
2710 }
2711 break;
2712 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2713 if (attachmentObjectType == GL_TEXTURE)
2714 {
2715 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2716 }
2717 else
2718 {
2719 return error(GL_INVALID_ENUM);
2720 }
2721 break;
2722 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2723 if (attachmentObjectType == GL_TEXTURE)
2724 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002725 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002726 {
2727 *params = attachmentType;
2728 }
2729 else
2730 {
2731 *params = 0;
2732 }
2733 }
2734 else
2735 {
2736 return error(GL_INVALID_ENUM);
2737 }
2738 break;
2739 default:
2740 return error(GL_INVALID_ENUM);
2741 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002742 }
2743 }
2744 catch(std::bad_alloc&)
2745 {
2746 return error(GL_OUT_OF_MEMORY);
2747 }
2748}
2749
2750void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2751{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002752 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002753
2754 try
2755 {
2756 gl::Context *context = gl::getContext();
2757
2758 if (context)
2759 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002760 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002761 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002762 GLenum nativeType;
2763 unsigned int numParams = 0;
2764 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2765 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002766
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002767 if (numParams == 0)
2768 return; // it is known that pname is valid, but there are no parameters to return
2769
2770 if (nativeType == GL_BOOL)
2771 {
2772 GLboolean *boolParams = NULL;
2773 boolParams = new GLboolean[numParams];
2774
2775 context->getBooleanv(pname, boolParams);
2776
2777 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002778 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002779 if (boolParams[i] == GL_FALSE)
2780 params[i] = 0;
2781 else
2782 params[i] = 1;
2783 }
2784
2785 delete [] boolParams;
2786 }
2787 else if (nativeType == GL_FLOAT)
2788 {
2789 GLfloat *floatParams = NULL;
2790 floatParams = new GLfloat[numParams];
2791
2792 context->getFloatv(pname, floatParams);
2793
2794 for (unsigned int i = 0; i < numParams; ++i)
2795 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002796 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 +00002797 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002798 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002799 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002800 else
2801 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 +00002802 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002803
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002804 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002805 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002806 }
2807 }
2808 }
2809 catch(std::bad_alloc&)
2810 {
2811 return error(GL_OUT_OF_MEMORY);
2812 }
2813}
2814
2815void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2816{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002817 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002818
2819 try
2820 {
2821 gl::Context *context = gl::getContext();
2822
2823 if (context)
2824 {
2825 gl::Program *programObject = context->getProgram(program);
2826
2827 if (!programObject)
2828 {
2829 return error(GL_INVALID_VALUE);
2830 }
2831
2832 switch (pname)
2833 {
2834 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002835 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002836 return;
2837 case GL_LINK_STATUS:
2838 *params = programObject->isLinked();
2839 return;
2840 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002841 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002842 return;
2843 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002844 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002845 return;
2846 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002847 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002848 return;
2849 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002850 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002851 return;
2852 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002853 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002854 return;
2855 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002856 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002857 return;
2858 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002859 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002860 return;
2861 default:
2862 return error(GL_INVALID_ENUM);
2863 }
2864 }
2865 }
2866 catch(std::bad_alloc&)
2867 {
2868 return error(GL_OUT_OF_MEMORY);
2869 }
2870}
2871
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002872void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002873{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002874 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 +00002875 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002876
2877 try
2878 {
2879 if (bufsize < 0)
2880 {
2881 return error(GL_INVALID_VALUE);
2882 }
2883
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002884 gl::Context *context = gl::getContext();
2885
2886 if (context)
2887 {
2888 gl::Program *programObject = context->getProgram(program);
2889
2890 if (!programObject)
2891 {
2892 return error(GL_INVALID_VALUE);
2893 }
2894
2895 programObject->getInfoLog(bufsize, length, infolog);
2896 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002897 }
2898 catch(std::bad_alloc&)
2899 {
2900 return error(GL_OUT_OF_MEMORY);
2901 }
2902}
2903
2904void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2905{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002906 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 +00002907
2908 try
2909 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002910 gl::Context *context = gl::getContext();
2911
2912 if (context)
2913 {
2914 if (target != GL_RENDERBUFFER)
2915 {
2916 return error(GL_INVALID_ENUM);
2917 }
2918
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002919 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002920 {
2921 return error(GL_INVALID_OPERATION);
2922 }
2923
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002924 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002925
2926 switch (pname)
2927 {
2928 case GL_RENDERBUFFER_WIDTH:
2929 *params = renderbuffer->getWidth();
2930 break;
2931 case GL_RENDERBUFFER_HEIGHT:
2932 *params = renderbuffer->getHeight();
2933 break;
2934 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2935 *params = renderbuffer->getFormat();
2936 break;
2937 case GL_RENDERBUFFER_RED_SIZE:
2938 if (renderbuffer->isColorbuffer())
2939 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002940 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002941 }
2942 else
2943 {
2944 *params = 0;
2945 }
2946 break;
2947 case GL_RENDERBUFFER_GREEN_SIZE:
2948 if (renderbuffer->isColorbuffer())
2949 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002950 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002951 }
2952 else
2953 {
2954 *params = 0;
2955 }
2956 break;
2957 case GL_RENDERBUFFER_BLUE_SIZE:
2958 if (renderbuffer->isColorbuffer())
2959 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002960 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002961 }
2962 else
2963 {
2964 *params = 0;
2965 }
2966 break;
2967 case GL_RENDERBUFFER_ALPHA_SIZE:
2968 if (renderbuffer->isColorbuffer())
2969 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002970 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002971 }
2972 else
2973 {
2974 *params = 0;
2975 }
2976 break;
2977 case GL_RENDERBUFFER_DEPTH_SIZE:
2978 if (renderbuffer->isDepthbuffer())
2979 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002980 *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002981 }
2982 else
2983 {
2984 *params = 0;
2985 }
2986 break;
2987 case GL_RENDERBUFFER_STENCIL_SIZE:
2988 if (renderbuffer->isStencilbuffer())
2989 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002990 *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002991 }
2992 else
2993 {
2994 *params = 0;
2995 }
2996 break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002997 case GL_RENDERBUFFER_SAMPLES_ANGLE:
2998 {
2999 if (context->getMaxSupportedSamples() != 0)
3000 {
3001 *params = renderbuffer->getStorage()->getSamples();
3002 }
3003 else
3004 {
3005 return error(GL_INVALID_ENUM);
3006 }
3007 }
3008 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00003009 default:
3010 return error(GL_INVALID_ENUM);
3011 }
3012 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003013 }
3014 catch(std::bad_alloc&)
3015 {
3016 return error(GL_OUT_OF_MEMORY);
3017 }
3018}
3019
3020void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3021{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003022 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003023
3024 try
3025 {
3026 gl::Context *context = gl::getContext();
3027
3028 if (context)
3029 {
3030 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003031
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003032 if (!shaderObject)
3033 {
3034 return error(GL_INVALID_VALUE);
3035 }
3036
3037 switch (pname)
3038 {
3039 case GL_SHADER_TYPE:
3040 *params = shaderObject->getType();
3041 return;
3042 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003043 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003044 return;
3045 case GL_COMPILE_STATUS:
3046 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3047 return;
3048 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003049 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003050 return;
3051 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003052 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003053 return;
3054 default:
3055 return error(GL_INVALID_ENUM);
3056 }
3057 }
3058 }
3059 catch(std::bad_alloc&)
3060 {
3061 return error(GL_OUT_OF_MEMORY);
3062 }
3063}
3064
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003065void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003066{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003067 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 +00003068 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003069
3070 try
3071 {
3072 if (bufsize < 0)
3073 {
3074 return error(GL_INVALID_VALUE);
3075 }
3076
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003077 gl::Context *context = gl::getContext();
3078
3079 if (context)
3080 {
3081 gl::Shader *shaderObject = context->getShader(shader);
3082
3083 if (!shaderObject)
3084 {
3085 return error(GL_INVALID_VALUE);
3086 }
3087
3088 shaderObject->getInfoLog(bufsize, length, infolog);
3089 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003090 }
3091 catch(std::bad_alloc&)
3092 {
3093 return error(GL_OUT_OF_MEMORY);
3094 }
3095}
3096
3097void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3098{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003099 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
3100 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003101
3102 try
3103 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003104 switch (shadertype)
3105 {
3106 case GL_VERTEX_SHADER:
3107 case GL_FRAGMENT_SHADER:
3108 break;
3109 default:
3110 return error(GL_INVALID_ENUM);
3111 }
3112
3113 switch (precisiontype)
3114 {
3115 case GL_LOW_FLOAT:
3116 case GL_MEDIUM_FLOAT:
3117 case GL_HIGH_FLOAT:
3118 // Assume IEEE 754 precision
3119 range[0] = 127;
3120 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003121 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003122 break;
3123 case GL_LOW_INT:
3124 case GL_MEDIUM_INT:
3125 case GL_HIGH_INT:
3126 // Some (most) hardware only supports single-precision floating-point numbers,
3127 // which can accurately represent integers up to +/-16777216
3128 range[0] = 24;
3129 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003130 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003131 break;
3132 default:
3133 return error(GL_INVALID_ENUM);
3134 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003135 }
3136 catch(std::bad_alloc&)
3137 {
3138 return error(GL_OUT_OF_MEMORY);
3139 }
3140}
3141
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003142void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003143{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003144 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 +00003145 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003146
3147 try
3148 {
3149 if (bufsize < 0)
3150 {
3151 return error(GL_INVALID_VALUE);
3152 }
3153
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003154 gl::Context *context = gl::getContext();
3155
3156 if (context)
3157 {
3158 gl::Shader *shaderObject = context->getShader(shader);
3159
3160 if (!shaderObject)
3161 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003162 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003163 }
3164
3165 shaderObject->getSource(bufsize, length, source);
3166 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003167 }
3168 catch(std::bad_alloc&)
3169 {
3170 return error(GL_OUT_OF_MEMORY);
3171 }
3172}
3173
3174const GLubyte* __stdcall glGetString(GLenum name)
3175{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003176 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003177
3178 try
3179 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003180 gl::Context *context = gl::getContext();
3181
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003182 switch (name)
3183 {
3184 case GL_VENDOR:
3185 return (GLubyte*)"TransGaming Inc.";
3186 case GL_RENDERER:
3187 return (GLubyte*)"ANGLE";
3188 case GL_VERSION:
3189 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
3190 case GL_SHADING_LANGUAGE_VERSION:
3191 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
3192 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003193 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003194 default:
3195 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3196 }
3197 }
3198 catch(std::bad_alloc&)
3199 {
3200 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3201 }
3202
3203 return NULL;
3204}
3205
3206void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3207{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003208 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 +00003209
3210 try
3211 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003212 gl::Context *context = gl::getContext();
3213
3214 if (context)
3215 {
3216 gl::Texture *texture;
3217
3218 switch (target)
3219 {
3220 case GL_TEXTURE_2D:
3221 texture = context->getTexture2D();
3222 break;
3223 case GL_TEXTURE_CUBE_MAP:
3224 texture = context->getTextureCubeMap();
3225 break;
3226 default:
3227 return error(GL_INVALID_ENUM);
3228 }
3229
3230 switch (pname)
3231 {
3232 case GL_TEXTURE_MAG_FILTER:
3233 *params = (GLfloat)texture->getMagFilter();
3234 break;
3235 case GL_TEXTURE_MIN_FILTER:
3236 *params = (GLfloat)texture->getMinFilter();
3237 break;
3238 case GL_TEXTURE_WRAP_S:
3239 *params = (GLfloat)texture->getWrapS();
3240 break;
3241 case GL_TEXTURE_WRAP_T:
3242 *params = (GLfloat)texture->getWrapT();
3243 break;
3244 default:
3245 return error(GL_INVALID_ENUM);
3246 }
3247 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003248 }
3249 catch(std::bad_alloc&)
3250 {
3251 return error(GL_OUT_OF_MEMORY);
3252 }
3253}
3254
3255void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3256{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003257 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 +00003258
3259 try
3260 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003261 gl::Context *context = gl::getContext();
3262
3263 if (context)
3264 {
3265 gl::Texture *texture;
3266
3267 switch (target)
3268 {
3269 case GL_TEXTURE_2D:
3270 texture = context->getTexture2D();
3271 break;
3272 case GL_TEXTURE_CUBE_MAP:
3273 texture = context->getTextureCubeMap();
3274 break;
3275 default:
3276 return error(GL_INVALID_ENUM);
3277 }
3278
3279 switch (pname)
3280 {
3281 case GL_TEXTURE_MAG_FILTER:
3282 *params = texture->getMagFilter();
3283 break;
3284 case GL_TEXTURE_MIN_FILTER:
3285 *params = texture->getMinFilter();
3286 break;
3287 case GL_TEXTURE_WRAP_S:
3288 *params = texture->getWrapS();
3289 break;
3290 case GL_TEXTURE_WRAP_T:
3291 *params = texture->getWrapT();
3292 break;
3293 default:
3294 return error(GL_INVALID_ENUM);
3295 }
3296 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003297 }
3298 catch(std::bad_alloc&)
3299 {
3300 return error(GL_OUT_OF_MEMORY);
3301 }
3302}
3303
3304void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3305{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003306 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003307
3308 try
3309 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003310 gl::Context *context = gl::getContext();
3311
3312 if (context)
3313 {
3314 if (program == 0)
3315 {
3316 return error(GL_INVALID_VALUE);
3317 }
3318
3319 gl::Program *programObject = context->getProgram(program);
3320
3321 if (!programObject || !programObject->isLinked())
3322 {
3323 return error(GL_INVALID_OPERATION);
3324 }
3325
3326 if (!programObject->getUniformfv(location, params))
3327 {
3328 return error(GL_INVALID_OPERATION);
3329 }
3330 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003331 }
3332 catch(std::bad_alloc&)
3333 {
3334 return error(GL_OUT_OF_MEMORY);
3335 }
3336}
3337
3338void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3339{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003340 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003341
3342 try
3343 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003344 gl::Context *context = gl::getContext();
3345
3346 if (context)
3347 {
3348 if (program == 0)
3349 {
3350 return error(GL_INVALID_VALUE);
3351 }
3352
3353 gl::Program *programObject = context->getProgram(program);
3354
3355 if (!programObject || !programObject->isLinked())
3356 {
3357 return error(GL_INVALID_OPERATION);
3358 }
3359
3360 if (!programObject)
3361 {
3362 return error(GL_INVALID_OPERATION);
3363 }
3364
3365 if (!programObject->getUniformiv(location, params))
3366 {
3367 return error(GL_INVALID_OPERATION);
3368 }
3369 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003370 }
3371 catch(std::bad_alloc&)
3372 {
3373 return error(GL_OUT_OF_MEMORY);
3374 }
3375}
3376
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003377int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003378{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003379 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003380
3381 try
3382 {
3383 gl::Context *context = gl::getContext();
3384
3385 if (strstr(name, "gl_") == name)
3386 {
3387 return -1;
3388 }
3389
3390 if (context)
3391 {
3392 gl::Program *programObject = context->getProgram(program);
3393
3394 if (!programObject)
3395 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003396 if (context->getShader(program))
3397 {
3398 return error(GL_INVALID_OPERATION, -1);
3399 }
3400 else
3401 {
3402 return error(GL_INVALID_VALUE, -1);
3403 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003404 }
3405
3406 if (!programObject->isLinked())
3407 {
3408 return error(GL_INVALID_OPERATION, -1);
3409 }
3410
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003411 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003412 }
3413 }
3414 catch(std::bad_alloc&)
3415 {
3416 return error(GL_OUT_OF_MEMORY, -1);
3417 }
3418
3419 return -1;
3420}
3421
3422void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3423{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003424 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003425
3426 try
3427 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003428 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003429
daniel@transgaming.come0078962010-04-15 20:45:08 +00003430 if (context)
3431 {
3432 if (index >= gl::MAX_VERTEX_ATTRIBS)
3433 {
3434 return error(GL_INVALID_VALUE);
3435 }
3436
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003437 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003438
daniel@transgaming.come0078962010-04-15 20:45:08 +00003439 switch (pname)
3440 {
3441 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003442 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003443 break;
3444 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003445 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003446 break;
3447 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003448 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003449 break;
3450 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003451 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003452 break;
3453 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003454 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003455 break;
3456 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003457 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003458 break;
3459 case GL_CURRENT_VERTEX_ATTRIB:
3460 for (int i = 0; i < 4; ++i)
3461 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003462 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003463 }
3464 break;
3465 default: return error(GL_INVALID_ENUM);
3466 }
3467 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003468 }
3469 catch(std::bad_alloc&)
3470 {
3471 return error(GL_OUT_OF_MEMORY);
3472 }
3473}
3474
3475void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3476{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003477 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003478
3479 try
3480 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003481 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003482
daniel@transgaming.come0078962010-04-15 20:45:08 +00003483 if (context)
3484 {
3485 if (index >= gl::MAX_VERTEX_ATTRIBS)
3486 {
3487 return error(GL_INVALID_VALUE);
3488 }
3489
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003490 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003491
daniel@transgaming.come0078962010-04-15 20:45:08 +00003492 switch (pname)
3493 {
3494 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003495 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003496 break;
3497 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003498 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003499 break;
3500 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003501 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003502 break;
3503 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003504 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003505 break;
3506 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003507 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003508 break;
3509 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003510 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003511 break;
3512 case GL_CURRENT_VERTEX_ATTRIB:
3513 for (int i = 0; i < 4; ++i)
3514 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003515 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003516 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3517 }
3518 break;
3519 default: return error(GL_INVALID_ENUM);
3520 }
3521 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003522 }
3523 catch(std::bad_alloc&)
3524 {
3525 return error(GL_OUT_OF_MEMORY);
3526 }
3527}
3528
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003529void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003530{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003531 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003532
3533 try
3534 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003535 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003536
daniel@transgaming.come0078962010-04-15 20:45:08 +00003537 if (context)
3538 {
3539 if (index >= gl::MAX_VERTEX_ATTRIBS)
3540 {
3541 return error(GL_INVALID_VALUE);
3542 }
3543
3544 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3545 {
3546 return error(GL_INVALID_ENUM);
3547 }
3548
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003549 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003550 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003551 }
3552 catch(std::bad_alloc&)
3553 {
3554 return error(GL_OUT_OF_MEMORY);
3555 }
3556}
3557
3558void __stdcall glHint(GLenum target, GLenum mode)
3559{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003560 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003561
3562 try
3563 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003564 switch (mode)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003565 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003566 case GL_FASTEST:
3567 case GL_NICEST:
3568 case GL_DONT_CARE:
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003569 break;
3570 default:
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003571 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003572 }
3573
3574 gl::Context *context = gl::getContext();
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003575 switch (target)
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003576 {
alokp@chromium.orgd303ef92010-09-09 17:30:15 +00003577 case GL_GENERATE_MIPMAP_HINT:
3578 if (context) context->setGenerateMipmapHint(mode);
3579 break;
3580 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3581 if (context) context->setFragmentShaderDerivativeHint(mode);
3582 break;
3583 default:
3584 return error(GL_INVALID_ENUM);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003585 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003586 }
3587 catch(std::bad_alloc&)
3588 {
3589 return error(GL_OUT_OF_MEMORY);
3590 }
3591}
3592
3593GLboolean __stdcall glIsBuffer(GLuint buffer)
3594{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003595 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003596
3597 try
3598 {
3599 gl::Context *context = gl::getContext();
3600
3601 if (context && buffer)
3602 {
3603 gl::Buffer *bufferObject = context->getBuffer(buffer);
3604
3605 if (bufferObject)
3606 {
3607 return GL_TRUE;
3608 }
3609 }
3610 }
3611 catch(std::bad_alloc&)
3612 {
3613 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3614 }
3615
3616 return GL_FALSE;
3617}
3618
3619GLboolean __stdcall glIsEnabled(GLenum cap)
3620{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003621 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003622
3623 try
3624 {
3625 gl::Context *context = gl::getContext();
3626
3627 if (context)
3628 {
3629 switch (cap)
3630 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003631 case GL_CULL_FACE: return context->isCullFaceEnabled();
3632 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3633 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3634 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3635 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3636 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3637 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3638 case GL_BLEND: return context->isBlendEnabled();
3639 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003640 default:
3641 return error(GL_INVALID_ENUM, false);
3642 }
3643 }
3644 }
3645 catch(std::bad_alloc&)
3646 {
3647 return error(GL_OUT_OF_MEMORY, false);
3648 }
3649
3650 return false;
3651}
3652
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003653GLboolean __stdcall glIsFenceNV(GLuint fence)
3654{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003655 TRACE("(GLuint fence = %d)", fence);
3656
3657 try
3658 {
3659 gl::Context *context = gl::getContext();
3660
3661 if (context)
3662 {
3663 gl::Fence *fenceObject = context->getFence(fence);
3664
3665 if (fenceObject == NULL)
3666 {
3667 return GL_FALSE;
3668 }
3669
3670 return fenceObject->isFence();
3671 }
3672 }
3673 catch(std::bad_alloc&)
3674 {
3675 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3676 }
3677
3678 return GL_FALSE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00003679}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00003680
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003681GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3682{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003683 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003684
3685 try
3686 {
3687 gl::Context *context = gl::getContext();
3688
3689 if (context && framebuffer)
3690 {
3691 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3692
3693 if (framebufferObject)
3694 {
3695 return GL_TRUE;
3696 }
3697 }
3698 }
3699 catch(std::bad_alloc&)
3700 {
3701 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3702 }
3703
3704 return GL_FALSE;
3705}
3706
3707GLboolean __stdcall glIsProgram(GLuint program)
3708{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003709 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003710
3711 try
3712 {
3713 gl::Context *context = gl::getContext();
3714
3715 if (context && program)
3716 {
3717 gl::Program *programObject = context->getProgram(program);
3718
3719 if (programObject)
3720 {
3721 return GL_TRUE;
3722 }
3723 }
3724 }
3725 catch(std::bad_alloc&)
3726 {
3727 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3728 }
3729
3730 return GL_FALSE;
3731}
3732
3733GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3734{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003735 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003736
3737 try
3738 {
3739 gl::Context *context = gl::getContext();
3740
3741 if (context && renderbuffer)
3742 {
3743 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3744
3745 if (renderbufferObject)
3746 {
3747 return GL_TRUE;
3748 }
3749 }
3750 }
3751 catch(std::bad_alloc&)
3752 {
3753 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3754 }
3755
3756 return GL_FALSE;
3757}
3758
3759GLboolean __stdcall glIsShader(GLuint shader)
3760{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003761 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003762
3763 try
3764 {
3765 gl::Context *context = gl::getContext();
3766
3767 if (context && shader)
3768 {
3769 gl::Shader *shaderObject = context->getShader(shader);
3770
3771 if (shaderObject)
3772 {
3773 return GL_TRUE;
3774 }
3775 }
3776 }
3777 catch(std::bad_alloc&)
3778 {
3779 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3780 }
3781
3782 return GL_FALSE;
3783}
3784
3785GLboolean __stdcall glIsTexture(GLuint texture)
3786{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003787 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003788
3789 try
3790 {
3791 gl::Context *context = gl::getContext();
3792
3793 if (context && texture)
3794 {
3795 gl::Texture *textureObject = context->getTexture(texture);
3796
3797 if (textureObject)
3798 {
3799 return GL_TRUE;
3800 }
3801 }
3802 }
3803 catch(std::bad_alloc&)
3804 {
3805 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3806 }
3807
3808 return GL_FALSE;
3809}
3810
3811void __stdcall glLineWidth(GLfloat width)
3812{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003813 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003814
3815 try
3816 {
3817 if (width <= 0.0f)
3818 {
3819 return error(GL_INVALID_VALUE);
3820 }
3821
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003822 gl::Context *context = gl::getContext();
3823
3824 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003825 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003826 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003827 }
3828 }
3829 catch(std::bad_alloc&)
3830 {
3831 return error(GL_OUT_OF_MEMORY);
3832 }
3833}
3834
3835void __stdcall glLinkProgram(GLuint program)
3836{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003837 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003838
3839 try
3840 {
3841 gl::Context *context = gl::getContext();
3842
3843 if (context)
3844 {
3845 gl::Program *programObject = context->getProgram(program);
3846
3847 if (!programObject)
3848 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003849 if (context->getShader(program))
3850 {
3851 return error(GL_INVALID_OPERATION);
3852 }
3853 else
3854 {
3855 return error(GL_INVALID_VALUE);
3856 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003857 }
3858
3859 programObject->link();
3860 }
3861 }
3862 catch(std::bad_alloc&)
3863 {
3864 return error(GL_OUT_OF_MEMORY);
3865 }
3866}
3867
3868void __stdcall glPixelStorei(GLenum pname, GLint param)
3869{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003870 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003871
3872 try
3873 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003874 gl::Context *context = gl::getContext();
3875
3876 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003877 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003878 switch (pname)
3879 {
3880 case GL_UNPACK_ALIGNMENT:
3881 if (param != 1 && param != 2 && param != 4 && param != 8)
3882 {
3883 return error(GL_INVALID_VALUE);
3884 }
3885
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003886 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003887 break;
3888
3889 case GL_PACK_ALIGNMENT:
3890 if (param != 1 && param != 2 && param != 4 && param != 8)
3891 {
3892 return error(GL_INVALID_VALUE);
3893 }
3894
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003895 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003896 break;
3897
3898 default:
3899 return error(GL_INVALID_ENUM);
3900 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003901 }
3902 }
3903 catch(std::bad_alloc&)
3904 {
3905 return error(GL_OUT_OF_MEMORY);
3906 }
3907}
3908
3909void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3910{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003911 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003912
3913 try
3914 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003915 gl::Context *context = gl::getContext();
3916
3917 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003918 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003919 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003920 }
3921 }
3922 catch(std::bad_alloc&)
3923 {
3924 return error(GL_OUT_OF_MEMORY);
3925 }
3926}
3927
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003928void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003929{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003930 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003931 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003932 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003933
3934 try
3935 {
3936 if (width < 0 || height < 0)
3937 {
3938 return error(GL_INVALID_VALUE);
3939 }
3940
3941 switch (format)
3942 {
3943 case GL_RGBA:
3944 switch (type)
3945 {
3946 case GL_UNSIGNED_BYTE:
3947 break;
3948 default:
3949 return error(GL_INVALID_OPERATION);
3950 }
3951 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003952 case GL_BGRA_EXT:
3953 switch (type)
3954 {
3955 case GL_UNSIGNED_BYTE:
3956 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3957 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3958 break;
3959 default:
3960 return error(GL_INVALID_OPERATION);
3961 }
3962 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003963 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3964 switch (type)
3965 {
3966 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3967 break;
3968 default:
3969 return error(GL_INVALID_OPERATION);
3970 }
3971 break;
3972 default:
3973 return error(GL_INVALID_OPERATION);
3974 }
3975
3976 gl::Context *context = gl::getContext();
3977
3978 if (context)
3979 {
3980 context->readPixels(x, y, width, height, format, type, pixels);
3981 }
3982 }
3983 catch(std::bad_alloc&)
3984 {
3985 return error(GL_OUT_OF_MEMORY);
3986 }
3987}
3988
3989void __stdcall glReleaseShaderCompiler(void)
3990{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003991 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003992
3993 try
3994 {
3995 gl::Shader::releaseCompiler();
3996 }
3997 catch(std::bad_alloc&)
3998 {
3999 return error(GL_OUT_OF_MEMORY);
4000 }
4001}
4002
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004003void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004004{
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004005 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4006 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004007
4008 try
4009 {
4010 switch (target)
4011 {
4012 case GL_RENDERBUFFER:
4013 break;
4014 default:
4015 return error(GL_INVALID_ENUM);
4016 }
4017
4018 switch (internalformat)
4019 {
4020 case GL_DEPTH_COMPONENT16:
4021 case GL_RGBA4:
4022 case GL_RGB5_A1:
4023 case GL_RGB565:
4024 case GL_STENCIL_INDEX8:
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004025 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004026 case GL_RGB8_OES:
4027 case GL_RGBA8_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004028 break;
4029 default:
4030 return error(GL_INVALID_ENUM);
4031 }
4032
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004033 if (width < 0 || height < 0 || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004034 {
4035 return error(GL_INVALID_VALUE);
4036 }
4037
4038 gl::Context *context = gl::getContext();
4039
4040 if (context)
4041 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004042 if (width > context->getMaximumRenderbufferDimension() ||
4043 height > context->getMaximumRenderbufferDimension() ||
4044 samples > context->getMaxSupportedSamples())
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004045 {
4046 return error(GL_INVALID_VALUE);
4047 }
4048
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00004049 GLuint handle = context->getRenderbufferHandle();
4050 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004051 {
4052 return error(GL_INVALID_OPERATION);
4053 }
4054
4055 switch (internalformat)
4056 {
4057 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004058 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004059 break;
4060 case GL_RGBA4:
4061 case GL_RGB5_A1:
4062 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00004063 case GL_RGB8_OES:
4064 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004065 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004066 break;
4067 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004068 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004069 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004070 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004071 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00004072 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004073 default:
4074 return error(GL_INVALID_ENUM);
4075 }
4076 }
4077 }
4078 catch(std::bad_alloc&)
4079 {
4080 return error(GL_OUT_OF_MEMORY);
4081 }
4082}
4083
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00004084void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4085{
4086 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4087}
4088
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004089void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4090{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004091 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004092
4093 try
4094 {
4095 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004096
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004097 if (context)
4098 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00004099 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004100 }
4101 }
4102 catch(std::bad_alloc&)
4103 {
4104 return error(GL_OUT_OF_MEMORY);
4105 }
4106}
4107
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004108void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4109{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004110 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
4111
4112 try
4113 {
4114 if (condition != GL_ALL_COMPLETED_NV)
4115 {
4116 return error(GL_INVALID_ENUM);
4117 }
4118
4119 gl::Context *context = gl::getContext();
4120
4121 if (context)
4122 {
4123 gl::Fence *fenceObject = context->getFence(fence);
4124
4125 if (fenceObject == NULL)
4126 {
4127 return error(GL_INVALID_OPERATION);
4128 }
4129
4130 fenceObject->setFence(condition);
4131 }
4132 }
4133 catch(std::bad_alloc&)
4134 {
4135 return error(GL_OUT_OF_MEMORY);
4136 }
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004137}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004138
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004139void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4140{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004141 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 +00004142
4143 try
4144 {
4145 if (width < 0 || height < 0)
4146 {
4147 return error(GL_INVALID_VALUE);
4148 }
4149
4150 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004151
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004152 if (context)
4153 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004154 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004155 }
4156 }
4157 catch(std::bad_alloc&)
4158 {
4159 return error(GL_OUT_OF_MEMORY);
4160 }
4161}
4162
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004163void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004164{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004165 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004166 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004167 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004168
4169 try
4170 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00004171 // No binary shader formats are supported.
4172 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004173 }
4174 catch(std::bad_alloc&)
4175 {
4176 return error(GL_OUT_OF_MEMORY);
4177 }
4178}
4179
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004180void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004181{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004182 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 +00004183 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004184
4185 try
4186 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004187 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004188 {
4189 return error(GL_INVALID_VALUE);
4190 }
4191
4192 gl::Context *context = gl::getContext();
4193
4194 if (context)
4195 {
4196 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004197
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004198 if (!shaderObject)
4199 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004200 if (context->getProgram(shader))
4201 {
4202 return error(GL_INVALID_OPERATION);
4203 }
4204 else
4205 {
4206 return error(GL_INVALID_VALUE);
4207 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004208 }
4209
4210 shaderObject->setSource(count, string, length);
4211 }
4212 }
4213 catch(std::bad_alloc&)
4214 {
4215 return error(GL_OUT_OF_MEMORY);
4216 }
4217}
4218
4219void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4220{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004221 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004222}
4223
4224void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4225{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004226 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 +00004227
4228 try
4229 {
4230 switch (face)
4231 {
4232 case GL_FRONT:
4233 case GL_BACK:
4234 case GL_FRONT_AND_BACK:
4235 break;
4236 default:
4237 return error(GL_INVALID_ENUM);
4238 }
4239
4240 switch (func)
4241 {
4242 case GL_NEVER:
4243 case GL_ALWAYS:
4244 case GL_LESS:
4245 case GL_LEQUAL:
4246 case GL_EQUAL:
4247 case GL_GEQUAL:
4248 case GL_GREATER:
4249 case GL_NOTEQUAL:
4250 break;
4251 default:
4252 return error(GL_INVALID_ENUM);
4253 }
4254
4255 gl::Context *context = gl::getContext();
4256
4257 if (context)
4258 {
4259 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4260 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004261 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004262 }
4263
4264 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4265 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004266 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004267 }
4268 }
4269 }
4270 catch(std::bad_alloc&)
4271 {
4272 return error(GL_OUT_OF_MEMORY);
4273 }
4274}
4275
4276void __stdcall glStencilMask(GLuint mask)
4277{
4278 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4279}
4280
4281void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4282{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004283 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004284
4285 try
4286 {
4287 switch (face)
4288 {
4289 case GL_FRONT:
4290 case GL_BACK:
4291 case GL_FRONT_AND_BACK:
4292 break;
4293 default:
4294 return error(GL_INVALID_ENUM);
4295 }
4296
4297 gl::Context *context = gl::getContext();
4298
4299 if (context)
4300 {
4301 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4302 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004303 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004304 }
4305
4306 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4307 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004308 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004309 }
4310 }
4311 }
4312 catch(std::bad_alloc&)
4313 {
4314 return error(GL_OUT_OF_MEMORY);
4315 }
4316}
4317
4318void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4319{
4320 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4321}
4322
4323void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4324{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004325 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4326 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004327
4328 try
4329 {
4330 switch (face)
4331 {
4332 case GL_FRONT:
4333 case GL_BACK:
4334 case GL_FRONT_AND_BACK:
4335 break;
4336 default:
4337 return error(GL_INVALID_ENUM);
4338 }
4339
4340 switch (fail)
4341 {
4342 case GL_ZERO:
4343 case GL_KEEP:
4344 case GL_REPLACE:
4345 case GL_INCR:
4346 case GL_DECR:
4347 case GL_INVERT:
4348 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004349 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004350 break;
4351 default:
4352 return error(GL_INVALID_ENUM);
4353 }
4354
4355 switch (zfail)
4356 {
4357 case GL_ZERO:
4358 case GL_KEEP:
4359 case GL_REPLACE:
4360 case GL_INCR:
4361 case GL_DECR:
4362 case GL_INVERT:
4363 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004364 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004365 break;
4366 default:
4367 return error(GL_INVALID_ENUM);
4368 }
4369
4370 switch (zpass)
4371 {
4372 case GL_ZERO:
4373 case GL_KEEP:
4374 case GL_REPLACE:
4375 case GL_INCR:
4376 case GL_DECR:
4377 case GL_INVERT:
4378 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004379 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004380 break;
4381 default:
4382 return error(GL_INVALID_ENUM);
4383 }
4384
4385 gl::Context *context = gl::getContext();
4386
4387 if (context)
4388 {
4389 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4390 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004391 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004392 }
4393
4394 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4395 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004396 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004397 }
4398 }
4399 }
4400 catch(std::bad_alloc&)
4401 {
4402 return error(GL_OUT_OF_MEMORY);
4403 }
4404}
4405
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004406GLboolean __stdcall glTestFenceNV(GLuint fence)
4407{
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004408 TRACE("(GLuint fence = %d)", fence);
4409
4410 try
4411 {
4412 gl::Context *context = gl::getContext();
4413
4414 if (context)
4415 {
4416 gl::Fence *fenceObject = context->getFence(fence);
4417
4418 if (fenceObject == NULL)
4419 {
4420 return error(GL_INVALID_OPERATION, GL_TRUE);
4421 }
4422
4423 return fenceObject->testFence();
4424 }
4425 }
4426 catch(std::bad_alloc&)
4427 {
4428 error(GL_OUT_OF_MEMORY);
4429 }
4430
4431 return GL_TRUE;
daniel@transgaming.comfe208882010-09-01 15:47:57 +00004432}
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00004433
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004434void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4435 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004436{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004437 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 +00004438 "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 +00004439 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004440
4441 try
4442 {
4443 if (level < 0 || width < 0 || height < 0)
4444 {
4445 return error(GL_INVALID_VALUE);
4446 }
4447
4448 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
4449 {
4450 return error(GL_INVALID_VALUE);
4451 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004452
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004453 if (internalformat != format)
4454 {
4455 return error(GL_INVALID_OPERATION);
4456 }
4457
4458 switch (internalformat)
4459 {
4460 case GL_ALPHA:
4461 case GL_LUMINANCE:
4462 case GL_LUMINANCE_ALPHA:
4463 switch (type)
4464 {
4465 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004466 case GL_FLOAT:
4467 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004468 break;
4469 default:
4470 return error(GL_INVALID_ENUM);
4471 }
4472 break;
4473 case GL_RGB:
4474 switch (type)
4475 {
4476 case GL_UNSIGNED_BYTE:
4477 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004478 case GL_FLOAT:
4479 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004480 break;
4481 default:
4482 return error(GL_INVALID_ENUM);
4483 }
4484 break;
4485 case GL_RGBA:
4486 switch (type)
4487 {
4488 case GL_UNSIGNED_BYTE:
4489 case GL_UNSIGNED_SHORT_4_4_4_4:
4490 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004491 case GL_FLOAT:
4492 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004493 break;
4494 default:
4495 return error(GL_INVALID_ENUM);
4496 }
4497 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004498 case GL_BGRA_EXT:
4499 switch (type)
4500 {
4501 case GL_UNSIGNED_BYTE:
4502 break;
4503 default:
4504 return error(GL_INVALID_ENUM);
4505 }
4506 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004507 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4508 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4509 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004510 default:
4511 return error(GL_INVALID_VALUE);
4512 }
4513
4514 if (border != 0)
4515 {
4516 return error(GL_INVALID_VALUE);
4517 }
4518
4519 gl::Context *context = gl::getContext();
4520
4521 if (context)
4522 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004523 switch (target)
4524 {
4525 case GL_TEXTURE_2D:
4526 if (width > (context->getMaximumTextureDimension() >> level) ||
4527 height > (context->getMaximumTextureDimension() >> level))
4528 {
4529 return error(GL_INVALID_VALUE);
4530 }
4531 break;
4532 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4533 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4534 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4535 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4536 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4537 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4538 if (width != height)
4539 {
4540 return error(GL_INVALID_VALUE);
4541 }
4542
4543 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4544 height > (context->getMaximumCubeTextureDimension() >> level))
4545 {
4546 return error(GL_INVALID_VALUE);
4547 }
4548 break;
4549 default:
4550 return error(GL_INVALID_ENUM);
4551 }
4552
daniel@transgaming.com01868132010-08-24 19:21:17 +00004553 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4554 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
4555 {
4556 if (context->supportsCompressedTextures())
4557 {
4558 return error(GL_INVALID_OPERATION);
4559 }
4560 else
4561 {
4562 return error(GL_INVALID_ENUM);
4563 }
4564 }
4565
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004566 if (type == GL_FLOAT)
4567 {
4568 if (!context->supportsFloatTextures())
4569 {
4570 return error(GL_INVALID_ENUM);
4571 }
4572 }
4573 else if (type == GL_HALF_FLOAT_OES)
4574 {
4575 if (!context->supportsHalfFloatTextures())
4576 {
4577 return error(GL_INVALID_ENUM);
4578 }
4579 }
4580
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004581 if (target == GL_TEXTURE_2D)
4582 {
4583 gl::Texture2D *texture = context->getTexture2D();
4584
4585 if (!texture)
4586 {
4587 return error(GL_INVALID_OPERATION);
4588 }
4589
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004590 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004591 }
4592 else
4593 {
4594 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4595
4596 if (!texture)
4597 {
4598 return error(GL_INVALID_OPERATION);
4599 }
4600
4601 switch (target)
4602 {
4603 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004604 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004605 break;
4606 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004607 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004608 break;
4609 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004610 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004611 break;
4612 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004613 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004614 break;
4615 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004616 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004617 break;
4618 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004619 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004620 break;
4621 default: UNREACHABLE();
4622 }
4623 }
4624 }
4625 }
4626 catch(std::bad_alloc&)
4627 {
4628 return error(GL_OUT_OF_MEMORY);
4629 }
4630}
4631
4632void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4633{
4634 glTexParameteri(target, pname, (GLint)param);
4635}
4636
4637void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4638{
4639 glTexParameteri(target, pname, (GLint)*params);
4640}
4641
4642void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4643{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004644 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004645
4646 try
4647 {
4648 gl::Context *context = gl::getContext();
4649
4650 if (context)
4651 {
4652 gl::Texture *texture;
4653
4654 switch (target)
4655 {
4656 case GL_TEXTURE_2D:
4657 texture = context->getTexture2D();
4658 break;
4659 case GL_TEXTURE_CUBE_MAP:
4660 texture = context->getTextureCubeMap();
4661 break;
4662 default:
4663 return error(GL_INVALID_ENUM);
4664 }
4665
4666 switch (pname)
4667 {
4668 case GL_TEXTURE_WRAP_S:
4669 if (!texture->setWrapS((GLenum)param))
4670 {
4671 return error(GL_INVALID_ENUM);
4672 }
4673 break;
4674 case GL_TEXTURE_WRAP_T:
4675 if (!texture->setWrapT((GLenum)param))
4676 {
4677 return error(GL_INVALID_ENUM);
4678 }
4679 break;
4680 case GL_TEXTURE_MIN_FILTER:
4681 if (!texture->setMinFilter((GLenum)param))
4682 {
4683 return error(GL_INVALID_ENUM);
4684 }
4685 break;
4686 case GL_TEXTURE_MAG_FILTER:
4687 if (!texture->setMagFilter((GLenum)param))
4688 {
4689 return error(GL_INVALID_ENUM);
4690 }
4691 break;
4692 default:
4693 return error(GL_INVALID_ENUM);
4694 }
4695 }
4696 }
4697 catch(std::bad_alloc&)
4698 {
4699 return error(GL_OUT_OF_MEMORY);
4700 }
4701}
4702
4703void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4704{
4705 glTexParameteri(target, pname, *params);
4706}
4707
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004708void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4709 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004710{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004711 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4712 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004713 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004714 target, level, xoffset, yoffset, width, height, format, type, pixels);
4715
4716 try
4717 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004718 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004719 {
4720 return error(GL_INVALID_ENUM);
4721 }
4722
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004723 if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004724 {
4725 return error(GL_INVALID_VALUE);
4726 }
4727
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004728 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4729 {
4730 return error(GL_INVALID_VALUE);
4731 }
4732
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004733 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004734 {
4735 return error(GL_INVALID_ENUM);
4736 }
4737
4738 if (width == 0 || height == 0 || pixels == NULL)
4739 {
4740 return;
4741 }
4742
4743 gl::Context *context = gl::getContext();
4744
4745 if (context)
4746 {
daniel@transgaming.com5d752f22010-10-07 13:37:20 +00004747 if (level > context->getMaximumTextureLevel())
4748 {
4749 return error(GL_INVALID_VALUE);
4750 }
4751
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004752 if (format == GL_FLOAT)
4753 {
4754 if (!context->supportsFloatTextures())
4755 {
4756 return error(GL_INVALID_ENUM);
4757 }
4758 }
4759 else if (format == GL_HALF_FLOAT_OES)
4760 {
4761 if (!context->supportsHalfFloatTextures())
4762 {
4763 return error(GL_INVALID_ENUM);
4764 }
4765 }
4766
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004767 if (target == GL_TEXTURE_2D)
4768 {
4769 gl::Texture2D *texture = context->getTexture2D();
4770
4771 if (!texture)
4772 {
4773 return error(GL_INVALID_OPERATION);
4774 }
4775
daniel@transgaming.com01868132010-08-24 19:21:17 +00004776 if (texture->isCompressed())
4777 {
4778 return error(GL_INVALID_OPERATION);
4779 }
4780
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004781 if (format != texture->getFormat())
4782 {
4783 return error(GL_INVALID_OPERATION);
4784 }
4785
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004786 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004787 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004788 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004789 {
4790 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4791
4792 if (!texture)
4793 {
4794 return error(GL_INVALID_OPERATION);
4795 }
4796
daniel@transgaming.com01868132010-08-24 19:21:17 +00004797 if (texture->isCompressed())
4798 {
4799 return error(GL_INVALID_OPERATION);
4800 }
4801
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004802 if (format != texture->getFormat())
4803 {
4804 return error(GL_INVALID_OPERATION);
4805 }
4806
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004807 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004808 }
4809 else
4810 {
4811 UNREACHABLE();
4812 }
4813 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004814 }
4815 catch(std::bad_alloc&)
4816 {
4817 return error(GL_OUT_OF_MEMORY);
4818 }
4819}
4820
4821void __stdcall glUniform1f(GLint location, GLfloat x)
4822{
4823 glUniform1fv(location, 1, &x);
4824}
4825
4826void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4827{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004828 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004829
4830 try
4831 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004832 if (count < 0)
4833 {
4834 return error(GL_INVALID_VALUE);
4835 }
4836
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004837 if (location == -1)
4838 {
4839 return;
4840 }
4841
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004842 gl::Context *context = gl::getContext();
4843
4844 if (context)
4845 {
4846 gl::Program *program = context->getCurrentProgram();
4847
4848 if (!program)
4849 {
4850 return error(GL_INVALID_OPERATION);
4851 }
4852
4853 if (!program->setUniform1fv(location, count, v))
4854 {
4855 return error(GL_INVALID_OPERATION);
4856 }
4857 }
4858 }
4859 catch(std::bad_alloc&)
4860 {
4861 return error(GL_OUT_OF_MEMORY);
4862 }
4863}
4864
4865void __stdcall glUniform1i(GLint location, GLint x)
4866{
4867 glUniform1iv(location, 1, &x);
4868}
4869
4870void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4871{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004872 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004873
4874 try
4875 {
4876 if (count < 0)
4877 {
4878 return error(GL_INVALID_VALUE);
4879 }
4880
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004881 if (location == -1)
4882 {
4883 return;
4884 }
4885
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004886 gl::Context *context = gl::getContext();
4887
4888 if (context)
4889 {
4890 gl::Program *program = context->getCurrentProgram();
4891
4892 if (!program)
4893 {
4894 return error(GL_INVALID_OPERATION);
4895 }
4896
4897 if (!program->setUniform1iv(location, count, v))
4898 {
4899 return error(GL_INVALID_OPERATION);
4900 }
4901 }
4902 }
4903 catch(std::bad_alloc&)
4904 {
4905 return error(GL_OUT_OF_MEMORY);
4906 }
4907}
4908
4909void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4910{
4911 GLfloat xy[2] = {x, y};
4912
4913 glUniform2fv(location, 1, (GLfloat*)&xy);
4914}
4915
4916void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4917{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004918 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004919
4920 try
4921 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004922 if (count < 0)
4923 {
4924 return error(GL_INVALID_VALUE);
4925 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004926
4927 if (location == -1)
4928 {
4929 return;
4930 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004931
4932 gl::Context *context = gl::getContext();
4933
4934 if (context)
4935 {
4936 gl::Program *program = context->getCurrentProgram();
4937
4938 if (!program)
4939 {
4940 return error(GL_INVALID_OPERATION);
4941 }
4942
4943 if (!program->setUniform2fv(location, count, v))
4944 {
4945 return error(GL_INVALID_OPERATION);
4946 }
4947 }
4948 }
4949 catch(std::bad_alloc&)
4950 {
4951 return error(GL_OUT_OF_MEMORY);
4952 }
4953}
4954
4955void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4956{
4957 GLint xy[4] = {x, y};
4958
4959 glUniform2iv(location, 1, (GLint*)&xy);
4960}
4961
4962void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4963{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004964 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004965
4966 try
4967 {
4968 if (count < 0)
4969 {
4970 return error(GL_INVALID_VALUE);
4971 }
4972
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004973 if (location == -1)
4974 {
4975 return;
4976 }
4977
4978 gl::Context *context = gl::getContext();
4979
4980 if (context)
4981 {
4982 gl::Program *program = context->getCurrentProgram();
4983
4984 if (!program)
4985 {
4986 return error(GL_INVALID_OPERATION);
4987 }
4988
4989 if (!program->setUniform2iv(location, count, v))
4990 {
4991 return error(GL_INVALID_OPERATION);
4992 }
4993 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004994 }
4995 catch(std::bad_alloc&)
4996 {
4997 return error(GL_OUT_OF_MEMORY);
4998 }
4999}
5000
5001void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5002{
5003 GLfloat xyz[3] = {x, y, z};
5004
5005 glUniform3fv(location, 1, (GLfloat*)&xyz);
5006}
5007
5008void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5009{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005010 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005011
5012 try
5013 {
5014 if (count < 0)
5015 {
5016 return error(GL_INVALID_VALUE);
5017 }
5018
5019 if (location == -1)
5020 {
5021 return;
5022 }
5023
5024 gl::Context *context = gl::getContext();
5025
5026 if (context)
5027 {
5028 gl::Program *program = context->getCurrentProgram();
5029
5030 if (!program)
5031 {
5032 return error(GL_INVALID_OPERATION);
5033 }
5034
5035 if (!program->setUniform3fv(location, count, v))
5036 {
5037 return error(GL_INVALID_OPERATION);
5038 }
5039 }
5040 }
5041 catch(std::bad_alloc&)
5042 {
5043 return error(GL_OUT_OF_MEMORY);
5044 }
5045}
5046
5047void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5048{
5049 GLint xyz[3] = {x, y, z};
5050
5051 glUniform3iv(location, 1, (GLint*)&xyz);
5052}
5053
5054void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5055{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005056 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005057
5058 try
5059 {
5060 if (count < 0)
5061 {
5062 return error(GL_INVALID_VALUE);
5063 }
5064
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005065 if (location == -1)
5066 {
5067 return;
5068 }
5069
5070 gl::Context *context = gl::getContext();
5071
5072 if (context)
5073 {
5074 gl::Program *program = context->getCurrentProgram();
5075
5076 if (!program)
5077 {
5078 return error(GL_INVALID_OPERATION);
5079 }
5080
5081 if (!program->setUniform3iv(location, count, v))
5082 {
5083 return error(GL_INVALID_OPERATION);
5084 }
5085 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005086 }
5087 catch(std::bad_alloc&)
5088 {
5089 return error(GL_OUT_OF_MEMORY);
5090 }
5091}
5092
5093void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5094{
5095 GLfloat xyzw[4] = {x, y, z, w};
5096
5097 glUniform4fv(location, 1, (GLfloat*)&xyzw);
5098}
5099
5100void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5101{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005102 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005103
5104 try
5105 {
5106 if (count < 0)
5107 {
5108 return error(GL_INVALID_VALUE);
5109 }
5110
5111 if (location == -1)
5112 {
5113 return;
5114 }
5115
5116 gl::Context *context = gl::getContext();
5117
5118 if (context)
5119 {
5120 gl::Program *program = context->getCurrentProgram();
5121
5122 if (!program)
5123 {
5124 return error(GL_INVALID_OPERATION);
5125 }
5126
5127 if (!program->setUniform4fv(location, count, v))
5128 {
5129 return error(GL_INVALID_OPERATION);
5130 }
5131 }
5132 }
5133 catch(std::bad_alloc&)
5134 {
5135 return error(GL_OUT_OF_MEMORY);
5136 }
5137}
5138
5139void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5140{
5141 GLint xyzw[4] = {x, y, z, w};
5142
5143 glUniform4iv(location, 1, (GLint*)&xyzw);
5144}
5145
5146void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5147{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005148 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005149
5150 try
5151 {
5152 if (count < 0)
5153 {
5154 return error(GL_INVALID_VALUE);
5155 }
5156
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00005157 if (location == -1)
5158 {
5159 return;
5160 }
5161
5162 gl::Context *context = gl::getContext();
5163
5164 if (context)
5165 {
5166 gl::Program *program = context->getCurrentProgram();
5167
5168 if (!program)
5169 {
5170 return error(GL_INVALID_OPERATION);
5171 }
5172
5173 if (!program->setUniform4iv(location, count, v))
5174 {
5175 return error(GL_INVALID_OPERATION);
5176 }
5177 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005178 }
5179 catch(std::bad_alloc&)
5180 {
5181 return error(GL_OUT_OF_MEMORY);
5182 }
5183}
5184
5185void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5186{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005187 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5188 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005189
5190 try
5191 {
5192 if (count < 0 || transpose != GL_FALSE)
5193 {
5194 return error(GL_INVALID_VALUE);
5195 }
5196
5197 if (location == -1)
5198 {
5199 return;
5200 }
5201
5202 gl::Context *context = gl::getContext();
5203
5204 if (context)
5205 {
5206 gl::Program *program = context->getCurrentProgram();
5207
5208 if (!program)
5209 {
5210 return error(GL_INVALID_OPERATION);
5211 }
5212
5213 if (!program->setUniformMatrix2fv(location, count, value))
5214 {
5215 return error(GL_INVALID_OPERATION);
5216 }
5217 }
5218 }
5219 catch(std::bad_alloc&)
5220 {
5221 return error(GL_OUT_OF_MEMORY);
5222 }
5223}
5224
5225void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5226{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005227 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5228 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005229
5230 try
5231 {
5232 if (count < 0 || transpose != GL_FALSE)
5233 {
5234 return error(GL_INVALID_VALUE);
5235 }
5236
5237 if (location == -1)
5238 {
5239 return;
5240 }
5241
5242 gl::Context *context = gl::getContext();
5243
5244 if (context)
5245 {
5246 gl::Program *program = context->getCurrentProgram();
5247
5248 if (!program)
5249 {
5250 return error(GL_INVALID_OPERATION);
5251 }
5252
5253 if (!program->setUniformMatrix3fv(location, count, value))
5254 {
5255 return error(GL_INVALID_OPERATION);
5256 }
5257 }
5258 }
5259 catch(std::bad_alloc&)
5260 {
5261 return error(GL_OUT_OF_MEMORY);
5262 }
5263}
5264
5265void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5266{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005267 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5268 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005269
5270 try
5271 {
5272 if (count < 0 || transpose != GL_FALSE)
5273 {
5274 return error(GL_INVALID_VALUE);
5275 }
5276
5277 if (location == -1)
5278 {
5279 return;
5280 }
5281
5282 gl::Context *context = gl::getContext();
5283
5284 if (context)
5285 {
5286 gl::Program *program = context->getCurrentProgram();
5287
5288 if (!program)
5289 {
5290 return error(GL_INVALID_OPERATION);
5291 }
5292
5293 if (!program->setUniformMatrix4fv(location, count, value))
5294 {
5295 return error(GL_INVALID_OPERATION);
5296 }
5297 }
5298 }
5299 catch(std::bad_alloc&)
5300 {
5301 return error(GL_OUT_OF_MEMORY);
5302 }
5303}
5304
5305void __stdcall glUseProgram(GLuint program)
5306{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005307 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005308
5309 try
5310 {
5311 gl::Context *context = gl::getContext();
5312
5313 if (context)
5314 {
5315 gl::Program *programObject = context->getProgram(program);
5316
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005317 if (!programObject && program != 0)
5318 {
5319 if (context->getShader(program))
5320 {
5321 return error(GL_INVALID_OPERATION);
5322 }
5323 else
5324 {
5325 return error(GL_INVALID_VALUE);
5326 }
5327 }
5328
5329 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005330 {
5331 return error(GL_INVALID_OPERATION);
5332 }
5333
5334 context->useProgram(program);
5335 }
5336 }
5337 catch(std::bad_alloc&)
5338 {
5339 return error(GL_OUT_OF_MEMORY);
5340 }
5341}
5342
5343void __stdcall glValidateProgram(GLuint program)
5344{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005345 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005346
5347 try
5348 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005349 gl::Context *context = gl::getContext();
5350
5351 if (context)
5352 {
5353 gl::Program *programObject = context->getProgram(program);
5354
5355 if (!programObject)
5356 {
5357 if (context->getShader(program))
5358 {
5359 return error(GL_INVALID_OPERATION);
5360 }
5361 else
5362 {
5363 return error(GL_INVALID_VALUE);
5364 }
5365 }
5366
5367 programObject->validate();
5368 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005369 }
5370 catch(std::bad_alloc&)
5371 {
5372 return error(GL_OUT_OF_MEMORY);
5373 }
5374}
5375
5376void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5377{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005378 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005379
5380 try
5381 {
5382 if (index >= gl::MAX_VERTEX_ATTRIBS)
5383 {
5384 return error(GL_INVALID_VALUE);
5385 }
5386
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005387 gl::Context *context = gl::getContext();
5388
5389 if (context)
5390 {
5391 GLfloat vals[4] = { x, 0, 0, 1 };
5392 context->setVertexAttrib(index, vals);
5393 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005394 }
5395 catch(std::bad_alloc&)
5396 {
5397 return error(GL_OUT_OF_MEMORY);
5398 }
5399}
5400
5401void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5402{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005403 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005404
5405 try
5406 {
5407 if (index >= gl::MAX_VERTEX_ATTRIBS)
5408 {
5409 return error(GL_INVALID_VALUE);
5410 }
5411
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005412 gl::Context *context = gl::getContext();
5413
5414 if (context)
5415 {
5416 GLfloat vals[4] = { values[0], 0, 0, 1 };
5417 context->setVertexAttrib(index, vals);
5418 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005419 }
5420 catch(std::bad_alloc&)
5421 {
5422 return error(GL_OUT_OF_MEMORY);
5423 }
5424}
5425
5426void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5427{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005428 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005429
5430 try
5431 {
5432 if (index >= gl::MAX_VERTEX_ATTRIBS)
5433 {
5434 return error(GL_INVALID_VALUE);
5435 }
5436
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005437 gl::Context *context = gl::getContext();
5438
5439 if (context)
5440 {
5441 GLfloat vals[4] = { x, y, 0, 1 };
5442 context->setVertexAttrib(index, vals);
5443 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005444 }
5445 catch(std::bad_alloc&)
5446 {
5447 return error(GL_OUT_OF_MEMORY);
5448 }
5449}
5450
5451void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5452{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005453 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005454
5455 try
5456 {
5457 if (index >= gl::MAX_VERTEX_ATTRIBS)
5458 {
5459 return error(GL_INVALID_VALUE);
5460 }
5461
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005462 gl::Context *context = gl::getContext();
5463
5464 if (context)
5465 {
5466 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5467 context->setVertexAttrib(index, vals);
5468 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005469 }
5470 catch(std::bad_alloc&)
5471 {
5472 return error(GL_OUT_OF_MEMORY);
5473 }
5474}
5475
5476void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5477{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005478 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 +00005479
5480 try
5481 {
5482 if (index >= gl::MAX_VERTEX_ATTRIBS)
5483 {
5484 return error(GL_INVALID_VALUE);
5485 }
5486
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005487 gl::Context *context = gl::getContext();
5488
5489 if (context)
5490 {
5491 GLfloat vals[4] = { x, y, z, 1 };
5492 context->setVertexAttrib(index, vals);
5493 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005494 }
5495 catch(std::bad_alloc&)
5496 {
5497 return error(GL_OUT_OF_MEMORY);
5498 }
5499}
5500
5501void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5502{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005503 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005504
5505 try
5506 {
5507 if (index >= gl::MAX_VERTEX_ATTRIBS)
5508 {
5509 return error(GL_INVALID_VALUE);
5510 }
5511
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005512 gl::Context *context = gl::getContext();
5513
5514 if (context)
5515 {
5516 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5517 context->setVertexAttrib(index, vals);
5518 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005519 }
5520 catch(std::bad_alloc&)
5521 {
5522 return error(GL_OUT_OF_MEMORY);
5523 }
5524}
5525
5526void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5527{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005528 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 +00005529
5530 try
5531 {
5532 if (index >= gl::MAX_VERTEX_ATTRIBS)
5533 {
5534 return error(GL_INVALID_VALUE);
5535 }
5536
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005537 gl::Context *context = gl::getContext();
5538
5539 if (context)
5540 {
5541 GLfloat vals[4] = { x, y, z, w };
5542 context->setVertexAttrib(index, vals);
5543 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005544 }
5545 catch(std::bad_alloc&)
5546 {
5547 return error(GL_OUT_OF_MEMORY);
5548 }
5549}
5550
5551void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5552{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005553 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005554
5555 try
5556 {
5557 if (index >= gl::MAX_VERTEX_ATTRIBS)
5558 {
5559 return error(GL_INVALID_VALUE);
5560 }
5561
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005562 gl::Context *context = gl::getContext();
5563
5564 if (context)
5565 {
5566 context->setVertexAttrib(index, values);
5567 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005568 }
5569 catch(std::bad_alloc&)
5570 {
5571 return error(GL_OUT_OF_MEMORY);
5572 }
5573}
5574
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005575void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005576{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005577 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005578 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005579 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005580
5581 try
5582 {
5583 if (index >= gl::MAX_VERTEX_ATTRIBS)
5584 {
5585 return error(GL_INVALID_VALUE);
5586 }
5587
5588 if (size < 1 || size > 4)
5589 {
5590 return error(GL_INVALID_VALUE);
5591 }
5592
5593 switch (type)
5594 {
5595 case GL_BYTE:
5596 case GL_UNSIGNED_BYTE:
5597 case GL_SHORT:
5598 case GL_UNSIGNED_SHORT:
5599 case GL_FIXED:
5600 case GL_FLOAT:
5601 break;
5602 default:
5603 return error(GL_INVALID_ENUM);
5604 }
5605
5606 if (stride < 0)
5607 {
5608 return error(GL_INVALID_VALUE);
5609 }
5610
5611 gl::Context *context = gl::getContext();
5612
5613 if (context)
5614 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005615 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005616 }
5617 }
5618 catch(std::bad_alloc&)
5619 {
5620 return error(GL_OUT_OF_MEMORY);
5621 }
5622}
5623
5624void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5625{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005626 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 +00005627
5628 try
5629 {
5630 if (width < 0 || height < 0)
5631 {
5632 return error(GL_INVALID_VALUE);
5633 }
5634
5635 gl::Context *context = gl::getContext();
5636
5637 if (context)
5638 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005639 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005640 }
5641 }
5642 catch(std::bad_alloc&)
5643 {
5644 return error(GL_OUT_OF_MEMORY);
5645 }
5646}
5647
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005648void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5649 GLbitfield mask, GLenum filter)
5650{
5651 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5652 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5653 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5654 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5655
5656 try
5657 {
5658 switch (filter)
5659 {
5660 case GL_NEAREST:
5661 break;
5662 default:
5663 return error(GL_INVALID_ENUM);
5664 }
5665
5666 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5667 {
5668 return error(GL_INVALID_VALUE);
5669 }
5670
5671 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5672 {
5673 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5674 return error(GL_INVALID_OPERATION);
5675 }
5676
5677 gl::Context *context = gl::getContext();
5678
5679 if (context)
5680 {
5681 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5682 {
5683 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5684 return error(GL_INVALID_OPERATION);
5685 }
5686
5687 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5688 }
5689 }
5690 catch(std::bad_alloc&)
5691 {
5692 return error(GL_OUT_OF_MEMORY);
5693 }
5694}
5695
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005696void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5697 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005698{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005699 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5700 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005701 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005702 target, level, internalformat, width, height, depth, border, format, type, pixels);
5703
5704 try
5705 {
5706 UNIMPLEMENTED(); // FIXME
5707 }
5708 catch(std::bad_alloc&)
5709 {
5710 return error(GL_OUT_OF_MEMORY);
5711 }
5712}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005713
5714__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5715{
5716 struct Extension
5717 {
5718 const char *name;
5719 __eglMustCastToProperFunctionPointerType address;
5720 };
5721
5722 static const Extension glExtensions[] =
5723 {
5724 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00005725 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
apatrick@chromium.orgd3bd0ad2010-08-30 18:55:36 +00005726 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
5727 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
5728 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
5729 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
5730 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
5731 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
5732 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005733 };
5734
5735 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5736 {
5737 if (strcmp(procname, glExtensions[ext].name) == 0)
5738 {
5739 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5740 }
5741 }
5742
5743 return NULL;
5744}
5745
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005746}