blob: 95d38b17c8f523c190b86ce7cf21e5aadfea69d3 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000017
18#include "libGLESv2/main.h"
19#include "libGLESv2/mathutil.h"
20#include "libGLESv2/utilities.h"
21#include "libGLESv2/Buffer.h"
22#include "libGLESv2/Context.h"
23#include "libGLESv2/Framebuffer.h"
24#include "libGLESv2/Program.h"
25#include "libGLESv2/Renderbuffer.h"
26#include "libGLESv2/Shader.h"
27#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000028
29extern "C"
30{
31
32void __stdcall glActiveTexture(GLenum texture)
33{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000034 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035
36 try
37 {
38 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
39 {
40 return error(GL_INVALID_ENUM);
41 }
42
43 gl::Context *context = gl::getContext();
44
45 if (context)
46 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +000047 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000048 }
49 }
50 catch(std::bad_alloc&)
51 {
52 return error(GL_OUT_OF_MEMORY);
53 }
54}
55
56void __stdcall glAttachShader(GLuint program, GLuint shader)
57{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000058 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000059
60 try
61 {
62 gl::Context *context = gl::getContext();
63
64 if (context)
65 {
66 gl::Program *programObject = context->getProgram(program);
67 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000068
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000069 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000071 if (context->getShader(program))
72 {
73 return error(GL_INVALID_OPERATION);
74 }
75 else
76 {
77 return error(GL_INVALID_VALUE);
78 }
79 }
80
81 if (!shaderObject)
82 {
83 if (context->getProgram(shader))
84 {
85 return error(GL_INVALID_OPERATION);
86 }
87 else
88 {
89 return error(GL_INVALID_VALUE);
90 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000091 }
92
93 if (!programObject->attachShader(shaderObject))
94 {
95 return error(GL_INVALID_OPERATION);
96 }
97 }
98 }
99 catch(std::bad_alloc&)
100 {
101 return error(GL_OUT_OF_MEMORY);
102 }
103}
104
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000105void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000106{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000107 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108
109 try
110 {
111 if (index >= gl::MAX_VERTEX_ATTRIBS)
112 {
113 return error(GL_INVALID_VALUE);
114 }
115
116 gl::Context *context = gl::getContext();
117
118 if (context)
119 {
120 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000121
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000122 if (!programObject)
123 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000124 if (context->getShader(program))
125 {
126 return error(GL_INVALID_OPERATION);
127 }
128 else
129 {
130 return error(GL_INVALID_VALUE);
131 }
132 }
133
134 if (strncmp(name, "gl_", 3) == 0)
135 {
136 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137 }
138
139 programObject->bindAttributeLocation(index, name);
140 }
141 }
142 catch(std::bad_alloc&)
143 {
144 return error(GL_OUT_OF_MEMORY);
145 }
146}
147
148void __stdcall glBindBuffer(GLenum target, GLuint buffer)
149{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000150 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000151
152 try
153 {
154 gl::Context *context = gl::getContext();
155
156 if (context)
157 {
158 switch (target)
159 {
160 case GL_ARRAY_BUFFER:
161 context->bindArrayBuffer(buffer);
162 return;
163 case GL_ELEMENT_ARRAY_BUFFER:
164 context->bindElementArrayBuffer(buffer);
165 return;
166 default:
167 return error(GL_INVALID_ENUM);
168 }
169 }
170 }
171 catch(std::bad_alloc&)
172 {
173 return error(GL_OUT_OF_MEMORY);
174 }
175}
176
177void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
178{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000179 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000180
181 try
182 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000183 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000184 {
185 return error(GL_INVALID_ENUM);
186 }
187
188 gl::Context *context = gl::getContext();
189
190 if (context)
191 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000192 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
193 {
194 context->bindReadFramebuffer(framebuffer);
195 }
196
197 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
198 {
199 context->bindDrawFramebuffer(framebuffer);
200 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000201 }
202 }
203 catch(std::bad_alloc&)
204 {
205 return error(GL_OUT_OF_MEMORY);
206 }
207}
208
209void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
210{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000211 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000212
213 try
214 {
215 if (target != GL_RENDERBUFFER)
216 {
217 return error(GL_INVALID_ENUM);
218 }
219
220 gl::Context *context = gl::getContext();
221
222 if (context)
223 {
224 context->bindRenderbuffer(renderbuffer);
225 }
226 }
227 catch(std::bad_alloc&)
228 {
229 return error(GL_OUT_OF_MEMORY);
230 }
231}
232
233void __stdcall glBindTexture(GLenum target, GLuint texture)
234{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000235 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000236
237 try
238 {
239 gl::Context *context = gl::getContext();
240
241 if (context)
242 {
243 gl::Texture *textureObject = context->getTexture(texture);
244
245 if (textureObject && textureObject->getTarget() != target && texture != 0)
246 {
247 return error(GL_INVALID_OPERATION);
248 }
249
250 switch (target)
251 {
252 case GL_TEXTURE_2D:
253 context->bindTexture2D(texture);
254 return;
255 case GL_TEXTURE_CUBE_MAP:
256 context->bindTextureCubeMap(texture);
257 return;
258 default:
259 return error(GL_INVALID_ENUM);
260 }
261 }
262 }
263 catch(std::bad_alloc&)
264 {
265 return error(GL_OUT_OF_MEMORY);
266 }
267}
268
269void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
270{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000271 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
272 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000273
274 try
275 {
276 gl::Context* context = gl::getContext();
277
278 if (context)
279 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000280 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000281 }
282 }
283 catch(std::bad_alloc&)
284 {
285 return error(GL_OUT_OF_MEMORY);
286 }
287}
288
289void __stdcall glBlendEquation(GLenum mode)
290{
291 glBlendEquationSeparate(mode, mode);
292}
293
294void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
295{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000296 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000297
298 try
299 {
300 switch (modeRGB)
301 {
302 case GL_FUNC_ADD:
303 case GL_FUNC_SUBTRACT:
304 case GL_FUNC_REVERSE_SUBTRACT:
305 break;
306 default:
307 return error(GL_INVALID_ENUM);
308 }
309
310 switch (modeAlpha)
311 {
312 case GL_FUNC_ADD:
313 case GL_FUNC_SUBTRACT:
314 case GL_FUNC_REVERSE_SUBTRACT:
315 break;
316 default:
317 return error(GL_INVALID_ENUM);
318 }
319
320 gl::Context *context = gl::getContext();
321
322 if (context)
323 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000324 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000325 }
326 }
327 catch(std::bad_alloc&)
328 {
329 return error(GL_OUT_OF_MEMORY);
330 }
331}
332
333void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
334{
335 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
336}
337
338void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
339{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000340 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
341 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000342
343 try
344 {
345 switch (srcRGB)
346 {
347 case GL_ZERO:
348 case GL_ONE:
349 case GL_SRC_COLOR:
350 case GL_ONE_MINUS_SRC_COLOR:
351 case GL_DST_COLOR:
352 case GL_ONE_MINUS_DST_COLOR:
353 case GL_SRC_ALPHA:
354 case GL_ONE_MINUS_SRC_ALPHA:
355 case GL_DST_ALPHA:
356 case GL_ONE_MINUS_DST_ALPHA:
357 case GL_CONSTANT_COLOR:
358 case GL_ONE_MINUS_CONSTANT_COLOR:
359 case GL_CONSTANT_ALPHA:
360 case GL_ONE_MINUS_CONSTANT_ALPHA:
361 case GL_SRC_ALPHA_SATURATE:
362 break;
363 default:
364 return error(GL_INVALID_ENUM);
365 }
366
367 switch (dstRGB)
368 {
369 case GL_ZERO:
370 case GL_ONE:
371 case GL_SRC_COLOR:
372 case GL_ONE_MINUS_SRC_COLOR:
373 case GL_DST_COLOR:
374 case GL_ONE_MINUS_DST_COLOR:
375 case GL_SRC_ALPHA:
376 case GL_ONE_MINUS_SRC_ALPHA:
377 case GL_DST_ALPHA:
378 case GL_ONE_MINUS_DST_ALPHA:
379 case GL_CONSTANT_COLOR:
380 case GL_ONE_MINUS_CONSTANT_COLOR:
381 case GL_CONSTANT_ALPHA:
382 case GL_ONE_MINUS_CONSTANT_ALPHA:
383 break;
384 default:
385 return error(GL_INVALID_ENUM);
386 }
387
388 switch (srcAlpha)
389 {
390 case GL_ZERO:
391 case GL_ONE:
392 case GL_SRC_COLOR:
393 case GL_ONE_MINUS_SRC_COLOR:
394 case GL_DST_COLOR:
395 case GL_ONE_MINUS_DST_COLOR:
396 case GL_SRC_ALPHA:
397 case GL_ONE_MINUS_SRC_ALPHA:
398 case GL_DST_ALPHA:
399 case GL_ONE_MINUS_DST_ALPHA:
400 case GL_CONSTANT_COLOR:
401 case GL_ONE_MINUS_CONSTANT_COLOR:
402 case GL_CONSTANT_ALPHA:
403 case GL_ONE_MINUS_CONSTANT_ALPHA:
404 case GL_SRC_ALPHA_SATURATE:
405 break;
406 default:
407 return error(GL_INVALID_ENUM);
408 }
409
410 switch (dstAlpha)
411 {
412 case GL_ZERO:
413 case GL_ONE:
414 case GL_SRC_COLOR:
415 case GL_ONE_MINUS_SRC_COLOR:
416 case GL_DST_COLOR:
417 case GL_ONE_MINUS_DST_COLOR:
418 case GL_SRC_ALPHA:
419 case GL_ONE_MINUS_SRC_ALPHA:
420 case GL_DST_ALPHA:
421 case GL_ONE_MINUS_DST_ALPHA:
422 case GL_CONSTANT_COLOR:
423 case GL_ONE_MINUS_CONSTANT_COLOR:
424 case GL_CONSTANT_ALPHA:
425 case GL_ONE_MINUS_CONSTANT_ALPHA:
426 break;
427 default:
428 return error(GL_INVALID_ENUM);
429 }
430
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000431 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
432 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
433
434 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
435 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
436
437 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000438 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000439 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
440 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000441 }
442
443 gl::Context *context = gl::getContext();
444
445 if (context)
446 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000447 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000448 }
449 }
450 catch(std::bad_alloc&)
451 {
452 return error(GL_OUT_OF_MEMORY);
453 }
454}
455
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000456void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000457{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000458 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 +0000459 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000460
461 try
462 {
463 if (size < 0)
464 {
465 return error(GL_INVALID_VALUE);
466 }
467
468 switch (usage)
469 {
470 case GL_STREAM_DRAW:
471 case GL_STATIC_DRAW:
472 case GL_DYNAMIC_DRAW:
473 break;
474 default:
475 return error(GL_INVALID_ENUM);
476 }
477
478 gl::Context *context = gl::getContext();
479
480 if (context)
481 {
482 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000483
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000484 switch (target)
485 {
486 case GL_ARRAY_BUFFER:
487 buffer = context->getArrayBuffer();
488 break;
489 case GL_ELEMENT_ARRAY_BUFFER:
490 buffer = context->getElementArrayBuffer();
491 break;
492 default:
493 return error(GL_INVALID_ENUM);
494 }
495
496 if (!buffer)
497 {
498 return error(GL_INVALID_OPERATION);
499 }
500
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000501 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000502 }
503 }
504 catch(std::bad_alloc&)
505 {
506 return error(GL_OUT_OF_MEMORY);
507 }
508}
509
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000510void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000511{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000512 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 +0000513 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000514
515 try
516 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000517 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000518 {
519 return error(GL_INVALID_VALUE);
520 }
521
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000522 if (data == NULL)
523 {
524 return;
525 }
526
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000527 gl::Context *context = gl::getContext();
528
529 if (context)
530 {
531 gl::Buffer *buffer;
532
533 switch (target)
534 {
535 case GL_ARRAY_BUFFER:
536 buffer = context->getArrayBuffer();
537 break;
538 case GL_ELEMENT_ARRAY_BUFFER:
539 buffer = context->getElementArrayBuffer();
540 break;
541 default:
542 return error(GL_INVALID_ENUM);
543 }
544
545 if (!buffer)
546 {
547 return error(GL_INVALID_OPERATION);
548 }
549
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000550 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000551 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000552 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000553 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000554
555 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000556 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000557 }
558 catch(std::bad_alloc&)
559 {
560 return error(GL_OUT_OF_MEMORY);
561 }
562}
563
564GLenum __stdcall glCheckFramebufferStatus(GLenum target)
565{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000566 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000567
568 try
569 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000570 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000571 {
572 return error(GL_INVALID_ENUM, 0);
573 }
574
575 gl::Context *context = gl::getContext();
576
577 if (context)
578 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000579 gl::Framebuffer *framebuffer = NULL;
580 if (target == GL_READ_FRAMEBUFFER_ANGLE)
581 {
582 framebuffer = context->getReadFramebuffer();
583 }
584 else
585 {
586 framebuffer = context->getDrawFramebuffer();
587 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000588
589 return framebuffer->completeness();
590 }
591 }
592 catch(std::bad_alloc&)
593 {
594 return error(GL_OUT_OF_MEMORY, 0);
595 }
596
597 return 0;
598}
599
600void __stdcall glClear(GLbitfield mask)
601{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000602 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000603
604 try
605 {
606 gl::Context *context = gl::getContext();
607
608 if (context)
609 {
610 context->clear(mask);
611 }
612 }
613 catch(std::bad_alloc&)
614 {
615 return error(GL_OUT_OF_MEMORY);
616 }
617}
618
619void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
620{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000621 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
622 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000623
624 try
625 {
626 gl::Context *context = gl::getContext();
627
628 if (context)
629 {
630 context->setClearColor(red, green, blue, alpha);
631 }
632 }
633 catch(std::bad_alloc&)
634 {
635 return error(GL_OUT_OF_MEMORY);
636 }
637}
638
639void __stdcall glClearDepthf(GLclampf depth)
640{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000641 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000642
643 try
644 {
645 gl::Context *context = gl::getContext();
646
647 if (context)
648 {
649 context->setClearDepth(depth);
650 }
651 }
652 catch(std::bad_alloc&)
653 {
654 return error(GL_OUT_OF_MEMORY);
655 }
656}
657
658void __stdcall glClearStencil(GLint s)
659{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000660 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000661
662 try
663 {
664 gl::Context *context = gl::getContext();
665
666 if (context)
667 {
668 context->setClearStencil(s);
669 }
670 }
671 catch(std::bad_alloc&)
672 {
673 return error(GL_OUT_OF_MEMORY);
674 }
675}
676
677void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
678{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000679 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
680 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000681
682 try
683 {
684 gl::Context *context = gl::getContext();
685
686 if (context)
687 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000688 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000689 }
690 }
691 catch(std::bad_alloc&)
692 {
693 return error(GL_OUT_OF_MEMORY);
694 }
695}
696
697void __stdcall glCompileShader(GLuint shader)
698{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000699 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000700
701 try
702 {
703 gl::Context *context = gl::getContext();
704
705 if (context)
706 {
707 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000708
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000709 if (!shaderObject)
710 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000711 if (context->getProgram(shader))
712 {
713 return error(GL_INVALID_OPERATION);
714 }
715 else
716 {
717 return error(GL_INVALID_VALUE);
718 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000719 }
720
721 shaderObject->compile();
722 }
723 }
724 catch(std::bad_alloc&)
725 {
726 return error(GL_OUT_OF_MEMORY);
727 }
728}
729
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000730void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
731 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000732{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000733 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000734 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000735 target, level, internalformat, width, height, border, imageSize, data);
736
737 try
738 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000739 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000740 {
741 return error(GL_INVALID_VALUE);
742 }
743
daniel@transgaming.com41430492010-03-11 20:36:18 +0000744 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
745 {
746 return error(GL_INVALID_VALUE);
747 }
748
daniel@transgaming.com01868132010-08-24 19:21:17 +0000749 switch (target)
750 {
751 case GL_TEXTURE_2D:
752 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
753 {
754 return error(GL_INVALID_VALUE);
755 }
756 break;
757 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
758 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
759 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
760 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
761 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
762 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
763 if (width != height)
764 {
765 return error(GL_INVALID_VALUE);
766 }
767
768 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
769 {
770 return error(GL_INVALID_VALUE);
771 }
772 break;
773 default:
774 return error(GL_INVALID_ENUM);
775 }
776
777 switch (internalformat)
778 {
779 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
780 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
781 break;
782 default:
783 return error(GL_INVALID_ENUM);
784 }
785
786 if (border != 0)
787 {
788 return error(GL_INVALID_VALUE);
789 }
790
791 gl::Context *context = gl::getContext();
792
793 if (context)
794 {
795 if (!context->supportsCompressedTextures())
796 {
797 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
798 }
799
800 if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
801 {
802 return error(GL_INVALID_VALUE);
803 }
804
805 if (target == GL_TEXTURE_2D)
806 {
807 gl::Texture2D *texture = context->getTexture2D();
808
809 if (!texture)
810 {
811 return error(GL_INVALID_OPERATION);
812 }
813
814 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
815 }
816 else
817 {
818 gl::TextureCubeMap *texture = context->getTextureCubeMap();
819
820 if (!texture)
821 {
822 return error(GL_INVALID_OPERATION);
823 }
824
825 switch (target)
826 {
827 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
828 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
829 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
830 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
831 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
832 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
833 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
834 break;
835 default: UNREACHABLE();
836 }
837 }
838 }
839
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000840 }
841 catch(std::bad_alloc&)
842 {
843 return error(GL_OUT_OF_MEMORY);
844 }
845}
846
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000847void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
848 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000849{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000850 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
851 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000852 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000853 target, level, xoffset, yoffset, width, height, format, imageSize, data);
854
855 try
856 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000857 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000858 {
859 return error(GL_INVALID_ENUM);
860 }
861
862 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000863 {
864 return error(GL_INVALID_VALUE);
865 }
866
daniel@transgaming.com01868132010-08-24 19:21:17 +0000867 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 ||
868 (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000869 {
870 return error(GL_INVALID_VALUE);
871 }
872
daniel@transgaming.com01868132010-08-24 19:21:17 +0000873 switch (format)
daniel@transgaming.com41430492010-03-11 20:36:18 +0000874 {
daniel@transgaming.com01868132010-08-24 19:21:17 +0000875 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
876 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
877 break;
878 default:
879 return error(GL_INVALID_ENUM);
daniel@transgaming.com41430492010-03-11 20:36:18 +0000880 }
881
daniel@transgaming.com01868132010-08-24 19:21:17 +0000882 if (width == 0 || height == 0 || data == NULL)
883 {
884 return;
885 }
886
887 gl::Context *context = gl::getContext();
888
889 if (context)
890 {
891 if (!context->supportsCompressedTextures())
892 {
893 return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
894 }
895
896 if (imageSize != gl::ComputeCompressedSize(width, height, format))
897 {
898 return error(GL_INVALID_VALUE);
899 }
900
901 if (xoffset % 4 != 0 || yoffset % 4 != 0)
902 {
903 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
904 // does not exist unless DXT1 textures are supported.
905 }
906
907 if (target == GL_TEXTURE_2D)
908 {
909 gl::Texture2D *texture = context->getTexture2D();
910
911 if (!texture)
912 {
913 return error(GL_INVALID_OPERATION);
914 }
915
916 if (!texture->isCompressed())
917 {
918 return error(GL_INVALID_OPERATION);
919 }
920
921 if ((width % 4 != 0 && width != texture->getWidth()) ||
922 (height % 4 != 0 && height != texture->getHeight()))
923 {
924 return error(GL_INVALID_OPERATION);
925 }
926
927 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
928 }
929 else if (gl::IsCubemapTextureTarget(target))
930 {
931 gl::TextureCubeMap *texture = context->getTextureCubeMap();
932
933 if (!texture)
934 {
935 return error(GL_INVALID_OPERATION);
936 }
937
938 if (!texture->isCompressed())
939 {
940 return error(GL_INVALID_OPERATION);
941 }
942
943 if ((width % 4 != 0 && width != texture->getWidth()) ||
944 (height % 4 != 0 && height != texture->getHeight()))
945 {
946 return error(GL_INVALID_OPERATION);
947 }
948
949 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
950 }
951 else
952 {
953 UNREACHABLE();
954 }
955 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000956 }
957 catch(std::bad_alloc&)
958 {
959 return error(GL_OUT_OF_MEMORY);
960 }
961}
962
963void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
964{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000965 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
966 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000967 target, level, internalformat, x, y, width, height, border);
968
969 try
970 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000971 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000972 {
973 return error(GL_INVALID_VALUE);
974 }
975
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000976 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
977 {
978 return error(GL_INVALID_VALUE);
979 }
980
981 switch (target)
982 {
983 case GL_TEXTURE_2D:
984 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
985 {
986 return error(GL_INVALID_VALUE);
987 }
988 break;
989 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
990 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
991 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
992 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
993 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
994 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +0000995 if (width != height)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000996 {
997 return error(GL_INVALID_VALUE);
998 }
999
1000 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
1001 {
1002 return error(GL_INVALID_VALUE);
1003 }
1004 break;
1005 default:
1006 return error(GL_INVALID_ENUM);
1007 }
1008
1009 switch (internalformat)
1010 {
1011 case GL_ALPHA:
1012 case GL_LUMINANCE:
1013 case GL_LUMINANCE_ALPHA:
1014 case GL_RGB:
1015 case GL_RGBA:
daniel@transgaming.com01868132010-08-24 19:21:17 +00001016 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // Compressed textures are not supported here, but if they are unsupported altogether,
1017 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 +00001018 break;
1019 default:
1020 return error(GL_INVALID_VALUE);
1021 }
1022
1023 if (border != 0)
1024 {
1025 return error(GL_INVALID_VALUE);
1026 }
1027
1028 gl::Context *context = gl::getContext();
1029
1030 if (context)
1031 {
daniel@transgaming.com01868132010-08-24 19:21:17 +00001032 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
1033 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
1034 {
1035 if (context->supportsCompressedTextures())
1036 {
1037 return error(GL_INVALID_OPERATION);
1038 }
1039 else
1040 {
1041 return error(GL_INVALID_ENUM);
1042 }
1043 }
1044
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001045 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001046 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1047 {
1048 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1049 }
1050
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001051 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1052 {
1053 return error(GL_INVALID_OPERATION);
1054 }
1055
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001056 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001057 if (target == GL_TEXTURE_2D)
1058 {
1059 gl::Texture2D *texture = context->getTexture2D();
1060
1061 if (!texture)
1062 {
1063 return error(GL_INVALID_OPERATION);
1064 }
daniel@transgaming.com01868132010-08-24 19:21:17 +00001065
1066 if (texture->isCompressed())
1067 {
1068 return error(GL_INVALID_OPERATION);
1069 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001070
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001071 if (texture->isFloatingPoint())
1072 {
1073 return error(GL_INVALID_OPERATION);
1074 }
1075
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001076 texture->copyImage(level, internalformat, x, y, width, height, source);
1077 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001078 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001079 {
1080 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1081
1082 if (!texture)
1083 {
1084 return error(GL_INVALID_OPERATION);
1085 }
1086
daniel@transgaming.com01868132010-08-24 19:21:17 +00001087 if (texture->isCompressed())
1088 {
1089 return error(GL_INVALID_OPERATION);
1090 }
1091
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001092 if (texture->isFloatingPoint())
1093 {
1094 return error(GL_INVALID_OPERATION);
1095 }
1096
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001097 texture->copyImage(target, level, internalformat, x, y, width, height, source);
1098 }
1099 else
1100 {
1101 UNREACHABLE();
1102 }
1103 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001104 }
1105 catch(std::bad_alloc&)
1106 {
1107 return error(GL_OUT_OF_MEMORY);
1108 }
1109}
1110
1111void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1112{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001113 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1114 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001115 target, level, xoffset, yoffset, x, y, width, height);
1116
1117 try
1118 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001119 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001120 {
1121 return error(GL_INVALID_ENUM);
1122 }
1123
1124 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001125 {
1126 return error(GL_INVALID_VALUE);
1127 }
1128
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001129 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1130 {
1131 return error(GL_INVALID_VALUE);
1132 }
1133
1134 if (width == 0 || height == 0)
1135 {
1136 return;
1137 }
1138
1139 gl::Context *context = gl::getContext();
1140
1141 if (context)
1142 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001143 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001144 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1145 {
1146 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1147 }
1148
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001149 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1150 {
1151 return error(GL_INVALID_OPERATION);
1152 }
1153
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001154 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001155 if (target == GL_TEXTURE_2D)
1156 {
1157 gl::Texture2D *texture = context->getTexture2D();
1158
1159 if (!texture)
1160 {
1161 return error(GL_INVALID_OPERATION);
1162 }
1163
daniel@transgaming.com01868132010-08-24 19:21:17 +00001164 if (texture->isCompressed())
1165 {
1166 return error(GL_INVALID_OPERATION);
1167 }
1168
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001169 if (texture->isFloatingPoint())
1170 {
1171 return error(GL_INVALID_OPERATION);
1172 }
1173
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001174 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
1175 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001176 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001177 {
1178 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1179
1180 if (!texture)
1181 {
1182 return error(GL_INVALID_OPERATION);
1183 }
1184
daniel@transgaming.com01868132010-08-24 19:21:17 +00001185 if (texture->isCompressed())
1186 {
1187 return error(GL_INVALID_OPERATION);
1188 }
1189
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00001190 if (texture->isFloatingPoint())
1191 {
1192 return error(GL_INVALID_OPERATION);
1193 }
1194
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001195 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
1196 }
1197 else
1198 {
1199 UNREACHABLE();
1200 }
1201 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001202 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001203
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001204 catch(std::bad_alloc&)
1205 {
1206 return error(GL_OUT_OF_MEMORY);
1207 }
1208}
1209
1210GLuint __stdcall glCreateProgram(void)
1211{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001212 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001213
1214 try
1215 {
1216 gl::Context *context = gl::getContext();
1217
1218 if (context)
1219 {
1220 return context->createProgram();
1221 }
1222 }
1223 catch(std::bad_alloc&)
1224 {
1225 return error(GL_OUT_OF_MEMORY, 0);
1226 }
1227
1228 return 0;
1229}
1230
1231GLuint __stdcall glCreateShader(GLenum type)
1232{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001233 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001234
1235 try
1236 {
1237 gl::Context *context = gl::getContext();
1238
1239 if (context)
1240 {
1241 switch (type)
1242 {
1243 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001244 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001245 return context->createShader(type);
1246 default:
1247 return error(GL_INVALID_ENUM, 0);
1248 }
1249 }
1250 }
1251 catch(std::bad_alloc&)
1252 {
1253 return error(GL_OUT_OF_MEMORY, 0);
1254 }
1255
1256 return 0;
1257}
1258
1259void __stdcall glCullFace(GLenum mode)
1260{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001261 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001262
1263 try
1264 {
1265 switch (mode)
1266 {
1267 case GL_FRONT:
1268 case GL_BACK:
1269 case GL_FRONT_AND_BACK:
1270 {
1271 gl::Context *context = gl::getContext();
1272
1273 if (context)
1274 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001275 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001276 }
1277 }
1278 break;
1279 default:
1280 return error(GL_INVALID_ENUM);
1281 }
1282 }
1283 catch(std::bad_alloc&)
1284 {
1285 return error(GL_OUT_OF_MEMORY);
1286 }
1287}
1288
1289void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1290{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001291 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001292
1293 try
1294 {
1295 if (n < 0)
1296 {
1297 return error(GL_INVALID_VALUE);
1298 }
1299
1300 gl::Context *context = gl::getContext();
1301
1302 if (context)
1303 {
1304 for (int i = 0; i < n; i++)
1305 {
1306 context->deleteBuffer(buffers[i]);
1307 }
1308 }
1309 }
1310 catch(std::bad_alloc&)
1311 {
1312 return error(GL_OUT_OF_MEMORY);
1313 }
1314}
1315
1316void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1317{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001318 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001319
1320 try
1321 {
1322 if (n < 0)
1323 {
1324 return error(GL_INVALID_VALUE);
1325 }
1326
1327 gl::Context *context = gl::getContext();
1328
1329 if (context)
1330 {
1331 for (int i = 0; i < n; i++)
1332 {
1333 if (framebuffers[i] != 0)
1334 {
1335 context->deleteFramebuffer(framebuffers[i]);
1336 }
1337 }
1338 }
1339 }
1340 catch(std::bad_alloc&)
1341 {
1342 return error(GL_OUT_OF_MEMORY);
1343 }
1344}
1345
1346void __stdcall glDeleteProgram(GLuint program)
1347{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001348 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001349
1350 try
1351 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001352 if (program == 0)
1353 {
1354 return;
1355 }
1356
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001357 gl::Context *context = gl::getContext();
1358
1359 if (context)
1360 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001361 if (!context->getProgram(program))
1362 {
1363 if(context->getShader(program))
1364 {
1365 return error(GL_INVALID_OPERATION);
1366 }
1367 else
1368 {
1369 return error(GL_INVALID_VALUE);
1370 }
1371 }
1372
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001373 context->deleteProgram(program);
1374 }
1375 }
1376 catch(std::bad_alloc&)
1377 {
1378 return error(GL_OUT_OF_MEMORY);
1379 }
1380}
1381
1382void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1383{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001384 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001385
1386 try
1387 {
1388 if (n < 0)
1389 {
1390 return error(GL_INVALID_VALUE);
1391 }
1392
1393 gl::Context *context = gl::getContext();
1394
1395 if (context)
1396 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001397 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001398 {
1399 context->deleteRenderbuffer(renderbuffers[i]);
1400 }
1401 }
1402 }
1403 catch(std::bad_alloc&)
1404 {
1405 return error(GL_OUT_OF_MEMORY);
1406 }
1407}
1408
1409void __stdcall glDeleteShader(GLuint shader)
1410{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001411 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001412
1413 try
1414 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001415 if (shader == 0)
1416 {
1417 return;
1418 }
1419
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001420 gl::Context *context = gl::getContext();
1421
1422 if (context)
1423 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001424 if (!context->getShader(shader))
1425 {
1426 if(context->getProgram(shader))
1427 {
1428 return error(GL_INVALID_OPERATION);
1429 }
1430 else
1431 {
1432 return error(GL_INVALID_VALUE);
1433 }
1434 }
1435
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001436 context->deleteShader(shader);
1437 }
1438 }
1439 catch(std::bad_alloc&)
1440 {
1441 return error(GL_OUT_OF_MEMORY);
1442 }
1443}
1444
1445void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1446{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001447 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001448
1449 try
1450 {
1451 if (n < 0)
1452 {
1453 return error(GL_INVALID_VALUE);
1454 }
1455
1456 gl::Context *context = gl::getContext();
1457
1458 if (context)
1459 {
1460 for (int i = 0; i < n; i++)
1461 {
1462 if (textures[i] != 0)
1463 {
1464 context->deleteTexture(textures[i]);
1465 }
1466 }
1467 }
1468 }
1469 catch(std::bad_alloc&)
1470 {
1471 return error(GL_OUT_OF_MEMORY);
1472 }
1473}
1474
1475void __stdcall glDepthFunc(GLenum func)
1476{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001477 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001478
1479 try
1480 {
1481 switch (func)
1482 {
1483 case GL_NEVER:
1484 case GL_ALWAYS:
1485 case GL_LESS:
1486 case GL_LEQUAL:
1487 case GL_EQUAL:
1488 case GL_GREATER:
1489 case GL_GEQUAL:
1490 case GL_NOTEQUAL:
1491 break;
1492 default:
1493 return error(GL_INVALID_ENUM);
1494 }
1495
1496 gl::Context *context = gl::getContext();
1497
1498 if (context)
1499 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001500 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001501 }
1502 }
1503 catch(std::bad_alloc&)
1504 {
1505 return error(GL_OUT_OF_MEMORY);
1506 }
1507}
1508
1509void __stdcall glDepthMask(GLboolean flag)
1510{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001511 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001512
1513 try
1514 {
1515 gl::Context *context = gl::getContext();
1516
1517 if (context)
1518 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001519 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001520 }
1521 }
1522 catch(std::bad_alloc&)
1523 {
1524 return error(GL_OUT_OF_MEMORY);
1525 }
1526}
1527
1528void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1529{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001530 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001531
1532 try
1533 {
1534 gl::Context *context = gl::getContext();
1535
1536 if (context)
1537 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001538 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001539 }
1540 }
1541 catch(std::bad_alloc&)
1542 {
1543 return error(GL_OUT_OF_MEMORY);
1544 }
1545}
1546
1547void __stdcall glDetachShader(GLuint program, GLuint shader)
1548{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001549 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001550
1551 try
1552 {
1553 gl::Context *context = gl::getContext();
1554
1555 if (context)
1556 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001557
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001558 gl::Program *programObject = context->getProgram(program);
1559 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001560
1561 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001562 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001563 gl::Shader *shaderByProgramHandle;
1564 shaderByProgramHandle = context->getShader(program);
1565 if (!shaderByProgramHandle)
1566 {
1567 return error(GL_INVALID_VALUE);
1568 }
1569 else
1570 {
1571 return error(GL_INVALID_OPERATION);
1572 }
1573 }
1574
1575 if (!shaderObject)
1576 {
1577 gl::Program *programByShaderHandle = context->getProgram(shader);
1578 if (!programByShaderHandle)
1579 {
1580 return error(GL_INVALID_VALUE);
1581 }
1582 else
1583 {
1584 return error(GL_INVALID_OPERATION);
1585 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001586 }
1587
1588 if (!programObject->detachShader(shaderObject))
1589 {
1590 return error(GL_INVALID_OPERATION);
1591 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001592 }
1593 }
1594 catch(std::bad_alloc&)
1595 {
1596 return error(GL_OUT_OF_MEMORY);
1597 }
1598}
1599
1600void __stdcall glDisable(GLenum cap)
1601{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001602 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001603
1604 try
1605 {
1606 gl::Context *context = gl::getContext();
1607
1608 if (context)
1609 {
1610 switch (cap)
1611 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001612 case GL_CULL_FACE: context->setCullFace(false); break;
1613 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1614 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1615 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1616 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1617 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1618 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1619 case GL_BLEND: context->setBlend(false); break;
1620 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001621 default:
1622 return error(GL_INVALID_ENUM);
1623 }
1624 }
1625 }
1626 catch(std::bad_alloc&)
1627 {
1628 return error(GL_OUT_OF_MEMORY);
1629 }
1630}
1631
1632void __stdcall glDisableVertexAttribArray(GLuint index)
1633{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001634 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001635
1636 try
1637 {
1638 if (index >= gl::MAX_VERTEX_ATTRIBS)
1639 {
1640 return error(GL_INVALID_VALUE);
1641 }
1642
1643 gl::Context *context = gl::getContext();
1644
1645 if (context)
1646 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001647 context->setVertexAttribEnabled(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001648 }
1649 }
1650 catch(std::bad_alloc&)
1651 {
1652 return error(GL_OUT_OF_MEMORY);
1653 }
1654}
1655
1656void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1657{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001658 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001659
1660 try
1661 {
1662 if (count < 0 || first < 0)
1663 {
1664 return error(GL_INVALID_VALUE);
1665 }
1666
1667 gl::Context *context = gl::getContext();
1668
1669 if (context)
1670 {
1671 context->drawArrays(mode, first, count);
1672 }
1673 }
1674 catch(std::bad_alloc&)
1675 {
1676 return error(GL_OUT_OF_MEMORY);
1677 }
1678}
1679
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001680void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001681{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001682 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 +00001683 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001684
1685 try
1686 {
1687 if (count < 0)
1688 {
1689 return error(GL_INVALID_VALUE);
1690 }
1691
1692 switch (type)
1693 {
1694 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001695 case GL_UNSIGNED_SHORT:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00001696 case GL_UNSIGNED_INT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001697 break;
1698 default:
1699 return error(GL_INVALID_ENUM);
1700 }
1701
1702 gl::Context *context = gl::getContext();
1703
1704 if (context)
1705 {
1706 context->drawElements(mode, count, type, indices);
1707 }
1708 }
1709 catch(std::bad_alloc&)
1710 {
1711 return error(GL_OUT_OF_MEMORY);
1712 }
1713}
1714
1715void __stdcall glEnable(GLenum cap)
1716{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001717 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001718
1719 try
1720 {
1721 gl::Context *context = gl::getContext();
1722
1723 if (context)
1724 {
1725 switch (cap)
1726 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001727 case GL_CULL_FACE: context->setCullFace(true); break;
1728 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1729 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1730 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1731 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1732 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1733 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1734 case GL_BLEND: context->setBlend(true); break;
1735 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001736 default:
1737 return error(GL_INVALID_ENUM);
1738 }
1739 }
1740 }
1741 catch(std::bad_alloc&)
1742 {
1743 return error(GL_OUT_OF_MEMORY);
1744 }
1745}
1746
1747void __stdcall glEnableVertexAttribArray(GLuint index)
1748{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001749 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001750
1751 try
1752 {
1753 if (index >= gl::MAX_VERTEX_ATTRIBS)
1754 {
1755 return error(GL_INVALID_VALUE);
1756 }
1757
1758 gl::Context *context = gl::getContext();
1759
1760 if (context)
1761 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001762 context->setVertexAttribEnabled(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001763 }
1764 }
1765 catch(std::bad_alloc&)
1766 {
1767 return error(GL_OUT_OF_MEMORY);
1768 }
1769}
1770
1771void __stdcall glFinish(void)
1772{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001773 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001774
1775 try
1776 {
1777 gl::Context *context = gl::getContext();
1778
1779 if (context)
1780 {
1781 context->finish();
1782 }
1783 }
1784 catch(std::bad_alloc&)
1785 {
1786 return error(GL_OUT_OF_MEMORY);
1787 }
1788}
1789
1790void __stdcall glFlush(void)
1791{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001792 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001793
1794 try
1795 {
1796 gl::Context *context = gl::getContext();
1797
1798 if (context)
1799 {
1800 context->flush();
1801 }
1802 }
1803 catch(std::bad_alloc&)
1804 {
1805 return error(GL_OUT_OF_MEMORY);
1806 }
1807}
1808
1809void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1810{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001811 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1812 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001813
1814 try
1815 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001816 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1817 || renderbuffertarget != GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001818 {
1819 return error(GL_INVALID_ENUM);
1820 }
1821
1822 gl::Context *context = gl::getContext();
1823
1824 if (context)
1825 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001826 gl::Framebuffer *framebuffer = NULL;
1827 GLuint framebufferHandle = 0;
1828 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1829 {
1830 framebuffer = context->getReadFramebuffer();
1831 framebufferHandle = context->getReadFramebufferHandle();
1832 }
1833 else
1834 {
1835 framebuffer = context->getDrawFramebuffer();
1836 framebufferHandle = context->getDrawFramebufferHandle();
1837 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001838
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001839 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001840 {
1841 return error(GL_INVALID_OPERATION);
1842 }
1843
1844 switch (attachment)
1845 {
1846 case GL_COLOR_ATTACHMENT0:
1847 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1848 break;
1849 case GL_DEPTH_ATTACHMENT:
1850 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1851 break;
1852 case GL_STENCIL_ATTACHMENT:
1853 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1854 break;
1855 default:
1856 return error(GL_INVALID_ENUM);
1857 }
1858 }
1859 }
1860 catch(std::bad_alloc&)
1861 {
1862 return error(GL_OUT_OF_MEMORY);
1863 }
1864}
1865
1866void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1867{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001868 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1869 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001870
1871 try
1872 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001873 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001874 {
1875 return error(GL_INVALID_ENUM);
1876 }
1877
1878 switch (attachment)
1879 {
1880 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001881 case GL_DEPTH_ATTACHMENT:
1882 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001883 break;
1884 default:
1885 return error(GL_INVALID_ENUM);
1886 }
1887
1888 gl::Context *context = gl::getContext();
1889
1890 if (context)
1891 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001892 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001893 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001894 textarget = GL_NONE;
1895 }
1896 else
1897 {
1898 gl::Texture *tex = context->getTexture(texture);
1899
1900 if (tex == NULL)
1901 {
1902 return error(GL_INVALID_OPERATION);
1903 }
1904
daniel@transgaming.com01868132010-08-24 19:21:17 +00001905 if (tex->isCompressed())
1906 {
1907 return error(GL_INVALID_OPERATION);
1908 }
1909
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001910 switch (textarget)
1911 {
1912 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001913 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001914 {
1915 return error(GL_INVALID_OPERATION);
1916 }
1917 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001918
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001919 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001920 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001921 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001922 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001923 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001924 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001925 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1926 {
1927 return error(GL_INVALID_OPERATION);
1928 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001929 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001930
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001931 default:
1932 return error(GL_INVALID_ENUM);
1933 }
1934
1935 if (level != 0)
1936 {
1937 return error(GL_INVALID_VALUE);
1938 }
1939 }
1940
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001941 gl::Framebuffer *framebuffer = NULL;
1942 GLuint framebufferHandle = 0;
1943 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1944 {
1945 framebuffer = context->getReadFramebuffer();
1946 framebufferHandle = context->getReadFramebufferHandle();
1947 }
1948 else
1949 {
1950 framebuffer = context->getDrawFramebuffer();
1951 framebufferHandle = context->getDrawFramebufferHandle();
1952 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001953
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001954 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001955 {
1956 return error(GL_INVALID_OPERATION);
1957 }
1958
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001959 switch (attachment)
1960 {
1961 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
1962 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
1963 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
1964 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001965 }
1966 }
1967 catch(std::bad_alloc&)
1968 {
1969 return error(GL_OUT_OF_MEMORY);
1970 }
1971}
1972
1973void __stdcall glFrontFace(GLenum mode)
1974{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001975 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001976
1977 try
1978 {
1979 switch (mode)
1980 {
1981 case GL_CW:
1982 case GL_CCW:
1983 {
1984 gl::Context *context = gl::getContext();
1985
1986 if (context)
1987 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001988 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001989 }
1990 }
1991 break;
1992 default:
1993 return error(GL_INVALID_ENUM);
1994 }
1995 }
1996 catch(std::bad_alloc&)
1997 {
1998 return error(GL_OUT_OF_MEMORY);
1999 }
2000}
2001
2002void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2003{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002004 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002005
2006 try
2007 {
2008 if (n < 0)
2009 {
2010 return error(GL_INVALID_VALUE);
2011 }
2012
2013 gl::Context *context = gl::getContext();
2014
2015 if (context)
2016 {
2017 for (int i = 0; i < n; i++)
2018 {
2019 buffers[i] = context->createBuffer();
2020 }
2021 }
2022 }
2023 catch(std::bad_alloc&)
2024 {
2025 return error(GL_OUT_OF_MEMORY);
2026 }
2027}
2028
2029void __stdcall glGenerateMipmap(GLenum target)
2030{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002031 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002032
2033 try
2034 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002035 gl::Context *context = gl::getContext();
2036
2037 if (context)
2038 {
2039 gl::Texture *texture;
2040
2041 switch (target)
2042 {
2043 case GL_TEXTURE_2D:
2044 texture = context->getTexture2D();
2045 break;
2046
2047 case GL_TEXTURE_CUBE_MAP:
2048 texture = context->getTextureCubeMap();
2049 break;
2050
2051 default:
2052 return error(GL_INVALID_ENUM);
2053 }
2054
daniel@transgaming.com01868132010-08-24 19:21:17 +00002055 if (texture->isCompressed())
2056 {
2057 return error(GL_INVALID_OPERATION);
2058 }
2059
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002060 texture->generateMipmaps();
2061 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002062 }
2063 catch(std::bad_alloc&)
2064 {
2065 return error(GL_OUT_OF_MEMORY);
2066 }
2067}
2068
2069void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2070{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002071 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002072
2073 try
2074 {
2075 if (n < 0)
2076 {
2077 return error(GL_INVALID_VALUE);
2078 }
2079
2080 gl::Context *context = gl::getContext();
2081
2082 if (context)
2083 {
2084 for (int i = 0; i < n; i++)
2085 {
2086 framebuffers[i] = context->createFramebuffer();
2087 }
2088 }
2089 }
2090 catch(std::bad_alloc&)
2091 {
2092 return error(GL_OUT_OF_MEMORY);
2093 }
2094}
2095
2096void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2097{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002098 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002099
2100 try
2101 {
2102 if (n < 0)
2103 {
2104 return error(GL_INVALID_VALUE);
2105 }
2106
2107 gl::Context *context = gl::getContext();
2108
2109 if (context)
2110 {
2111 for (int i = 0; i < n; i++)
2112 {
2113 renderbuffers[i] = context->createRenderbuffer();
2114 }
2115 }
2116 }
2117 catch(std::bad_alloc&)
2118 {
2119 return error(GL_OUT_OF_MEMORY);
2120 }
2121}
2122
2123void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2124{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002125 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002126
2127 try
2128 {
2129 if (n < 0)
2130 {
2131 return error(GL_INVALID_VALUE);
2132 }
2133
2134 gl::Context *context = gl::getContext();
2135
2136 if (context)
2137 {
2138 for (int i = 0; i < n; i++)
2139 {
2140 textures[i] = context->createTexture();
2141 }
2142 }
2143 }
2144 catch(std::bad_alloc&)
2145 {
2146 return error(GL_OUT_OF_MEMORY);
2147 }
2148}
2149
daniel@transgaming.com85423182010-04-22 13:35:27 +00002150void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002151{
daniel@transgaming.com85423182010-04-22 13:35:27 +00002152 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2153 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002154 program, index, bufsize, length, size, type, name);
2155
2156 try
2157 {
2158 if (bufsize < 0)
2159 {
2160 return error(GL_INVALID_VALUE);
2161 }
2162
daniel@transgaming.com85423182010-04-22 13:35:27 +00002163 gl::Context *context = gl::getContext();
2164
2165 if (context)
2166 {
2167 gl::Program *programObject = context->getProgram(program);
2168
2169 if (!programObject)
2170 {
2171 if (context->getShader(program))
2172 {
2173 return error(GL_INVALID_OPERATION);
2174 }
2175 else
2176 {
2177 return error(GL_INVALID_VALUE);
2178 }
2179 }
2180
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002181 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002182 {
2183 return error(GL_INVALID_VALUE);
2184 }
2185
2186 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2187 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002188 }
2189 catch(std::bad_alloc&)
2190 {
2191 return error(GL_OUT_OF_MEMORY);
2192 }
2193}
2194
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002195void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002196{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002197 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002198 "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 +00002199 program, index, bufsize, length, size, type, name);
2200
2201 try
2202 {
2203 if (bufsize < 0)
2204 {
2205 return error(GL_INVALID_VALUE);
2206 }
2207
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002208 gl::Context *context = gl::getContext();
2209
2210 if (context)
2211 {
2212 gl::Program *programObject = context->getProgram(program);
2213
2214 if (!programObject)
2215 {
2216 if (context->getShader(program))
2217 {
2218 return error(GL_INVALID_OPERATION);
2219 }
2220 else
2221 {
2222 return error(GL_INVALID_VALUE);
2223 }
2224 }
2225
2226 if (index >= (GLuint)programObject->getActiveUniformCount())
2227 {
2228 return error(GL_INVALID_VALUE);
2229 }
2230
2231 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2232 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002233 }
2234 catch(std::bad_alloc&)
2235 {
2236 return error(GL_OUT_OF_MEMORY);
2237 }
2238}
2239
2240void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2241{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002242 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2243 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002244
2245 try
2246 {
2247 if (maxcount < 0)
2248 {
2249 return error(GL_INVALID_VALUE);
2250 }
2251
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002252 gl::Context *context = gl::getContext();
2253
2254 if (context)
2255 {
2256 gl::Program *programObject = context->getProgram(program);
2257
2258 if (!programObject)
2259 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002260 if (context->getShader(program))
2261 {
2262 return error(GL_INVALID_OPERATION);
2263 }
2264 else
2265 {
2266 return error(GL_INVALID_VALUE);
2267 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002268 }
2269
2270 return programObject->getAttachedShaders(maxcount, count, shaders);
2271 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002272 }
2273 catch(std::bad_alloc&)
2274 {
2275 return error(GL_OUT_OF_MEMORY);
2276 }
2277}
2278
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002279int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002280{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002281 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002282
2283 try
2284 {
2285 gl::Context *context = gl::getContext();
2286
2287 if (context)
2288 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002289
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002290 gl::Program *programObject = context->getProgram(program);
2291
2292 if (!programObject)
2293 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002294 if (context->getShader(program))
2295 {
2296 return error(GL_INVALID_OPERATION, -1);
2297 }
2298 else
2299 {
2300 return error(GL_INVALID_VALUE, -1);
2301 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002302 }
2303
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002304 if (!programObject->isLinked())
2305 {
2306 return error(GL_INVALID_OPERATION, -1);
2307 }
2308
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002309 return programObject->getAttributeLocation(name);
2310 }
2311 }
2312 catch(std::bad_alloc&)
2313 {
2314 return error(GL_OUT_OF_MEMORY, -1);
2315 }
2316
2317 return -1;
2318}
2319
2320void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2321{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002322 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002323
2324 try
2325 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002326 gl::Context *context = gl::getContext();
2327
2328 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002329 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002330 if (!(context->getBooleanv(pname, params)))
2331 {
2332 GLenum nativeType;
2333 unsigned int numParams = 0;
2334 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2335 return error(GL_INVALID_ENUM);
2336
2337 if (numParams == 0)
2338 return; // it is known that the pname is valid, but there are no parameters to return
2339
2340 if (nativeType == GL_FLOAT)
2341 {
2342 GLfloat *floatParams = NULL;
2343 floatParams = new GLfloat[numParams];
2344
2345 context->getFloatv(pname, floatParams);
2346
2347 for (unsigned int i = 0; i < numParams; ++i)
2348 {
2349 if (floatParams[i] == 0.0f)
2350 params[i] = GL_FALSE;
2351 else
2352 params[i] = GL_TRUE;
2353 }
2354
2355 delete [] floatParams;
2356 }
2357 else if (nativeType == GL_INT)
2358 {
2359 GLint *intParams = NULL;
2360 intParams = new GLint[numParams];
2361
2362 context->getIntegerv(pname, intParams);
2363
2364 for (unsigned int i = 0; i < numParams; ++i)
2365 {
2366 if (intParams[i] == 0)
2367 params[i] = GL_FALSE;
2368 else
2369 params[i] = GL_TRUE;
2370 }
2371
2372 delete [] intParams;
2373 }
2374 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002375 }
2376 }
2377 catch(std::bad_alloc&)
2378 {
2379 return error(GL_OUT_OF_MEMORY);
2380 }
2381}
2382
2383void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2384{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002385 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 +00002386
2387 try
2388 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002389 gl::Context *context = gl::getContext();
2390
2391 if (context)
2392 {
2393 gl::Buffer *buffer;
2394
2395 switch (target)
2396 {
2397 case GL_ARRAY_BUFFER:
2398 buffer = context->getArrayBuffer();
2399 break;
2400 case GL_ELEMENT_ARRAY_BUFFER:
2401 buffer = context->getElementArrayBuffer();
2402 break;
2403 default: return error(GL_INVALID_ENUM);
2404 }
2405
2406 if (!buffer)
2407 {
2408 // A null buffer means that "0" is bound to the requested buffer target
2409 return error(GL_INVALID_OPERATION);
2410 }
2411
2412 switch (pname)
2413 {
2414 case GL_BUFFER_USAGE:
2415 *params = buffer->usage();
2416 break;
2417 case GL_BUFFER_SIZE:
2418 *params = buffer->size();
2419 break;
2420 default: return error(GL_INVALID_ENUM);
2421 }
2422 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002423 }
2424 catch(std::bad_alloc&)
2425 {
2426 return error(GL_OUT_OF_MEMORY);
2427 }
2428}
2429
2430GLenum __stdcall glGetError(void)
2431{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002432 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002433
2434 gl::Context *context = gl::getContext();
2435
2436 if (context)
2437 {
2438 return context->getError();
2439 }
2440
2441 return GL_NO_ERROR;
2442}
2443
2444void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2445{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002446 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002447
2448 try
2449 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002450 gl::Context *context = gl::getContext();
2451
2452 if (context)
2453 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002454 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002455 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002456 GLenum nativeType;
2457 unsigned int numParams = 0;
2458 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2459 return error(GL_INVALID_ENUM);
2460
2461 if (numParams == 0)
2462 return; // it is known that the pname is valid, but that there are no parameters to return.
2463
2464 if (nativeType == GL_BOOL)
2465 {
2466 GLboolean *boolParams = NULL;
2467 boolParams = new GLboolean[numParams];
2468
2469 context->getBooleanv(pname, boolParams);
2470
2471 for (unsigned int i = 0; i < numParams; ++i)
2472 {
2473 if (boolParams[i] == GL_FALSE)
2474 params[i] = 0.0f;
2475 else
2476 params[i] = 1.0f;
2477 }
2478
2479 delete [] boolParams;
2480 }
2481 else if (nativeType == GL_INT)
2482 {
2483 GLint *intParams = NULL;
2484 intParams = new GLint[numParams];
2485
2486 context->getIntegerv(pname, intParams);
2487
2488 for (unsigned int i = 0; i < numParams; ++i)
2489 {
2490 params[i] = (GLfloat)intParams[i];
2491 }
2492
2493 delete [] intParams;
2494 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002495 }
2496 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002497 }
2498 catch(std::bad_alloc&)
2499 {
2500 return error(GL_OUT_OF_MEMORY);
2501 }
2502}
2503
2504void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2505{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002506 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2507 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002508
2509 try
2510 {
2511 gl::Context *context = gl::getContext();
2512
2513 if (context)
2514 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002515 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002516 {
2517 return error(GL_INVALID_ENUM);
2518 }
2519
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002520 gl::Framebuffer *framebuffer = NULL;
2521 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2522 {
2523 if(context->getReadFramebufferHandle() == 0)
2524 {
2525 return error(GL_INVALID_OPERATION);
2526 }
2527
2528 framebuffer = context->getReadFramebuffer();
2529 }
2530 else
2531 {
2532 if (context->getDrawFramebufferHandle() == 0)
2533 {
2534 return error(GL_INVALID_OPERATION);
2535 }
2536
2537 framebuffer = context->getDrawFramebuffer();
2538 }
2539
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002540 GLenum attachmentType;
2541 GLuint attachmentHandle;
2542 switch (attachment)
2543 {
2544 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002545 attachmentType = framebuffer->getColorbufferType();
2546 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002547 break;
2548 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002549 attachmentType = framebuffer->getDepthbufferType();
2550 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002551 break;
2552 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002553 attachmentType = framebuffer->getStencilbufferType();
2554 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002555 break;
2556 default: return error(GL_INVALID_ENUM);
2557 }
2558
2559 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002560 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002561 {
2562 attachmentObjectType = attachmentType;
2563 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002564 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002565 {
2566 attachmentObjectType = GL_TEXTURE;
2567 }
2568 else UNREACHABLE();
2569
2570 switch (pname)
2571 {
2572 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2573 *params = attachmentObjectType;
2574 break;
2575 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2576 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2577 {
2578 *params = attachmentHandle;
2579 }
2580 else
2581 {
2582 return error(GL_INVALID_ENUM);
2583 }
2584 break;
2585 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2586 if (attachmentObjectType == GL_TEXTURE)
2587 {
2588 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2589 }
2590 else
2591 {
2592 return error(GL_INVALID_ENUM);
2593 }
2594 break;
2595 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2596 if (attachmentObjectType == GL_TEXTURE)
2597 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002598 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002599 {
2600 *params = attachmentType;
2601 }
2602 else
2603 {
2604 *params = 0;
2605 }
2606 }
2607 else
2608 {
2609 return error(GL_INVALID_ENUM);
2610 }
2611 break;
2612 default:
2613 return error(GL_INVALID_ENUM);
2614 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002615 }
2616 }
2617 catch(std::bad_alloc&)
2618 {
2619 return error(GL_OUT_OF_MEMORY);
2620 }
2621}
2622
2623void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2624{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002625 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002626
2627 try
2628 {
2629 gl::Context *context = gl::getContext();
2630
2631 if (context)
2632 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002633 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002634 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002635 GLenum nativeType;
2636 unsigned int numParams = 0;
2637 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2638 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002639
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002640 if (numParams == 0)
2641 return; // it is known that pname is valid, but there are no parameters to return
2642
2643 if (nativeType == GL_BOOL)
2644 {
2645 GLboolean *boolParams = NULL;
2646 boolParams = new GLboolean[numParams];
2647
2648 context->getBooleanv(pname, boolParams);
2649
2650 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002651 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002652 if (boolParams[i] == GL_FALSE)
2653 params[i] = 0;
2654 else
2655 params[i] = 1;
2656 }
2657
2658 delete [] boolParams;
2659 }
2660 else if (nativeType == GL_FLOAT)
2661 {
2662 GLfloat *floatParams = NULL;
2663 floatParams = new GLfloat[numParams];
2664
2665 context->getFloatv(pname, floatParams);
2666
2667 for (unsigned int i = 0; i < numParams; ++i)
2668 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002669 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 +00002670 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002671 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002672 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002673 else
2674 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 +00002675 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002676
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002677 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002678 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002679 }
2680 }
2681 }
2682 catch(std::bad_alloc&)
2683 {
2684 return error(GL_OUT_OF_MEMORY);
2685 }
2686}
2687
2688void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2689{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002690 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002691
2692 try
2693 {
2694 gl::Context *context = gl::getContext();
2695
2696 if (context)
2697 {
2698 gl::Program *programObject = context->getProgram(program);
2699
2700 if (!programObject)
2701 {
2702 return error(GL_INVALID_VALUE);
2703 }
2704
2705 switch (pname)
2706 {
2707 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002708 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002709 return;
2710 case GL_LINK_STATUS:
2711 *params = programObject->isLinked();
2712 return;
2713 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002714 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002715 return;
2716 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002717 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002718 return;
2719 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002720 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002721 return;
2722 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002723 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002724 return;
2725 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002726 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002727 return;
2728 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002729 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002730 return;
2731 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002732 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002733 return;
2734 default:
2735 return error(GL_INVALID_ENUM);
2736 }
2737 }
2738 }
2739 catch(std::bad_alloc&)
2740 {
2741 return error(GL_OUT_OF_MEMORY);
2742 }
2743}
2744
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002745void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002746{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002747 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 +00002748 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002749
2750 try
2751 {
2752 if (bufsize < 0)
2753 {
2754 return error(GL_INVALID_VALUE);
2755 }
2756
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002757 gl::Context *context = gl::getContext();
2758
2759 if (context)
2760 {
2761 gl::Program *programObject = context->getProgram(program);
2762
2763 if (!programObject)
2764 {
2765 return error(GL_INVALID_VALUE);
2766 }
2767
2768 programObject->getInfoLog(bufsize, length, infolog);
2769 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002770 }
2771 catch(std::bad_alloc&)
2772 {
2773 return error(GL_OUT_OF_MEMORY);
2774 }
2775}
2776
2777void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2778{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002779 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 +00002780
2781 try
2782 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002783 gl::Context *context = gl::getContext();
2784
2785 if (context)
2786 {
2787 if (target != GL_RENDERBUFFER)
2788 {
2789 return error(GL_INVALID_ENUM);
2790 }
2791
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002792 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002793 {
2794 return error(GL_INVALID_OPERATION);
2795 }
2796
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002797 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002798
2799 switch (pname)
2800 {
2801 case GL_RENDERBUFFER_WIDTH:
2802 *params = renderbuffer->getWidth();
2803 break;
2804 case GL_RENDERBUFFER_HEIGHT:
2805 *params = renderbuffer->getHeight();
2806 break;
2807 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2808 *params = renderbuffer->getFormat();
2809 break;
2810 case GL_RENDERBUFFER_RED_SIZE:
2811 if (renderbuffer->isColorbuffer())
2812 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002813 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002814 }
2815 else
2816 {
2817 *params = 0;
2818 }
2819 break;
2820 case GL_RENDERBUFFER_GREEN_SIZE:
2821 if (renderbuffer->isColorbuffer())
2822 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002823 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002824 }
2825 else
2826 {
2827 *params = 0;
2828 }
2829 break;
2830 case GL_RENDERBUFFER_BLUE_SIZE:
2831 if (renderbuffer->isColorbuffer())
2832 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002833 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002834 }
2835 else
2836 {
2837 *params = 0;
2838 }
2839 break;
2840 case GL_RENDERBUFFER_ALPHA_SIZE:
2841 if (renderbuffer->isColorbuffer())
2842 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002843 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002844 }
2845 else
2846 {
2847 *params = 0;
2848 }
2849 break;
2850 case GL_RENDERBUFFER_DEPTH_SIZE:
2851 if (renderbuffer->isDepthbuffer())
2852 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002853 *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002854 }
2855 else
2856 {
2857 *params = 0;
2858 }
2859 break;
2860 case GL_RENDERBUFFER_STENCIL_SIZE:
2861 if (renderbuffer->isStencilbuffer())
2862 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002863 *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002864 }
2865 else
2866 {
2867 *params = 0;
2868 }
2869 break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002870 case GL_RENDERBUFFER_SAMPLES_ANGLE:
2871 {
2872 if (context->getMaxSupportedSamples() != 0)
2873 {
2874 *params = renderbuffer->getStorage()->getSamples();
2875 }
2876 else
2877 {
2878 return error(GL_INVALID_ENUM);
2879 }
2880 }
2881 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002882 default:
2883 return error(GL_INVALID_ENUM);
2884 }
2885 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002886 }
2887 catch(std::bad_alloc&)
2888 {
2889 return error(GL_OUT_OF_MEMORY);
2890 }
2891}
2892
2893void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2894{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002895 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002896
2897 try
2898 {
2899 gl::Context *context = gl::getContext();
2900
2901 if (context)
2902 {
2903 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002904
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002905 if (!shaderObject)
2906 {
2907 return error(GL_INVALID_VALUE);
2908 }
2909
2910 switch (pname)
2911 {
2912 case GL_SHADER_TYPE:
2913 *params = shaderObject->getType();
2914 return;
2915 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002916 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002917 return;
2918 case GL_COMPILE_STATUS:
2919 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2920 return;
2921 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002922 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002923 return;
2924 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002925 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002926 return;
2927 default:
2928 return error(GL_INVALID_ENUM);
2929 }
2930 }
2931 }
2932 catch(std::bad_alloc&)
2933 {
2934 return error(GL_OUT_OF_MEMORY);
2935 }
2936}
2937
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002938void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002939{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002940 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 +00002941 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002942
2943 try
2944 {
2945 if (bufsize < 0)
2946 {
2947 return error(GL_INVALID_VALUE);
2948 }
2949
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002950 gl::Context *context = gl::getContext();
2951
2952 if (context)
2953 {
2954 gl::Shader *shaderObject = context->getShader(shader);
2955
2956 if (!shaderObject)
2957 {
2958 return error(GL_INVALID_VALUE);
2959 }
2960
2961 shaderObject->getInfoLog(bufsize, length, infolog);
2962 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002963 }
2964 catch(std::bad_alloc&)
2965 {
2966 return error(GL_OUT_OF_MEMORY);
2967 }
2968}
2969
2970void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2971{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002972 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2973 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002974
2975 try
2976 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002977 switch (shadertype)
2978 {
2979 case GL_VERTEX_SHADER:
2980 case GL_FRAGMENT_SHADER:
2981 break;
2982 default:
2983 return error(GL_INVALID_ENUM);
2984 }
2985
2986 switch (precisiontype)
2987 {
2988 case GL_LOW_FLOAT:
2989 case GL_MEDIUM_FLOAT:
2990 case GL_HIGH_FLOAT:
2991 // Assume IEEE 754 precision
2992 range[0] = 127;
2993 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002994 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002995 break;
2996 case GL_LOW_INT:
2997 case GL_MEDIUM_INT:
2998 case GL_HIGH_INT:
2999 // Some (most) hardware only supports single-precision floating-point numbers,
3000 // which can accurately represent integers up to +/-16777216
3001 range[0] = 24;
3002 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00003003 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00003004 break;
3005 default:
3006 return error(GL_INVALID_ENUM);
3007 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003008 }
3009 catch(std::bad_alloc&)
3010 {
3011 return error(GL_OUT_OF_MEMORY);
3012 }
3013}
3014
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003015void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003016{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003017 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 +00003018 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003019
3020 try
3021 {
3022 if (bufsize < 0)
3023 {
3024 return error(GL_INVALID_VALUE);
3025 }
3026
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003027 gl::Context *context = gl::getContext();
3028
3029 if (context)
3030 {
3031 gl::Shader *shaderObject = context->getShader(shader);
3032
3033 if (!shaderObject)
3034 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003035 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003036 }
3037
3038 shaderObject->getSource(bufsize, length, source);
3039 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003040 }
3041 catch(std::bad_alloc&)
3042 {
3043 return error(GL_OUT_OF_MEMORY);
3044 }
3045}
3046
3047const GLubyte* __stdcall glGetString(GLenum name)
3048{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003049 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003050
3051 try
3052 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003053 gl::Context *context = gl::getContext();
3054
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003055 switch (name)
3056 {
3057 case GL_VENDOR:
3058 return (GLubyte*)"TransGaming Inc.";
3059 case GL_RENDERER:
3060 return (GLubyte*)"ANGLE";
3061 case GL_VERSION:
3062 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
3063 case GL_SHADING_LANGUAGE_VERSION:
3064 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
3065 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003066 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003067 default:
3068 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3069 }
3070 }
3071 catch(std::bad_alloc&)
3072 {
3073 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3074 }
3075
3076 return NULL;
3077}
3078
3079void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3080{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003081 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 +00003082
3083 try
3084 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003085 gl::Context *context = gl::getContext();
3086
3087 if (context)
3088 {
3089 gl::Texture *texture;
3090
3091 switch (target)
3092 {
3093 case GL_TEXTURE_2D:
3094 texture = context->getTexture2D();
3095 break;
3096 case GL_TEXTURE_CUBE_MAP:
3097 texture = context->getTextureCubeMap();
3098 break;
3099 default:
3100 return error(GL_INVALID_ENUM);
3101 }
3102
3103 switch (pname)
3104 {
3105 case GL_TEXTURE_MAG_FILTER:
3106 *params = (GLfloat)texture->getMagFilter();
3107 break;
3108 case GL_TEXTURE_MIN_FILTER:
3109 *params = (GLfloat)texture->getMinFilter();
3110 break;
3111 case GL_TEXTURE_WRAP_S:
3112 *params = (GLfloat)texture->getWrapS();
3113 break;
3114 case GL_TEXTURE_WRAP_T:
3115 *params = (GLfloat)texture->getWrapT();
3116 break;
3117 default:
3118 return error(GL_INVALID_ENUM);
3119 }
3120 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003121 }
3122 catch(std::bad_alloc&)
3123 {
3124 return error(GL_OUT_OF_MEMORY);
3125 }
3126}
3127
3128void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3129{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003130 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 +00003131
3132 try
3133 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003134 gl::Context *context = gl::getContext();
3135
3136 if (context)
3137 {
3138 gl::Texture *texture;
3139
3140 switch (target)
3141 {
3142 case GL_TEXTURE_2D:
3143 texture = context->getTexture2D();
3144 break;
3145 case GL_TEXTURE_CUBE_MAP:
3146 texture = context->getTextureCubeMap();
3147 break;
3148 default:
3149 return error(GL_INVALID_ENUM);
3150 }
3151
3152 switch (pname)
3153 {
3154 case GL_TEXTURE_MAG_FILTER:
3155 *params = texture->getMagFilter();
3156 break;
3157 case GL_TEXTURE_MIN_FILTER:
3158 *params = texture->getMinFilter();
3159 break;
3160 case GL_TEXTURE_WRAP_S:
3161 *params = texture->getWrapS();
3162 break;
3163 case GL_TEXTURE_WRAP_T:
3164 *params = texture->getWrapT();
3165 break;
3166 default:
3167 return error(GL_INVALID_ENUM);
3168 }
3169 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003170 }
3171 catch(std::bad_alloc&)
3172 {
3173 return error(GL_OUT_OF_MEMORY);
3174 }
3175}
3176
3177void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3178{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003179 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003180
3181 try
3182 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003183 gl::Context *context = gl::getContext();
3184
3185 if (context)
3186 {
3187 if (program == 0)
3188 {
3189 return error(GL_INVALID_VALUE);
3190 }
3191
3192 gl::Program *programObject = context->getProgram(program);
3193
3194 if (!programObject || !programObject->isLinked())
3195 {
3196 return error(GL_INVALID_OPERATION);
3197 }
3198
3199 if (!programObject->getUniformfv(location, params))
3200 {
3201 return error(GL_INVALID_OPERATION);
3202 }
3203 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003204 }
3205 catch(std::bad_alloc&)
3206 {
3207 return error(GL_OUT_OF_MEMORY);
3208 }
3209}
3210
3211void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3212{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003213 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003214
3215 try
3216 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003217 gl::Context *context = gl::getContext();
3218
3219 if (context)
3220 {
3221 if (program == 0)
3222 {
3223 return error(GL_INVALID_VALUE);
3224 }
3225
3226 gl::Program *programObject = context->getProgram(program);
3227
3228 if (!programObject || !programObject->isLinked())
3229 {
3230 return error(GL_INVALID_OPERATION);
3231 }
3232
3233 if (!programObject)
3234 {
3235 return error(GL_INVALID_OPERATION);
3236 }
3237
3238 if (!programObject->getUniformiv(location, params))
3239 {
3240 return error(GL_INVALID_OPERATION);
3241 }
3242 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003243 }
3244 catch(std::bad_alloc&)
3245 {
3246 return error(GL_OUT_OF_MEMORY);
3247 }
3248}
3249
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003250int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003251{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003252 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003253
3254 try
3255 {
3256 gl::Context *context = gl::getContext();
3257
3258 if (strstr(name, "gl_") == name)
3259 {
3260 return -1;
3261 }
3262
3263 if (context)
3264 {
3265 gl::Program *programObject = context->getProgram(program);
3266
3267 if (!programObject)
3268 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003269 if (context->getShader(program))
3270 {
3271 return error(GL_INVALID_OPERATION, -1);
3272 }
3273 else
3274 {
3275 return error(GL_INVALID_VALUE, -1);
3276 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003277 }
3278
3279 if (!programObject->isLinked())
3280 {
3281 return error(GL_INVALID_OPERATION, -1);
3282 }
3283
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003284 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003285 }
3286 }
3287 catch(std::bad_alloc&)
3288 {
3289 return error(GL_OUT_OF_MEMORY, -1);
3290 }
3291
3292 return -1;
3293}
3294
3295void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3296{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003297 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003298
3299 try
3300 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003301 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003302
daniel@transgaming.come0078962010-04-15 20:45:08 +00003303 if (context)
3304 {
3305 if (index >= gl::MAX_VERTEX_ATTRIBS)
3306 {
3307 return error(GL_INVALID_VALUE);
3308 }
3309
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003310 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003311
daniel@transgaming.come0078962010-04-15 20:45:08 +00003312 switch (pname)
3313 {
3314 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003315 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003316 break;
3317 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003318 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003319 break;
3320 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003321 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003322 break;
3323 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003324 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003325 break;
3326 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003327 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003328 break;
3329 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003330 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003331 break;
3332 case GL_CURRENT_VERTEX_ATTRIB:
3333 for (int i = 0; i < 4; ++i)
3334 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003335 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003336 }
3337 break;
3338 default: return error(GL_INVALID_ENUM);
3339 }
3340 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003341 }
3342 catch(std::bad_alloc&)
3343 {
3344 return error(GL_OUT_OF_MEMORY);
3345 }
3346}
3347
3348void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3349{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003350 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003351
3352 try
3353 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003354 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003355
daniel@transgaming.come0078962010-04-15 20:45:08 +00003356 if (context)
3357 {
3358 if (index >= gl::MAX_VERTEX_ATTRIBS)
3359 {
3360 return error(GL_INVALID_VALUE);
3361 }
3362
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003363 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003364
daniel@transgaming.come0078962010-04-15 20:45:08 +00003365 switch (pname)
3366 {
3367 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003368 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003369 break;
3370 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003371 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003372 break;
3373 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003374 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003375 break;
3376 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003377 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003378 break;
3379 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003380 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003381 break;
3382 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003383 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003384 break;
3385 case GL_CURRENT_VERTEX_ATTRIB:
3386 for (int i = 0; i < 4; ++i)
3387 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003388 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003389 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3390 }
3391 break;
3392 default: return error(GL_INVALID_ENUM);
3393 }
3394 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003395 }
3396 catch(std::bad_alloc&)
3397 {
3398 return error(GL_OUT_OF_MEMORY);
3399 }
3400}
3401
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003402void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003403{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003404 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003405
3406 try
3407 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003408 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003409
daniel@transgaming.come0078962010-04-15 20:45:08 +00003410 if (context)
3411 {
3412 if (index >= gl::MAX_VERTEX_ATTRIBS)
3413 {
3414 return error(GL_INVALID_VALUE);
3415 }
3416
3417 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3418 {
3419 return error(GL_INVALID_ENUM);
3420 }
3421
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003422 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003423 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003424 }
3425 catch(std::bad_alloc&)
3426 {
3427 return error(GL_OUT_OF_MEMORY);
3428 }
3429}
3430
3431void __stdcall glHint(GLenum target, GLenum mode)
3432{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003433 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003434
3435 try
3436 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003437 switch (target)
3438 {
3439 case GL_GENERATE_MIPMAP_HINT:
3440 switch (mode)
3441 {
3442 case GL_FASTEST:
3443 case GL_NICEST:
3444 case GL_DONT_CARE:
3445 break;
3446 default:
3447 return error(GL_INVALID_ENUM);
3448 }
3449 break;
3450 default:
3451 return error(GL_INVALID_ENUM);
3452 }
3453
3454 gl::Context *context = gl::getContext();
3455 if (context)
3456 {
3457 if (target == GL_GENERATE_MIPMAP_HINT)
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003458 context->setGenerateMipmapHint(mode);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003459 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003460 }
3461 catch(std::bad_alloc&)
3462 {
3463 return error(GL_OUT_OF_MEMORY);
3464 }
3465}
3466
3467GLboolean __stdcall glIsBuffer(GLuint buffer)
3468{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003469 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003470
3471 try
3472 {
3473 gl::Context *context = gl::getContext();
3474
3475 if (context && buffer)
3476 {
3477 gl::Buffer *bufferObject = context->getBuffer(buffer);
3478
3479 if (bufferObject)
3480 {
3481 return GL_TRUE;
3482 }
3483 }
3484 }
3485 catch(std::bad_alloc&)
3486 {
3487 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3488 }
3489
3490 return GL_FALSE;
3491}
3492
3493GLboolean __stdcall glIsEnabled(GLenum cap)
3494{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003495 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003496
3497 try
3498 {
3499 gl::Context *context = gl::getContext();
3500
3501 if (context)
3502 {
3503 switch (cap)
3504 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003505 case GL_CULL_FACE: return context->isCullFaceEnabled();
3506 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3507 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3508 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3509 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3510 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3511 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3512 case GL_BLEND: return context->isBlendEnabled();
3513 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003514 default:
3515 return error(GL_INVALID_ENUM, false);
3516 }
3517 }
3518 }
3519 catch(std::bad_alloc&)
3520 {
3521 return error(GL_OUT_OF_MEMORY, false);
3522 }
3523
3524 return false;
3525}
3526
3527GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3528{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003529 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003530
3531 try
3532 {
3533 gl::Context *context = gl::getContext();
3534
3535 if (context && framebuffer)
3536 {
3537 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3538
3539 if (framebufferObject)
3540 {
3541 return GL_TRUE;
3542 }
3543 }
3544 }
3545 catch(std::bad_alloc&)
3546 {
3547 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3548 }
3549
3550 return GL_FALSE;
3551}
3552
3553GLboolean __stdcall glIsProgram(GLuint program)
3554{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003555 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003556
3557 try
3558 {
3559 gl::Context *context = gl::getContext();
3560
3561 if (context && program)
3562 {
3563 gl::Program *programObject = context->getProgram(program);
3564
3565 if (programObject)
3566 {
3567 return GL_TRUE;
3568 }
3569 }
3570 }
3571 catch(std::bad_alloc&)
3572 {
3573 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3574 }
3575
3576 return GL_FALSE;
3577}
3578
3579GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3580{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003581 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003582
3583 try
3584 {
3585 gl::Context *context = gl::getContext();
3586
3587 if (context && renderbuffer)
3588 {
3589 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3590
3591 if (renderbufferObject)
3592 {
3593 return GL_TRUE;
3594 }
3595 }
3596 }
3597 catch(std::bad_alloc&)
3598 {
3599 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3600 }
3601
3602 return GL_FALSE;
3603}
3604
3605GLboolean __stdcall glIsShader(GLuint shader)
3606{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003607 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003608
3609 try
3610 {
3611 gl::Context *context = gl::getContext();
3612
3613 if (context && shader)
3614 {
3615 gl::Shader *shaderObject = context->getShader(shader);
3616
3617 if (shaderObject)
3618 {
3619 return GL_TRUE;
3620 }
3621 }
3622 }
3623 catch(std::bad_alloc&)
3624 {
3625 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3626 }
3627
3628 return GL_FALSE;
3629}
3630
3631GLboolean __stdcall glIsTexture(GLuint texture)
3632{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003633 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003634
3635 try
3636 {
3637 gl::Context *context = gl::getContext();
3638
3639 if (context && texture)
3640 {
3641 gl::Texture *textureObject = context->getTexture(texture);
3642
3643 if (textureObject)
3644 {
3645 return GL_TRUE;
3646 }
3647 }
3648 }
3649 catch(std::bad_alloc&)
3650 {
3651 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3652 }
3653
3654 return GL_FALSE;
3655}
3656
3657void __stdcall glLineWidth(GLfloat width)
3658{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003659 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003660
3661 try
3662 {
3663 if (width <= 0.0f)
3664 {
3665 return error(GL_INVALID_VALUE);
3666 }
3667
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003668 gl::Context *context = gl::getContext();
3669
3670 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003671 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003672 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003673 }
3674 }
3675 catch(std::bad_alloc&)
3676 {
3677 return error(GL_OUT_OF_MEMORY);
3678 }
3679}
3680
3681void __stdcall glLinkProgram(GLuint program)
3682{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003683 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003684
3685 try
3686 {
3687 gl::Context *context = gl::getContext();
3688
3689 if (context)
3690 {
3691 gl::Program *programObject = context->getProgram(program);
3692
3693 if (!programObject)
3694 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003695 if (context->getShader(program))
3696 {
3697 return error(GL_INVALID_OPERATION);
3698 }
3699 else
3700 {
3701 return error(GL_INVALID_VALUE);
3702 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003703 }
3704
3705 programObject->link();
3706 }
3707 }
3708 catch(std::bad_alloc&)
3709 {
3710 return error(GL_OUT_OF_MEMORY);
3711 }
3712}
3713
3714void __stdcall glPixelStorei(GLenum pname, GLint param)
3715{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003716 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003717
3718 try
3719 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003720 gl::Context *context = gl::getContext();
3721
3722 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003723 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003724 switch (pname)
3725 {
3726 case GL_UNPACK_ALIGNMENT:
3727 if (param != 1 && param != 2 && param != 4 && param != 8)
3728 {
3729 return error(GL_INVALID_VALUE);
3730 }
3731
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003732 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003733 break;
3734
3735 case GL_PACK_ALIGNMENT:
3736 if (param != 1 && param != 2 && param != 4 && param != 8)
3737 {
3738 return error(GL_INVALID_VALUE);
3739 }
3740
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003741 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003742 break;
3743
3744 default:
3745 return error(GL_INVALID_ENUM);
3746 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003747 }
3748 }
3749 catch(std::bad_alloc&)
3750 {
3751 return error(GL_OUT_OF_MEMORY);
3752 }
3753}
3754
3755void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3756{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003757 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003758
3759 try
3760 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003761 gl::Context *context = gl::getContext();
3762
3763 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003764 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003765 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003766 }
3767 }
3768 catch(std::bad_alloc&)
3769 {
3770 return error(GL_OUT_OF_MEMORY);
3771 }
3772}
3773
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003774void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003775{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003776 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003777 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003778 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003779
3780 try
3781 {
3782 if (width < 0 || height < 0)
3783 {
3784 return error(GL_INVALID_VALUE);
3785 }
3786
3787 switch (format)
3788 {
3789 case GL_RGBA:
3790 switch (type)
3791 {
3792 case GL_UNSIGNED_BYTE:
3793 break;
3794 default:
3795 return error(GL_INVALID_OPERATION);
3796 }
3797 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003798 case GL_BGRA_EXT:
3799 switch (type)
3800 {
3801 case GL_UNSIGNED_BYTE:
3802 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3803 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3804 break;
3805 default:
3806 return error(GL_INVALID_OPERATION);
3807 }
3808 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003809 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3810 switch (type)
3811 {
3812 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3813 break;
3814 default:
3815 return error(GL_INVALID_OPERATION);
3816 }
3817 break;
3818 default:
3819 return error(GL_INVALID_OPERATION);
3820 }
3821
3822 gl::Context *context = gl::getContext();
3823
3824 if (context)
3825 {
3826 context->readPixels(x, y, width, height, format, type, pixels);
3827 }
3828 }
3829 catch(std::bad_alloc&)
3830 {
3831 return error(GL_OUT_OF_MEMORY);
3832 }
3833}
3834
3835void __stdcall glReleaseShaderCompiler(void)
3836{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003837 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003838
3839 try
3840 {
3841 gl::Shader::releaseCompiler();
3842 }
3843 catch(std::bad_alloc&)
3844 {
3845 return error(GL_OUT_OF_MEMORY);
3846 }
3847}
3848
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003849void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003850{
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003851 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3852 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003853
3854 try
3855 {
3856 switch (target)
3857 {
3858 case GL_RENDERBUFFER:
3859 break;
3860 default:
3861 return error(GL_INVALID_ENUM);
3862 }
3863
3864 switch (internalformat)
3865 {
3866 case GL_DEPTH_COMPONENT16:
3867 case GL_RGBA4:
3868 case GL_RGB5_A1:
3869 case GL_RGB565:
3870 case GL_STENCIL_INDEX8:
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003871 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com63977542010-08-24 19:21:02 +00003872 case GL_RGB8_OES:
3873 case GL_RGBA8_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003874 break;
3875 default:
3876 return error(GL_INVALID_ENUM);
3877 }
3878
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003879 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003880 {
3881 return error(GL_INVALID_VALUE);
3882 }
3883
3884 gl::Context *context = gl::getContext();
3885
3886 if (context)
3887 {
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003888 if (samples > context->getMaxSupportedSamples())
3889 {
3890 return error(GL_INVALID_VALUE);
3891 }
3892
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003893 GLuint handle = context->getRenderbufferHandle();
3894 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003895 {
3896 return error(GL_INVALID_OPERATION);
3897 }
3898
3899 switch (internalformat)
3900 {
3901 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003902 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003903 break;
3904 case GL_RGBA4:
3905 case GL_RGB5_A1:
3906 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00003907 case GL_RGB8_OES:
3908 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003909 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003910 break;
3911 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003912 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003913 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003914 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003915 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003916 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003917 default:
3918 return error(GL_INVALID_ENUM);
3919 }
3920 }
3921 }
3922 catch(std::bad_alloc&)
3923 {
3924 return error(GL_OUT_OF_MEMORY);
3925 }
3926}
3927
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003928void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3929{
3930 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
3931}
3932
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003933void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3934{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003935 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003936
3937 try
3938 {
3939 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003940
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003941 if (context)
3942 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00003943 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003944 }
3945 }
3946 catch(std::bad_alloc&)
3947 {
3948 return error(GL_OUT_OF_MEMORY);
3949 }
3950}
3951
3952void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3953{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003954 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 +00003955
3956 try
3957 {
3958 if (width < 0 || height < 0)
3959 {
3960 return error(GL_INVALID_VALUE);
3961 }
3962
3963 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003964
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003965 if (context)
3966 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003967 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003968 }
3969 }
3970 catch(std::bad_alloc&)
3971 {
3972 return error(GL_OUT_OF_MEMORY);
3973 }
3974}
3975
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003976void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003977{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003978 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003979 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003980 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003981
3982 try
3983 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00003984 // No binary shader formats are supported.
3985 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003986 }
3987 catch(std::bad_alloc&)
3988 {
3989 return error(GL_OUT_OF_MEMORY);
3990 }
3991}
3992
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003993void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003994{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003995 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 +00003996 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003997
3998 try
3999 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004000 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004001 {
4002 return error(GL_INVALID_VALUE);
4003 }
4004
4005 gl::Context *context = gl::getContext();
4006
4007 if (context)
4008 {
4009 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004010
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004011 if (!shaderObject)
4012 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00004013 if (context->getProgram(shader))
4014 {
4015 return error(GL_INVALID_OPERATION);
4016 }
4017 else
4018 {
4019 return error(GL_INVALID_VALUE);
4020 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004021 }
4022
4023 shaderObject->setSource(count, string, length);
4024 }
4025 }
4026 catch(std::bad_alloc&)
4027 {
4028 return error(GL_OUT_OF_MEMORY);
4029 }
4030}
4031
4032void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4033{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004034 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004035}
4036
4037void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4038{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004039 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 +00004040
4041 try
4042 {
4043 switch (face)
4044 {
4045 case GL_FRONT:
4046 case GL_BACK:
4047 case GL_FRONT_AND_BACK:
4048 break;
4049 default:
4050 return error(GL_INVALID_ENUM);
4051 }
4052
4053 switch (func)
4054 {
4055 case GL_NEVER:
4056 case GL_ALWAYS:
4057 case GL_LESS:
4058 case GL_LEQUAL:
4059 case GL_EQUAL:
4060 case GL_GEQUAL:
4061 case GL_GREATER:
4062 case GL_NOTEQUAL:
4063 break;
4064 default:
4065 return error(GL_INVALID_ENUM);
4066 }
4067
4068 gl::Context *context = gl::getContext();
4069
4070 if (context)
4071 {
4072 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4073 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004074 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004075 }
4076
4077 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4078 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004079 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004080 }
4081 }
4082 }
4083 catch(std::bad_alloc&)
4084 {
4085 return error(GL_OUT_OF_MEMORY);
4086 }
4087}
4088
4089void __stdcall glStencilMask(GLuint mask)
4090{
4091 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4092}
4093
4094void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4095{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004096 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004097
4098 try
4099 {
4100 switch (face)
4101 {
4102 case GL_FRONT:
4103 case GL_BACK:
4104 case GL_FRONT_AND_BACK:
4105 break;
4106 default:
4107 return error(GL_INVALID_ENUM);
4108 }
4109
4110 gl::Context *context = gl::getContext();
4111
4112 if (context)
4113 {
4114 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4115 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004116 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004117 }
4118
4119 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4120 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004121 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004122 }
4123 }
4124 }
4125 catch(std::bad_alloc&)
4126 {
4127 return error(GL_OUT_OF_MEMORY);
4128 }
4129}
4130
4131void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4132{
4133 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4134}
4135
4136void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4137{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004138 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4139 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004140
4141 try
4142 {
4143 switch (face)
4144 {
4145 case GL_FRONT:
4146 case GL_BACK:
4147 case GL_FRONT_AND_BACK:
4148 break;
4149 default:
4150 return error(GL_INVALID_ENUM);
4151 }
4152
4153 switch (fail)
4154 {
4155 case GL_ZERO:
4156 case GL_KEEP:
4157 case GL_REPLACE:
4158 case GL_INCR:
4159 case GL_DECR:
4160 case GL_INVERT:
4161 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004162 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004163 break;
4164 default:
4165 return error(GL_INVALID_ENUM);
4166 }
4167
4168 switch (zfail)
4169 {
4170 case GL_ZERO:
4171 case GL_KEEP:
4172 case GL_REPLACE:
4173 case GL_INCR:
4174 case GL_DECR:
4175 case GL_INVERT:
4176 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004177 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004178 break;
4179 default:
4180 return error(GL_INVALID_ENUM);
4181 }
4182
4183 switch (zpass)
4184 {
4185 case GL_ZERO:
4186 case GL_KEEP:
4187 case GL_REPLACE:
4188 case GL_INCR:
4189 case GL_DECR:
4190 case GL_INVERT:
4191 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004192 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004193 break;
4194 default:
4195 return error(GL_INVALID_ENUM);
4196 }
4197
4198 gl::Context *context = gl::getContext();
4199
4200 if (context)
4201 {
4202 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4203 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004204 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004205 }
4206
4207 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4208 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004209 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004210 }
4211 }
4212 }
4213 catch(std::bad_alloc&)
4214 {
4215 return error(GL_OUT_OF_MEMORY);
4216 }
4217}
4218
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004219void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4220 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004221{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004222 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 +00004223 "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 +00004224 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004225
4226 try
4227 {
4228 if (level < 0 || width < 0 || height < 0)
4229 {
4230 return error(GL_INVALID_VALUE);
4231 }
4232
4233 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
4234 {
4235 return error(GL_INVALID_VALUE);
4236 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004237
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004238 switch (target)
4239 {
4240 case GL_TEXTURE_2D:
4241 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
4242 {
4243 return error(GL_INVALID_VALUE);
4244 }
4245 break;
4246 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4247 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4248 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4249 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4250 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4251 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00004252 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004253 {
4254 return error(GL_INVALID_VALUE);
4255 }
4256
4257 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
4258 {
4259 return error(GL_INVALID_VALUE);
4260 }
4261 break;
4262 default:
4263 return error(GL_INVALID_ENUM);
4264 }
4265
4266 if (internalformat != format)
4267 {
4268 return error(GL_INVALID_OPERATION);
4269 }
4270
4271 switch (internalformat)
4272 {
4273 case GL_ALPHA:
4274 case GL_LUMINANCE:
4275 case GL_LUMINANCE_ALPHA:
4276 switch (type)
4277 {
4278 case GL_UNSIGNED_BYTE:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004279 case GL_FLOAT:
4280 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004281 break;
4282 default:
4283 return error(GL_INVALID_ENUM);
4284 }
4285 break;
4286 case GL_RGB:
4287 switch (type)
4288 {
4289 case GL_UNSIGNED_BYTE:
4290 case GL_UNSIGNED_SHORT_5_6_5:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004291 case GL_FLOAT:
4292 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004293 break;
4294 default:
4295 return error(GL_INVALID_ENUM);
4296 }
4297 break;
4298 case GL_RGBA:
4299 switch (type)
4300 {
4301 case GL_UNSIGNED_BYTE:
4302 case GL_UNSIGNED_SHORT_4_4_4_4:
4303 case GL_UNSIGNED_SHORT_5_5_5_1:
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004304 case GL_FLOAT:
4305 case GL_HALF_FLOAT_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004306 break;
4307 default:
4308 return error(GL_INVALID_ENUM);
4309 }
4310 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004311 case GL_BGRA_EXT:
4312 switch (type)
4313 {
4314 case GL_UNSIGNED_BYTE:
4315 break;
4316 default:
4317 return error(GL_INVALID_ENUM);
4318 }
4319 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004320 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4321 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4322 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004323 default:
4324 return error(GL_INVALID_VALUE);
4325 }
4326
4327 if (border != 0)
4328 {
4329 return error(GL_INVALID_VALUE);
4330 }
4331
4332 gl::Context *context = gl::getContext();
4333
4334 if (context)
4335 {
daniel@transgaming.com01868132010-08-24 19:21:17 +00004336 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4337 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
4338 {
4339 if (context->supportsCompressedTextures())
4340 {
4341 return error(GL_INVALID_OPERATION);
4342 }
4343 else
4344 {
4345 return error(GL_INVALID_ENUM);
4346 }
4347 }
4348
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004349 if (type == GL_FLOAT)
4350 {
4351 if (!context->supportsFloatTextures())
4352 {
4353 return error(GL_INVALID_ENUM);
4354 }
4355 }
4356 else if (type == GL_HALF_FLOAT_OES)
4357 {
4358 if (!context->supportsHalfFloatTextures())
4359 {
4360 return error(GL_INVALID_ENUM);
4361 }
4362 }
4363
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004364 if (target == GL_TEXTURE_2D)
4365 {
4366 gl::Texture2D *texture = context->getTexture2D();
4367
4368 if (!texture)
4369 {
4370 return error(GL_INVALID_OPERATION);
4371 }
4372
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004373 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004374 }
4375 else
4376 {
4377 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4378
4379 if (!texture)
4380 {
4381 return error(GL_INVALID_OPERATION);
4382 }
4383
4384 switch (target)
4385 {
4386 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004387 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004388 break;
4389 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004390 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004391 break;
4392 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004393 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004394 break;
4395 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004396 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004397 break;
4398 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004399 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004400 break;
4401 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004402 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004403 break;
4404 default: UNREACHABLE();
4405 }
4406 }
4407 }
4408 }
4409 catch(std::bad_alloc&)
4410 {
4411 return error(GL_OUT_OF_MEMORY);
4412 }
4413}
4414
4415void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4416{
4417 glTexParameteri(target, pname, (GLint)param);
4418}
4419
4420void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4421{
4422 glTexParameteri(target, pname, (GLint)*params);
4423}
4424
4425void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4426{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004427 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004428
4429 try
4430 {
4431 gl::Context *context = gl::getContext();
4432
4433 if (context)
4434 {
4435 gl::Texture *texture;
4436
4437 switch (target)
4438 {
4439 case GL_TEXTURE_2D:
4440 texture = context->getTexture2D();
4441 break;
4442 case GL_TEXTURE_CUBE_MAP:
4443 texture = context->getTextureCubeMap();
4444 break;
4445 default:
4446 return error(GL_INVALID_ENUM);
4447 }
4448
4449 switch (pname)
4450 {
4451 case GL_TEXTURE_WRAP_S:
4452 if (!texture->setWrapS((GLenum)param))
4453 {
4454 return error(GL_INVALID_ENUM);
4455 }
4456 break;
4457 case GL_TEXTURE_WRAP_T:
4458 if (!texture->setWrapT((GLenum)param))
4459 {
4460 return error(GL_INVALID_ENUM);
4461 }
4462 break;
4463 case GL_TEXTURE_MIN_FILTER:
4464 if (!texture->setMinFilter((GLenum)param))
4465 {
4466 return error(GL_INVALID_ENUM);
4467 }
4468 break;
4469 case GL_TEXTURE_MAG_FILTER:
4470 if (!texture->setMagFilter((GLenum)param))
4471 {
4472 return error(GL_INVALID_ENUM);
4473 }
4474 break;
4475 default:
4476 return error(GL_INVALID_ENUM);
4477 }
4478 }
4479 }
4480 catch(std::bad_alloc&)
4481 {
4482 return error(GL_OUT_OF_MEMORY);
4483 }
4484}
4485
4486void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4487{
4488 glTexParameteri(target, pname, *params);
4489}
4490
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004491void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4492 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004493{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004494 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4495 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004496 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004497 target, level, xoffset, yoffset, width, height, format, type, pixels);
4498
4499 try
4500 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004501 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004502 {
4503 return error(GL_INVALID_ENUM);
4504 }
4505
4506 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004507 {
4508 return error(GL_INVALID_VALUE);
4509 }
4510
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004511 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4512 {
4513 return error(GL_INVALID_VALUE);
4514 }
4515
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004516 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004517 {
4518 return error(GL_INVALID_ENUM);
4519 }
4520
4521 if (width == 0 || height == 0 || pixels == NULL)
4522 {
4523 return;
4524 }
4525
4526 gl::Context *context = gl::getContext();
4527
4528 if (context)
4529 {
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004530 if (format == GL_FLOAT)
4531 {
4532 if (!context->supportsFloatTextures())
4533 {
4534 return error(GL_INVALID_ENUM);
4535 }
4536 }
4537 else if (format == GL_HALF_FLOAT_OES)
4538 {
4539 if (!context->supportsHalfFloatTextures())
4540 {
4541 return error(GL_INVALID_ENUM);
4542 }
4543 }
4544
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004545 if (target == GL_TEXTURE_2D)
4546 {
4547 gl::Texture2D *texture = context->getTexture2D();
4548
4549 if (!texture)
4550 {
4551 return error(GL_INVALID_OPERATION);
4552 }
4553
daniel@transgaming.com01868132010-08-24 19:21:17 +00004554 if (texture->isCompressed())
4555 {
4556 return error(GL_INVALID_OPERATION);
4557 }
4558
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004559 if (format != texture->getFormat())
4560 {
4561 return error(GL_INVALID_OPERATION);
4562 }
4563
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004564 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004565 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004566 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004567 {
4568 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4569
4570 if (!texture)
4571 {
4572 return error(GL_INVALID_OPERATION);
4573 }
4574
daniel@transgaming.com01868132010-08-24 19:21:17 +00004575 if (texture->isCompressed())
4576 {
4577 return error(GL_INVALID_OPERATION);
4578 }
4579
daniel@transgaming.com0a337e92010-08-28 17:38:27 +00004580 if (format != texture->getFormat())
4581 {
4582 return error(GL_INVALID_OPERATION);
4583 }
4584
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004585 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004586 }
4587 else
4588 {
4589 UNREACHABLE();
4590 }
4591 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004592 }
4593 catch(std::bad_alloc&)
4594 {
4595 return error(GL_OUT_OF_MEMORY);
4596 }
4597}
4598
4599void __stdcall glUniform1f(GLint location, GLfloat x)
4600{
4601 glUniform1fv(location, 1, &x);
4602}
4603
4604void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4605{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004606 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004607
4608 try
4609 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004610 if (count < 0)
4611 {
4612 return error(GL_INVALID_VALUE);
4613 }
4614
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004615 if (location == -1)
4616 {
4617 return;
4618 }
4619
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004620 gl::Context *context = gl::getContext();
4621
4622 if (context)
4623 {
4624 gl::Program *program = context->getCurrentProgram();
4625
4626 if (!program)
4627 {
4628 return error(GL_INVALID_OPERATION);
4629 }
4630
4631 if (!program->setUniform1fv(location, count, v))
4632 {
4633 return error(GL_INVALID_OPERATION);
4634 }
4635 }
4636 }
4637 catch(std::bad_alloc&)
4638 {
4639 return error(GL_OUT_OF_MEMORY);
4640 }
4641}
4642
4643void __stdcall glUniform1i(GLint location, GLint x)
4644{
4645 glUniform1iv(location, 1, &x);
4646}
4647
4648void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004650 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004651
4652 try
4653 {
4654 if (count < 0)
4655 {
4656 return error(GL_INVALID_VALUE);
4657 }
4658
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004659 if (location == -1)
4660 {
4661 return;
4662 }
4663
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004664 gl::Context *context = gl::getContext();
4665
4666 if (context)
4667 {
4668 gl::Program *program = context->getCurrentProgram();
4669
4670 if (!program)
4671 {
4672 return error(GL_INVALID_OPERATION);
4673 }
4674
4675 if (!program->setUniform1iv(location, count, v))
4676 {
4677 return error(GL_INVALID_OPERATION);
4678 }
4679 }
4680 }
4681 catch(std::bad_alloc&)
4682 {
4683 return error(GL_OUT_OF_MEMORY);
4684 }
4685}
4686
4687void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4688{
4689 GLfloat xy[2] = {x, y};
4690
4691 glUniform2fv(location, 1, (GLfloat*)&xy);
4692}
4693
4694void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4695{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004696 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004697
4698 try
4699 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004700 if (count < 0)
4701 {
4702 return error(GL_INVALID_VALUE);
4703 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004704
4705 if (location == -1)
4706 {
4707 return;
4708 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004709
4710 gl::Context *context = gl::getContext();
4711
4712 if (context)
4713 {
4714 gl::Program *program = context->getCurrentProgram();
4715
4716 if (!program)
4717 {
4718 return error(GL_INVALID_OPERATION);
4719 }
4720
4721 if (!program->setUniform2fv(location, count, v))
4722 {
4723 return error(GL_INVALID_OPERATION);
4724 }
4725 }
4726 }
4727 catch(std::bad_alloc&)
4728 {
4729 return error(GL_OUT_OF_MEMORY);
4730 }
4731}
4732
4733void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4734{
4735 GLint xy[4] = {x, y};
4736
4737 glUniform2iv(location, 1, (GLint*)&xy);
4738}
4739
4740void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4741{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004742 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004743
4744 try
4745 {
4746 if (count < 0)
4747 {
4748 return error(GL_INVALID_VALUE);
4749 }
4750
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004751 if (location == -1)
4752 {
4753 return;
4754 }
4755
4756 gl::Context *context = gl::getContext();
4757
4758 if (context)
4759 {
4760 gl::Program *program = context->getCurrentProgram();
4761
4762 if (!program)
4763 {
4764 return error(GL_INVALID_OPERATION);
4765 }
4766
4767 if (!program->setUniform2iv(location, count, v))
4768 {
4769 return error(GL_INVALID_OPERATION);
4770 }
4771 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004772 }
4773 catch(std::bad_alloc&)
4774 {
4775 return error(GL_OUT_OF_MEMORY);
4776 }
4777}
4778
4779void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4780{
4781 GLfloat xyz[3] = {x, y, z};
4782
4783 glUniform3fv(location, 1, (GLfloat*)&xyz);
4784}
4785
4786void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4787{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004788 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004789
4790 try
4791 {
4792 if (count < 0)
4793 {
4794 return error(GL_INVALID_VALUE);
4795 }
4796
4797 if (location == -1)
4798 {
4799 return;
4800 }
4801
4802 gl::Context *context = gl::getContext();
4803
4804 if (context)
4805 {
4806 gl::Program *program = context->getCurrentProgram();
4807
4808 if (!program)
4809 {
4810 return error(GL_INVALID_OPERATION);
4811 }
4812
4813 if (!program->setUniform3fv(location, count, v))
4814 {
4815 return error(GL_INVALID_OPERATION);
4816 }
4817 }
4818 }
4819 catch(std::bad_alloc&)
4820 {
4821 return error(GL_OUT_OF_MEMORY);
4822 }
4823}
4824
4825void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4826{
4827 GLint xyz[3] = {x, y, z};
4828
4829 glUniform3iv(location, 1, (GLint*)&xyz);
4830}
4831
4832void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4833{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004834 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004835
4836 try
4837 {
4838 if (count < 0)
4839 {
4840 return error(GL_INVALID_VALUE);
4841 }
4842
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004843 if (location == -1)
4844 {
4845 return;
4846 }
4847
4848 gl::Context *context = gl::getContext();
4849
4850 if (context)
4851 {
4852 gl::Program *program = context->getCurrentProgram();
4853
4854 if (!program)
4855 {
4856 return error(GL_INVALID_OPERATION);
4857 }
4858
4859 if (!program->setUniform3iv(location, count, v))
4860 {
4861 return error(GL_INVALID_OPERATION);
4862 }
4863 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004864 }
4865 catch(std::bad_alloc&)
4866 {
4867 return error(GL_OUT_OF_MEMORY);
4868 }
4869}
4870
4871void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4872{
4873 GLfloat xyzw[4] = {x, y, z, w};
4874
4875 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4876}
4877
4878void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4879{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004880 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004881
4882 try
4883 {
4884 if (count < 0)
4885 {
4886 return error(GL_INVALID_VALUE);
4887 }
4888
4889 if (location == -1)
4890 {
4891 return;
4892 }
4893
4894 gl::Context *context = gl::getContext();
4895
4896 if (context)
4897 {
4898 gl::Program *program = context->getCurrentProgram();
4899
4900 if (!program)
4901 {
4902 return error(GL_INVALID_OPERATION);
4903 }
4904
4905 if (!program->setUniform4fv(location, count, v))
4906 {
4907 return error(GL_INVALID_OPERATION);
4908 }
4909 }
4910 }
4911 catch(std::bad_alloc&)
4912 {
4913 return error(GL_OUT_OF_MEMORY);
4914 }
4915}
4916
4917void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4918{
4919 GLint xyzw[4] = {x, y, z, w};
4920
4921 glUniform4iv(location, 1, (GLint*)&xyzw);
4922}
4923
4924void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4925{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004926 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004927
4928 try
4929 {
4930 if (count < 0)
4931 {
4932 return error(GL_INVALID_VALUE);
4933 }
4934
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004935 if (location == -1)
4936 {
4937 return;
4938 }
4939
4940 gl::Context *context = gl::getContext();
4941
4942 if (context)
4943 {
4944 gl::Program *program = context->getCurrentProgram();
4945
4946 if (!program)
4947 {
4948 return error(GL_INVALID_OPERATION);
4949 }
4950
4951 if (!program->setUniform4iv(location, count, v))
4952 {
4953 return error(GL_INVALID_OPERATION);
4954 }
4955 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004956 }
4957 catch(std::bad_alloc&)
4958 {
4959 return error(GL_OUT_OF_MEMORY);
4960 }
4961}
4962
4963void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4964{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004965 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4966 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004967
4968 try
4969 {
4970 if (count < 0 || transpose != GL_FALSE)
4971 {
4972 return error(GL_INVALID_VALUE);
4973 }
4974
4975 if (location == -1)
4976 {
4977 return;
4978 }
4979
4980 gl::Context *context = gl::getContext();
4981
4982 if (context)
4983 {
4984 gl::Program *program = context->getCurrentProgram();
4985
4986 if (!program)
4987 {
4988 return error(GL_INVALID_OPERATION);
4989 }
4990
4991 if (!program->setUniformMatrix2fv(location, count, value))
4992 {
4993 return error(GL_INVALID_OPERATION);
4994 }
4995 }
4996 }
4997 catch(std::bad_alloc&)
4998 {
4999 return error(GL_OUT_OF_MEMORY);
5000 }
5001}
5002
5003void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5004{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005005 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5006 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005007
5008 try
5009 {
5010 if (count < 0 || transpose != GL_FALSE)
5011 {
5012 return error(GL_INVALID_VALUE);
5013 }
5014
5015 if (location == -1)
5016 {
5017 return;
5018 }
5019
5020 gl::Context *context = gl::getContext();
5021
5022 if (context)
5023 {
5024 gl::Program *program = context->getCurrentProgram();
5025
5026 if (!program)
5027 {
5028 return error(GL_INVALID_OPERATION);
5029 }
5030
5031 if (!program->setUniformMatrix3fv(location, count, value))
5032 {
5033 return error(GL_INVALID_OPERATION);
5034 }
5035 }
5036 }
5037 catch(std::bad_alloc&)
5038 {
5039 return error(GL_OUT_OF_MEMORY);
5040 }
5041}
5042
5043void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5044{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005045 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5046 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005047
5048 try
5049 {
5050 if (count < 0 || transpose != GL_FALSE)
5051 {
5052 return error(GL_INVALID_VALUE);
5053 }
5054
5055 if (location == -1)
5056 {
5057 return;
5058 }
5059
5060 gl::Context *context = gl::getContext();
5061
5062 if (context)
5063 {
5064 gl::Program *program = context->getCurrentProgram();
5065
5066 if (!program)
5067 {
5068 return error(GL_INVALID_OPERATION);
5069 }
5070
5071 if (!program->setUniformMatrix4fv(location, count, value))
5072 {
5073 return error(GL_INVALID_OPERATION);
5074 }
5075 }
5076 }
5077 catch(std::bad_alloc&)
5078 {
5079 return error(GL_OUT_OF_MEMORY);
5080 }
5081}
5082
5083void __stdcall glUseProgram(GLuint program)
5084{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005085 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005086
5087 try
5088 {
5089 gl::Context *context = gl::getContext();
5090
5091 if (context)
5092 {
5093 gl::Program *programObject = context->getProgram(program);
5094
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005095 if (!programObject && program != 0)
5096 {
5097 if (context->getShader(program))
5098 {
5099 return error(GL_INVALID_OPERATION);
5100 }
5101 else
5102 {
5103 return error(GL_INVALID_VALUE);
5104 }
5105 }
5106
5107 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005108 {
5109 return error(GL_INVALID_OPERATION);
5110 }
5111
5112 context->useProgram(program);
5113 }
5114 }
5115 catch(std::bad_alloc&)
5116 {
5117 return error(GL_OUT_OF_MEMORY);
5118 }
5119}
5120
5121void __stdcall glValidateProgram(GLuint program)
5122{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005123 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005124
5125 try
5126 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005127 gl::Context *context = gl::getContext();
5128
5129 if (context)
5130 {
5131 gl::Program *programObject = context->getProgram(program);
5132
5133 if (!programObject)
5134 {
5135 if (context->getShader(program))
5136 {
5137 return error(GL_INVALID_OPERATION);
5138 }
5139 else
5140 {
5141 return error(GL_INVALID_VALUE);
5142 }
5143 }
5144
5145 programObject->validate();
5146 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005147 }
5148 catch(std::bad_alloc&)
5149 {
5150 return error(GL_OUT_OF_MEMORY);
5151 }
5152}
5153
5154void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5155{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005156 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005157
5158 try
5159 {
5160 if (index >= gl::MAX_VERTEX_ATTRIBS)
5161 {
5162 return error(GL_INVALID_VALUE);
5163 }
5164
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005165 gl::Context *context = gl::getContext();
5166
5167 if (context)
5168 {
5169 GLfloat vals[4] = { x, 0, 0, 1 };
5170 context->setVertexAttrib(index, vals);
5171 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005172 }
5173 catch(std::bad_alloc&)
5174 {
5175 return error(GL_OUT_OF_MEMORY);
5176 }
5177}
5178
5179void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5180{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005181 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005182
5183 try
5184 {
5185 if (index >= gl::MAX_VERTEX_ATTRIBS)
5186 {
5187 return error(GL_INVALID_VALUE);
5188 }
5189
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005190 gl::Context *context = gl::getContext();
5191
5192 if (context)
5193 {
5194 GLfloat vals[4] = { values[0], 0, 0, 1 };
5195 context->setVertexAttrib(index, vals);
5196 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005197 }
5198 catch(std::bad_alloc&)
5199 {
5200 return error(GL_OUT_OF_MEMORY);
5201 }
5202}
5203
5204void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5205{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005206 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005207
5208 try
5209 {
5210 if (index >= gl::MAX_VERTEX_ATTRIBS)
5211 {
5212 return error(GL_INVALID_VALUE);
5213 }
5214
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005215 gl::Context *context = gl::getContext();
5216
5217 if (context)
5218 {
5219 GLfloat vals[4] = { x, y, 0, 1 };
5220 context->setVertexAttrib(index, vals);
5221 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005222 }
5223 catch(std::bad_alloc&)
5224 {
5225 return error(GL_OUT_OF_MEMORY);
5226 }
5227}
5228
5229void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5230{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005231 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005232
5233 try
5234 {
5235 if (index >= gl::MAX_VERTEX_ATTRIBS)
5236 {
5237 return error(GL_INVALID_VALUE);
5238 }
5239
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005240 gl::Context *context = gl::getContext();
5241
5242 if (context)
5243 {
5244 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5245 context->setVertexAttrib(index, vals);
5246 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005247 }
5248 catch(std::bad_alloc&)
5249 {
5250 return error(GL_OUT_OF_MEMORY);
5251 }
5252}
5253
5254void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5255{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005256 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 +00005257
5258 try
5259 {
5260 if (index >= gl::MAX_VERTEX_ATTRIBS)
5261 {
5262 return error(GL_INVALID_VALUE);
5263 }
5264
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005265 gl::Context *context = gl::getContext();
5266
5267 if (context)
5268 {
5269 GLfloat vals[4] = { x, y, z, 1 };
5270 context->setVertexAttrib(index, vals);
5271 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005272 }
5273 catch(std::bad_alloc&)
5274 {
5275 return error(GL_OUT_OF_MEMORY);
5276 }
5277}
5278
5279void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5280{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005281 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005282
5283 try
5284 {
5285 if (index >= gl::MAX_VERTEX_ATTRIBS)
5286 {
5287 return error(GL_INVALID_VALUE);
5288 }
5289
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005290 gl::Context *context = gl::getContext();
5291
5292 if (context)
5293 {
5294 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5295 context->setVertexAttrib(index, vals);
5296 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005297 }
5298 catch(std::bad_alloc&)
5299 {
5300 return error(GL_OUT_OF_MEMORY);
5301 }
5302}
5303
5304void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5305{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005306 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 +00005307
5308 try
5309 {
5310 if (index >= gl::MAX_VERTEX_ATTRIBS)
5311 {
5312 return error(GL_INVALID_VALUE);
5313 }
5314
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005315 gl::Context *context = gl::getContext();
5316
5317 if (context)
5318 {
5319 GLfloat vals[4] = { x, y, z, w };
5320 context->setVertexAttrib(index, vals);
5321 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005322 }
5323 catch(std::bad_alloc&)
5324 {
5325 return error(GL_OUT_OF_MEMORY);
5326 }
5327}
5328
5329void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5330{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005331 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005332
5333 try
5334 {
5335 if (index >= gl::MAX_VERTEX_ATTRIBS)
5336 {
5337 return error(GL_INVALID_VALUE);
5338 }
5339
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005340 gl::Context *context = gl::getContext();
5341
5342 if (context)
5343 {
5344 context->setVertexAttrib(index, values);
5345 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005346 }
5347 catch(std::bad_alloc&)
5348 {
5349 return error(GL_OUT_OF_MEMORY);
5350 }
5351}
5352
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005353void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005354{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005355 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005356 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005357 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005358
5359 try
5360 {
5361 if (index >= gl::MAX_VERTEX_ATTRIBS)
5362 {
5363 return error(GL_INVALID_VALUE);
5364 }
5365
5366 if (size < 1 || size > 4)
5367 {
5368 return error(GL_INVALID_VALUE);
5369 }
5370
5371 switch (type)
5372 {
5373 case GL_BYTE:
5374 case GL_UNSIGNED_BYTE:
5375 case GL_SHORT:
5376 case GL_UNSIGNED_SHORT:
5377 case GL_FIXED:
5378 case GL_FLOAT:
5379 break;
5380 default:
5381 return error(GL_INVALID_ENUM);
5382 }
5383
5384 if (stride < 0)
5385 {
5386 return error(GL_INVALID_VALUE);
5387 }
5388
5389 gl::Context *context = gl::getContext();
5390
5391 if (context)
5392 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005393 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005394 }
5395 }
5396 catch(std::bad_alloc&)
5397 {
5398 return error(GL_OUT_OF_MEMORY);
5399 }
5400}
5401
5402void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5403{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005404 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 +00005405
5406 try
5407 {
5408 if (width < 0 || height < 0)
5409 {
5410 return error(GL_INVALID_VALUE);
5411 }
5412
5413 gl::Context *context = gl::getContext();
5414
5415 if (context)
5416 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005417 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005418 }
5419 }
5420 catch(std::bad_alloc&)
5421 {
5422 return error(GL_OUT_OF_MEMORY);
5423 }
5424}
5425
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005426void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5427 GLbitfield mask, GLenum filter)
5428{
5429 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5430 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5431 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5432 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5433
5434 try
5435 {
5436 switch (filter)
5437 {
5438 case GL_NEAREST:
5439 break;
5440 default:
5441 return error(GL_INVALID_ENUM);
5442 }
5443
5444 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5445 {
5446 return error(GL_INVALID_VALUE);
5447 }
5448
5449 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5450 {
5451 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5452 return error(GL_INVALID_OPERATION);
5453 }
5454
5455 gl::Context *context = gl::getContext();
5456
5457 if (context)
5458 {
5459 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5460 {
5461 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5462 return error(GL_INVALID_OPERATION);
5463 }
5464
5465 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5466 }
5467 }
5468 catch(std::bad_alloc&)
5469 {
5470 return error(GL_OUT_OF_MEMORY);
5471 }
5472}
5473
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005474void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5475 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005476{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005477 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5478 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005479 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005480 target, level, internalformat, width, height, depth, border, format, type, pixels);
5481
5482 try
5483 {
5484 UNIMPLEMENTED(); // FIXME
5485 }
5486 catch(std::bad_alloc&)
5487 {
5488 return error(GL_OUT_OF_MEMORY);
5489 }
5490}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005491
5492__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5493{
5494 struct Extension
5495 {
5496 const char *name;
5497 __eglMustCastToProperFunctionPointerType address;
5498 };
5499
5500 static const Extension glExtensions[] =
5501 {
5502 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00005503 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005504 };
5505
5506 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5507 {
5508 if (strcmp(procname, glExtensions[ext].name) == 0)
5509 {
5510 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5511 }
5512 }
5513
5514 return NULL;
5515}
5516
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005517}