blob: 25d083be2bb9075448ec27b5f538d8c61b373fb2 [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
1071 texture->copyImage(level, internalformat, x, y, width, height, source);
1072 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001073 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001074 {
1075 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1076
1077 if (!texture)
1078 {
1079 return error(GL_INVALID_OPERATION);
1080 }
1081
daniel@transgaming.com01868132010-08-24 19:21:17 +00001082 if (texture->isCompressed())
1083 {
1084 return error(GL_INVALID_OPERATION);
1085 }
1086
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001087 texture->copyImage(target, level, internalformat, x, y, width, height, source);
1088 }
1089 else
1090 {
1091 UNREACHABLE();
1092 }
1093 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001094 }
1095 catch(std::bad_alloc&)
1096 {
1097 return error(GL_OUT_OF_MEMORY);
1098 }
1099}
1100
1101void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1102{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001103 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1104 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001105 target, level, xoffset, yoffset, x, y, width, height);
1106
1107 try
1108 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001109 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001110 {
1111 return error(GL_INVALID_ENUM);
1112 }
1113
1114 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001115 {
1116 return error(GL_INVALID_VALUE);
1117 }
1118
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001119 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1120 {
1121 return error(GL_INVALID_VALUE);
1122 }
1123
1124 if (width == 0 || height == 0)
1125 {
1126 return;
1127 }
1128
1129 gl::Context *context = gl::getContext();
1130
1131 if (context)
1132 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001133 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +00001134 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1135 {
1136 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1137 }
1138
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00001139 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1140 {
1141 return error(GL_INVALID_OPERATION);
1142 }
1143
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00001144 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001145 if (target == GL_TEXTURE_2D)
1146 {
1147 gl::Texture2D *texture = context->getTexture2D();
1148
1149 if (!texture)
1150 {
1151 return error(GL_INVALID_OPERATION);
1152 }
1153
daniel@transgaming.com01868132010-08-24 19:21:17 +00001154 if (texture->isCompressed())
1155 {
1156 return error(GL_INVALID_OPERATION);
1157 }
1158
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001159 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
1160 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00001161 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001162 {
1163 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1164
1165 if (!texture)
1166 {
1167 return error(GL_INVALID_OPERATION);
1168 }
1169
daniel@transgaming.com01868132010-08-24 19:21:17 +00001170 if (texture->isCompressed())
1171 {
1172 return error(GL_INVALID_OPERATION);
1173 }
1174
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001175 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
1176 }
1177 else
1178 {
1179 UNREACHABLE();
1180 }
1181 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001182 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +00001183
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001184 catch(std::bad_alloc&)
1185 {
1186 return error(GL_OUT_OF_MEMORY);
1187 }
1188}
1189
1190GLuint __stdcall glCreateProgram(void)
1191{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001192 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001193
1194 try
1195 {
1196 gl::Context *context = gl::getContext();
1197
1198 if (context)
1199 {
1200 return context->createProgram();
1201 }
1202 }
1203 catch(std::bad_alloc&)
1204 {
1205 return error(GL_OUT_OF_MEMORY, 0);
1206 }
1207
1208 return 0;
1209}
1210
1211GLuint __stdcall glCreateShader(GLenum type)
1212{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001213 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001214
1215 try
1216 {
1217 gl::Context *context = gl::getContext();
1218
1219 if (context)
1220 {
1221 switch (type)
1222 {
1223 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001224 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001225 return context->createShader(type);
1226 default:
1227 return error(GL_INVALID_ENUM, 0);
1228 }
1229 }
1230 }
1231 catch(std::bad_alloc&)
1232 {
1233 return error(GL_OUT_OF_MEMORY, 0);
1234 }
1235
1236 return 0;
1237}
1238
1239void __stdcall glCullFace(GLenum mode)
1240{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001241 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001242
1243 try
1244 {
1245 switch (mode)
1246 {
1247 case GL_FRONT:
1248 case GL_BACK:
1249 case GL_FRONT_AND_BACK:
1250 {
1251 gl::Context *context = gl::getContext();
1252
1253 if (context)
1254 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001255 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001256 }
1257 }
1258 break;
1259 default:
1260 return error(GL_INVALID_ENUM);
1261 }
1262 }
1263 catch(std::bad_alloc&)
1264 {
1265 return error(GL_OUT_OF_MEMORY);
1266 }
1267}
1268
1269void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1270{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001271 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001272
1273 try
1274 {
1275 if (n < 0)
1276 {
1277 return error(GL_INVALID_VALUE);
1278 }
1279
1280 gl::Context *context = gl::getContext();
1281
1282 if (context)
1283 {
1284 for (int i = 0; i < n; i++)
1285 {
1286 context->deleteBuffer(buffers[i]);
1287 }
1288 }
1289 }
1290 catch(std::bad_alloc&)
1291 {
1292 return error(GL_OUT_OF_MEMORY);
1293 }
1294}
1295
1296void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1297{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001298 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001299
1300 try
1301 {
1302 if (n < 0)
1303 {
1304 return error(GL_INVALID_VALUE);
1305 }
1306
1307 gl::Context *context = gl::getContext();
1308
1309 if (context)
1310 {
1311 for (int i = 0; i < n; i++)
1312 {
1313 if (framebuffers[i] != 0)
1314 {
1315 context->deleteFramebuffer(framebuffers[i]);
1316 }
1317 }
1318 }
1319 }
1320 catch(std::bad_alloc&)
1321 {
1322 return error(GL_OUT_OF_MEMORY);
1323 }
1324}
1325
1326void __stdcall glDeleteProgram(GLuint program)
1327{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001328 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001329
1330 try
1331 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001332 if (program == 0)
1333 {
1334 return;
1335 }
1336
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001337 gl::Context *context = gl::getContext();
1338
1339 if (context)
1340 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001341 if (!context->getProgram(program))
1342 {
1343 if(context->getShader(program))
1344 {
1345 return error(GL_INVALID_OPERATION);
1346 }
1347 else
1348 {
1349 return error(GL_INVALID_VALUE);
1350 }
1351 }
1352
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001353 context->deleteProgram(program);
1354 }
1355 }
1356 catch(std::bad_alloc&)
1357 {
1358 return error(GL_OUT_OF_MEMORY);
1359 }
1360}
1361
1362void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1363{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001364 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001365
1366 try
1367 {
1368 if (n < 0)
1369 {
1370 return error(GL_INVALID_VALUE);
1371 }
1372
1373 gl::Context *context = gl::getContext();
1374
1375 if (context)
1376 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001377 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001378 {
1379 context->deleteRenderbuffer(renderbuffers[i]);
1380 }
1381 }
1382 }
1383 catch(std::bad_alloc&)
1384 {
1385 return error(GL_OUT_OF_MEMORY);
1386 }
1387}
1388
1389void __stdcall glDeleteShader(GLuint shader)
1390{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001391 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001392
1393 try
1394 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001395 if (shader == 0)
1396 {
1397 return;
1398 }
1399
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001400 gl::Context *context = gl::getContext();
1401
1402 if (context)
1403 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001404 if (!context->getShader(shader))
1405 {
1406 if(context->getProgram(shader))
1407 {
1408 return error(GL_INVALID_OPERATION);
1409 }
1410 else
1411 {
1412 return error(GL_INVALID_VALUE);
1413 }
1414 }
1415
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001416 context->deleteShader(shader);
1417 }
1418 }
1419 catch(std::bad_alloc&)
1420 {
1421 return error(GL_OUT_OF_MEMORY);
1422 }
1423}
1424
1425void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1426{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001427 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001428
1429 try
1430 {
1431 if (n < 0)
1432 {
1433 return error(GL_INVALID_VALUE);
1434 }
1435
1436 gl::Context *context = gl::getContext();
1437
1438 if (context)
1439 {
1440 for (int i = 0; i < n; i++)
1441 {
1442 if (textures[i] != 0)
1443 {
1444 context->deleteTexture(textures[i]);
1445 }
1446 }
1447 }
1448 }
1449 catch(std::bad_alloc&)
1450 {
1451 return error(GL_OUT_OF_MEMORY);
1452 }
1453}
1454
1455void __stdcall glDepthFunc(GLenum func)
1456{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001457 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001458
1459 try
1460 {
1461 switch (func)
1462 {
1463 case GL_NEVER:
1464 case GL_ALWAYS:
1465 case GL_LESS:
1466 case GL_LEQUAL:
1467 case GL_EQUAL:
1468 case GL_GREATER:
1469 case GL_GEQUAL:
1470 case GL_NOTEQUAL:
1471 break;
1472 default:
1473 return error(GL_INVALID_ENUM);
1474 }
1475
1476 gl::Context *context = gl::getContext();
1477
1478 if (context)
1479 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001480 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001481 }
1482 }
1483 catch(std::bad_alloc&)
1484 {
1485 return error(GL_OUT_OF_MEMORY);
1486 }
1487}
1488
1489void __stdcall glDepthMask(GLboolean flag)
1490{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001491 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001492
1493 try
1494 {
1495 gl::Context *context = gl::getContext();
1496
1497 if (context)
1498 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001499 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001500 }
1501 }
1502 catch(std::bad_alloc&)
1503 {
1504 return error(GL_OUT_OF_MEMORY);
1505 }
1506}
1507
1508void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1509{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001510 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001511
1512 try
1513 {
1514 gl::Context *context = gl::getContext();
1515
1516 if (context)
1517 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001518 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001519 }
1520 }
1521 catch(std::bad_alloc&)
1522 {
1523 return error(GL_OUT_OF_MEMORY);
1524 }
1525}
1526
1527void __stdcall glDetachShader(GLuint program, GLuint shader)
1528{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001529 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001530
1531 try
1532 {
1533 gl::Context *context = gl::getContext();
1534
1535 if (context)
1536 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001537
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001538 gl::Program *programObject = context->getProgram(program);
1539 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001540
1541 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001542 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001543 gl::Shader *shaderByProgramHandle;
1544 shaderByProgramHandle = context->getShader(program);
1545 if (!shaderByProgramHandle)
1546 {
1547 return error(GL_INVALID_VALUE);
1548 }
1549 else
1550 {
1551 return error(GL_INVALID_OPERATION);
1552 }
1553 }
1554
1555 if (!shaderObject)
1556 {
1557 gl::Program *programByShaderHandle = context->getProgram(shader);
1558 if (!programByShaderHandle)
1559 {
1560 return error(GL_INVALID_VALUE);
1561 }
1562 else
1563 {
1564 return error(GL_INVALID_OPERATION);
1565 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001566 }
1567
1568 if (!programObject->detachShader(shaderObject))
1569 {
1570 return error(GL_INVALID_OPERATION);
1571 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001572 }
1573 }
1574 catch(std::bad_alloc&)
1575 {
1576 return error(GL_OUT_OF_MEMORY);
1577 }
1578}
1579
1580void __stdcall glDisable(GLenum cap)
1581{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001582 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001583
1584 try
1585 {
1586 gl::Context *context = gl::getContext();
1587
1588 if (context)
1589 {
1590 switch (cap)
1591 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001592 case GL_CULL_FACE: context->setCullFace(false); break;
1593 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1594 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1595 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1596 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1597 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1598 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1599 case GL_BLEND: context->setBlend(false); break;
1600 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001601 default:
1602 return error(GL_INVALID_ENUM);
1603 }
1604 }
1605 }
1606 catch(std::bad_alloc&)
1607 {
1608 return error(GL_OUT_OF_MEMORY);
1609 }
1610}
1611
1612void __stdcall glDisableVertexAttribArray(GLuint index)
1613{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001614 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001615
1616 try
1617 {
1618 if (index >= gl::MAX_VERTEX_ATTRIBS)
1619 {
1620 return error(GL_INVALID_VALUE);
1621 }
1622
1623 gl::Context *context = gl::getContext();
1624
1625 if (context)
1626 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001627 context->setVertexAttribEnabled(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001628 }
1629 }
1630 catch(std::bad_alloc&)
1631 {
1632 return error(GL_OUT_OF_MEMORY);
1633 }
1634}
1635
1636void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1637{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001638 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001639
1640 try
1641 {
1642 if (count < 0 || first < 0)
1643 {
1644 return error(GL_INVALID_VALUE);
1645 }
1646
1647 gl::Context *context = gl::getContext();
1648
1649 if (context)
1650 {
1651 context->drawArrays(mode, first, count);
1652 }
1653 }
1654 catch(std::bad_alloc&)
1655 {
1656 return error(GL_OUT_OF_MEMORY);
1657 }
1658}
1659
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001660void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001661{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001662 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 +00001663 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001664
1665 try
1666 {
1667 if (count < 0)
1668 {
1669 return error(GL_INVALID_VALUE);
1670 }
1671
1672 switch (type)
1673 {
1674 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001675 case GL_UNSIGNED_SHORT:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00001676 case GL_UNSIGNED_INT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001677 break;
1678 default:
1679 return error(GL_INVALID_ENUM);
1680 }
1681
1682 gl::Context *context = gl::getContext();
1683
1684 if (context)
1685 {
1686 context->drawElements(mode, count, type, indices);
1687 }
1688 }
1689 catch(std::bad_alloc&)
1690 {
1691 return error(GL_OUT_OF_MEMORY);
1692 }
1693}
1694
1695void __stdcall glEnable(GLenum cap)
1696{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001697 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001698
1699 try
1700 {
1701 gl::Context *context = gl::getContext();
1702
1703 if (context)
1704 {
1705 switch (cap)
1706 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001707 case GL_CULL_FACE: context->setCullFace(true); break;
1708 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1709 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1710 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1711 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1712 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1713 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1714 case GL_BLEND: context->setBlend(true); break;
1715 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001716 default:
1717 return error(GL_INVALID_ENUM);
1718 }
1719 }
1720 }
1721 catch(std::bad_alloc&)
1722 {
1723 return error(GL_OUT_OF_MEMORY);
1724 }
1725}
1726
1727void __stdcall glEnableVertexAttribArray(GLuint index)
1728{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001729 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001730
1731 try
1732 {
1733 if (index >= gl::MAX_VERTEX_ATTRIBS)
1734 {
1735 return error(GL_INVALID_VALUE);
1736 }
1737
1738 gl::Context *context = gl::getContext();
1739
1740 if (context)
1741 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001742 context->setVertexAttribEnabled(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001743 }
1744 }
1745 catch(std::bad_alloc&)
1746 {
1747 return error(GL_OUT_OF_MEMORY);
1748 }
1749}
1750
1751void __stdcall glFinish(void)
1752{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001753 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001754
1755 try
1756 {
1757 gl::Context *context = gl::getContext();
1758
1759 if (context)
1760 {
1761 context->finish();
1762 }
1763 }
1764 catch(std::bad_alloc&)
1765 {
1766 return error(GL_OUT_OF_MEMORY);
1767 }
1768}
1769
1770void __stdcall glFlush(void)
1771{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001772 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001773
1774 try
1775 {
1776 gl::Context *context = gl::getContext();
1777
1778 if (context)
1779 {
1780 context->flush();
1781 }
1782 }
1783 catch(std::bad_alloc&)
1784 {
1785 return error(GL_OUT_OF_MEMORY);
1786 }
1787}
1788
1789void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1790{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001791 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1792 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001793
1794 try
1795 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001796 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1797 || renderbuffertarget != GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001798 {
1799 return error(GL_INVALID_ENUM);
1800 }
1801
1802 gl::Context *context = gl::getContext();
1803
1804 if (context)
1805 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001806 gl::Framebuffer *framebuffer = NULL;
1807 GLuint framebufferHandle = 0;
1808 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1809 {
1810 framebuffer = context->getReadFramebuffer();
1811 framebufferHandle = context->getReadFramebufferHandle();
1812 }
1813 else
1814 {
1815 framebuffer = context->getDrawFramebuffer();
1816 framebufferHandle = context->getDrawFramebufferHandle();
1817 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001818
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001819 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001820 {
1821 return error(GL_INVALID_OPERATION);
1822 }
1823
1824 switch (attachment)
1825 {
1826 case GL_COLOR_ATTACHMENT0:
1827 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1828 break;
1829 case GL_DEPTH_ATTACHMENT:
1830 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1831 break;
1832 case GL_STENCIL_ATTACHMENT:
1833 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1834 break;
1835 default:
1836 return error(GL_INVALID_ENUM);
1837 }
1838 }
1839 }
1840 catch(std::bad_alloc&)
1841 {
1842 return error(GL_OUT_OF_MEMORY);
1843 }
1844}
1845
1846void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1847{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001848 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1849 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001850
1851 try
1852 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001853 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001854 {
1855 return error(GL_INVALID_ENUM);
1856 }
1857
1858 switch (attachment)
1859 {
1860 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001861 case GL_DEPTH_ATTACHMENT:
1862 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001863 break;
1864 default:
1865 return error(GL_INVALID_ENUM);
1866 }
1867
1868 gl::Context *context = gl::getContext();
1869
1870 if (context)
1871 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001872 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001873 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001874 textarget = GL_NONE;
1875 }
1876 else
1877 {
1878 gl::Texture *tex = context->getTexture(texture);
1879
1880 if (tex == NULL)
1881 {
1882 return error(GL_INVALID_OPERATION);
1883 }
1884
daniel@transgaming.com01868132010-08-24 19:21:17 +00001885 if (tex->isCompressed())
1886 {
1887 return error(GL_INVALID_OPERATION);
1888 }
1889
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001890 switch (textarget)
1891 {
1892 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001893 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001894 {
1895 return error(GL_INVALID_OPERATION);
1896 }
1897 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001898
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001899 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001900 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001901 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001902 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001903 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001904 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001905 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1906 {
1907 return error(GL_INVALID_OPERATION);
1908 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001909 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001910
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001911 default:
1912 return error(GL_INVALID_ENUM);
1913 }
1914
1915 if (level != 0)
1916 {
1917 return error(GL_INVALID_VALUE);
1918 }
1919 }
1920
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001921 gl::Framebuffer *framebuffer = NULL;
1922 GLuint framebufferHandle = 0;
1923 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1924 {
1925 framebuffer = context->getReadFramebuffer();
1926 framebufferHandle = context->getReadFramebufferHandle();
1927 }
1928 else
1929 {
1930 framebuffer = context->getDrawFramebuffer();
1931 framebufferHandle = context->getDrawFramebufferHandle();
1932 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001933
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001934 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001935 {
1936 return error(GL_INVALID_OPERATION);
1937 }
1938
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001939 switch (attachment)
1940 {
1941 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
1942 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
1943 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
1944 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001945 }
1946 }
1947 catch(std::bad_alloc&)
1948 {
1949 return error(GL_OUT_OF_MEMORY);
1950 }
1951}
1952
1953void __stdcall glFrontFace(GLenum mode)
1954{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001955 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001956
1957 try
1958 {
1959 switch (mode)
1960 {
1961 case GL_CW:
1962 case GL_CCW:
1963 {
1964 gl::Context *context = gl::getContext();
1965
1966 if (context)
1967 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001968 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001969 }
1970 }
1971 break;
1972 default:
1973 return error(GL_INVALID_ENUM);
1974 }
1975 }
1976 catch(std::bad_alloc&)
1977 {
1978 return error(GL_OUT_OF_MEMORY);
1979 }
1980}
1981
1982void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1983{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001984 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001985
1986 try
1987 {
1988 if (n < 0)
1989 {
1990 return error(GL_INVALID_VALUE);
1991 }
1992
1993 gl::Context *context = gl::getContext();
1994
1995 if (context)
1996 {
1997 for (int i = 0; i < n; i++)
1998 {
1999 buffers[i] = context->createBuffer();
2000 }
2001 }
2002 }
2003 catch(std::bad_alloc&)
2004 {
2005 return error(GL_OUT_OF_MEMORY);
2006 }
2007}
2008
2009void __stdcall glGenerateMipmap(GLenum target)
2010{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002011 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002012
2013 try
2014 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002015 gl::Context *context = gl::getContext();
2016
2017 if (context)
2018 {
2019 gl::Texture *texture;
2020
2021 switch (target)
2022 {
2023 case GL_TEXTURE_2D:
2024 texture = context->getTexture2D();
2025 break;
2026
2027 case GL_TEXTURE_CUBE_MAP:
2028 texture = context->getTextureCubeMap();
2029 break;
2030
2031 default:
2032 return error(GL_INVALID_ENUM);
2033 }
2034
daniel@transgaming.com01868132010-08-24 19:21:17 +00002035 if (texture->isCompressed())
2036 {
2037 return error(GL_INVALID_OPERATION);
2038 }
2039
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00002040 texture->generateMipmaps();
2041 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002042 }
2043 catch(std::bad_alloc&)
2044 {
2045 return error(GL_OUT_OF_MEMORY);
2046 }
2047}
2048
2049void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2050{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002051 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002052
2053 try
2054 {
2055 if (n < 0)
2056 {
2057 return error(GL_INVALID_VALUE);
2058 }
2059
2060 gl::Context *context = gl::getContext();
2061
2062 if (context)
2063 {
2064 for (int i = 0; i < n; i++)
2065 {
2066 framebuffers[i] = context->createFramebuffer();
2067 }
2068 }
2069 }
2070 catch(std::bad_alloc&)
2071 {
2072 return error(GL_OUT_OF_MEMORY);
2073 }
2074}
2075
2076void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2077{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002078 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002079
2080 try
2081 {
2082 if (n < 0)
2083 {
2084 return error(GL_INVALID_VALUE);
2085 }
2086
2087 gl::Context *context = gl::getContext();
2088
2089 if (context)
2090 {
2091 for (int i = 0; i < n; i++)
2092 {
2093 renderbuffers[i] = context->createRenderbuffer();
2094 }
2095 }
2096 }
2097 catch(std::bad_alloc&)
2098 {
2099 return error(GL_OUT_OF_MEMORY);
2100 }
2101}
2102
2103void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2104{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002105 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002106
2107 try
2108 {
2109 if (n < 0)
2110 {
2111 return error(GL_INVALID_VALUE);
2112 }
2113
2114 gl::Context *context = gl::getContext();
2115
2116 if (context)
2117 {
2118 for (int i = 0; i < n; i++)
2119 {
2120 textures[i] = context->createTexture();
2121 }
2122 }
2123 }
2124 catch(std::bad_alloc&)
2125 {
2126 return error(GL_OUT_OF_MEMORY);
2127 }
2128}
2129
daniel@transgaming.com85423182010-04-22 13:35:27 +00002130void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002131{
daniel@transgaming.com85423182010-04-22 13:35:27 +00002132 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2133 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002134 program, index, bufsize, length, size, type, name);
2135
2136 try
2137 {
2138 if (bufsize < 0)
2139 {
2140 return error(GL_INVALID_VALUE);
2141 }
2142
daniel@transgaming.com85423182010-04-22 13:35:27 +00002143 gl::Context *context = gl::getContext();
2144
2145 if (context)
2146 {
2147 gl::Program *programObject = context->getProgram(program);
2148
2149 if (!programObject)
2150 {
2151 if (context->getShader(program))
2152 {
2153 return error(GL_INVALID_OPERATION);
2154 }
2155 else
2156 {
2157 return error(GL_INVALID_VALUE);
2158 }
2159 }
2160
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002161 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00002162 {
2163 return error(GL_INVALID_VALUE);
2164 }
2165
2166 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2167 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002168 }
2169 catch(std::bad_alloc&)
2170 {
2171 return error(GL_OUT_OF_MEMORY);
2172 }
2173}
2174
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002175void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002176{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002177 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002178 "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 +00002179 program, index, bufsize, length, size, type, name);
2180
2181 try
2182 {
2183 if (bufsize < 0)
2184 {
2185 return error(GL_INVALID_VALUE);
2186 }
2187
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002188 gl::Context *context = gl::getContext();
2189
2190 if (context)
2191 {
2192 gl::Program *programObject = context->getProgram(program);
2193
2194 if (!programObject)
2195 {
2196 if (context->getShader(program))
2197 {
2198 return error(GL_INVALID_OPERATION);
2199 }
2200 else
2201 {
2202 return error(GL_INVALID_VALUE);
2203 }
2204 }
2205
2206 if (index >= (GLuint)programObject->getActiveUniformCount())
2207 {
2208 return error(GL_INVALID_VALUE);
2209 }
2210
2211 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2212 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002213 }
2214 catch(std::bad_alloc&)
2215 {
2216 return error(GL_OUT_OF_MEMORY);
2217 }
2218}
2219
2220void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2221{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002222 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2223 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002224
2225 try
2226 {
2227 if (maxcount < 0)
2228 {
2229 return error(GL_INVALID_VALUE);
2230 }
2231
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002232 gl::Context *context = gl::getContext();
2233
2234 if (context)
2235 {
2236 gl::Program *programObject = context->getProgram(program);
2237
2238 if (!programObject)
2239 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002240 if (context->getShader(program))
2241 {
2242 return error(GL_INVALID_OPERATION);
2243 }
2244 else
2245 {
2246 return error(GL_INVALID_VALUE);
2247 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002248 }
2249
2250 return programObject->getAttachedShaders(maxcount, count, shaders);
2251 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002252 }
2253 catch(std::bad_alloc&)
2254 {
2255 return error(GL_OUT_OF_MEMORY);
2256 }
2257}
2258
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002259int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002260{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002261 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002262
2263 try
2264 {
2265 gl::Context *context = gl::getContext();
2266
2267 if (context)
2268 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002269
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002270 gl::Program *programObject = context->getProgram(program);
2271
2272 if (!programObject)
2273 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002274 if (context->getShader(program))
2275 {
2276 return error(GL_INVALID_OPERATION, -1);
2277 }
2278 else
2279 {
2280 return error(GL_INVALID_VALUE, -1);
2281 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002282 }
2283
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002284 if (!programObject->isLinked())
2285 {
2286 return error(GL_INVALID_OPERATION, -1);
2287 }
2288
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002289 return programObject->getAttributeLocation(name);
2290 }
2291 }
2292 catch(std::bad_alloc&)
2293 {
2294 return error(GL_OUT_OF_MEMORY, -1);
2295 }
2296
2297 return -1;
2298}
2299
2300void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2301{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002302 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002303
2304 try
2305 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002306 gl::Context *context = gl::getContext();
2307
2308 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002309 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002310 if (!(context->getBooleanv(pname, params)))
2311 {
2312 GLenum nativeType;
2313 unsigned int numParams = 0;
2314 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2315 return error(GL_INVALID_ENUM);
2316
2317 if (numParams == 0)
2318 return; // it is known that the pname is valid, but there are no parameters to return
2319
2320 if (nativeType == GL_FLOAT)
2321 {
2322 GLfloat *floatParams = NULL;
2323 floatParams = new GLfloat[numParams];
2324
2325 context->getFloatv(pname, floatParams);
2326
2327 for (unsigned int i = 0; i < numParams; ++i)
2328 {
2329 if (floatParams[i] == 0.0f)
2330 params[i] = GL_FALSE;
2331 else
2332 params[i] = GL_TRUE;
2333 }
2334
2335 delete [] floatParams;
2336 }
2337 else if (nativeType == GL_INT)
2338 {
2339 GLint *intParams = NULL;
2340 intParams = new GLint[numParams];
2341
2342 context->getIntegerv(pname, intParams);
2343
2344 for (unsigned int i = 0; i < numParams; ++i)
2345 {
2346 if (intParams[i] == 0)
2347 params[i] = GL_FALSE;
2348 else
2349 params[i] = GL_TRUE;
2350 }
2351
2352 delete [] intParams;
2353 }
2354 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002355 }
2356 }
2357 catch(std::bad_alloc&)
2358 {
2359 return error(GL_OUT_OF_MEMORY);
2360 }
2361}
2362
2363void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2364{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002365 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 +00002366
2367 try
2368 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002369 gl::Context *context = gl::getContext();
2370
2371 if (context)
2372 {
2373 gl::Buffer *buffer;
2374
2375 switch (target)
2376 {
2377 case GL_ARRAY_BUFFER:
2378 buffer = context->getArrayBuffer();
2379 break;
2380 case GL_ELEMENT_ARRAY_BUFFER:
2381 buffer = context->getElementArrayBuffer();
2382 break;
2383 default: return error(GL_INVALID_ENUM);
2384 }
2385
2386 if (!buffer)
2387 {
2388 // A null buffer means that "0" is bound to the requested buffer target
2389 return error(GL_INVALID_OPERATION);
2390 }
2391
2392 switch (pname)
2393 {
2394 case GL_BUFFER_USAGE:
2395 *params = buffer->usage();
2396 break;
2397 case GL_BUFFER_SIZE:
2398 *params = buffer->size();
2399 break;
2400 default: return error(GL_INVALID_ENUM);
2401 }
2402 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002403 }
2404 catch(std::bad_alloc&)
2405 {
2406 return error(GL_OUT_OF_MEMORY);
2407 }
2408}
2409
2410GLenum __stdcall glGetError(void)
2411{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002412 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002413
2414 gl::Context *context = gl::getContext();
2415
2416 if (context)
2417 {
2418 return context->getError();
2419 }
2420
2421 return GL_NO_ERROR;
2422}
2423
2424void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2425{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002426 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002427
2428 try
2429 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002430 gl::Context *context = gl::getContext();
2431
2432 if (context)
2433 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002434 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002435 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002436 GLenum nativeType;
2437 unsigned int numParams = 0;
2438 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2439 return error(GL_INVALID_ENUM);
2440
2441 if (numParams == 0)
2442 return; // it is known that the pname is valid, but that there are no parameters to return.
2443
2444 if (nativeType == GL_BOOL)
2445 {
2446 GLboolean *boolParams = NULL;
2447 boolParams = new GLboolean[numParams];
2448
2449 context->getBooleanv(pname, boolParams);
2450
2451 for (unsigned int i = 0; i < numParams; ++i)
2452 {
2453 if (boolParams[i] == GL_FALSE)
2454 params[i] = 0.0f;
2455 else
2456 params[i] = 1.0f;
2457 }
2458
2459 delete [] boolParams;
2460 }
2461 else if (nativeType == GL_INT)
2462 {
2463 GLint *intParams = NULL;
2464 intParams = new GLint[numParams];
2465
2466 context->getIntegerv(pname, intParams);
2467
2468 for (unsigned int i = 0; i < numParams; ++i)
2469 {
2470 params[i] = (GLfloat)intParams[i];
2471 }
2472
2473 delete [] intParams;
2474 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002475 }
2476 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002477 }
2478 catch(std::bad_alloc&)
2479 {
2480 return error(GL_OUT_OF_MEMORY);
2481 }
2482}
2483
2484void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2485{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002486 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2487 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002488
2489 try
2490 {
2491 gl::Context *context = gl::getContext();
2492
2493 if (context)
2494 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002495 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002496 {
2497 return error(GL_INVALID_ENUM);
2498 }
2499
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002500 gl::Framebuffer *framebuffer = NULL;
2501 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2502 {
2503 if(context->getReadFramebufferHandle() == 0)
2504 {
2505 return error(GL_INVALID_OPERATION);
2506 }
2507
2508 framebuffer = context->getReadFramebuffer();
2509 }
2510 else
2511 {
2512 if (context->getDrawFramebufferHandle() == 0)
2513 {
2514 return error(GL_INVALID_OPERATION);
2515 }
2516
2517 framebuffer = context->getDrawFramebuffer();
2518 }
2519
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002520 GLenum attachmentType;
2521 GLuint attachmentHandle;
2522 switch (attachment)
2523 {
2524 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002525 attachmentType = framebuffer->getColorbufferType();
2526 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002527 break;
2528 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002529 attachmentType = framebuffer->getDepthbufferType();
2530 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002531 break;
2532 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002533 attachmentType = framebuffer->getStencilbufferType();
2534 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002535 break;
2536 default: return error(GL_INVALID_ENUM);
2537 }
2538
2539 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002540 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002541 {
2542 attachmentObjectType = attachmentType;
2543 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002544 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002545 {
2546 attachmentObjectType = GL_TEXTURE;
2547 }
2548 else UNREACHABLE();
2549
2550 switch (pname)
2551 {
2552 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2553 *params = attachmentObjectType;
2554 break;
2555 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2556 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2557 {
2558 *params = attachmentHandle;
2559 }
2560 else
2561 {
2562 return error(GL_INVALID_ENUM);
2563 }
2564 break;
2565 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2566 if (attachmentObjectType == GL_TEXTURE)
2567 {
2568 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2569 }
2570 else
2571 {
2572 return error(GL_INVALID_ENUM);
2573 }
2574 break;
2575 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2576 if (attachmentObjectType == GL_TEXTURE)
2577 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002578 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002579 {
2580 *params = attachmentType;
2581 }
2582 else
2583 {
2584 *params = 0;
2585 }
2586 }
2587 else
2588 {
2589 return error(GL_INVALID_ENUM);
2590 }
2591 break;
2592 default:
2593 return error(GL_INVALID_ENUM);
2594 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002595 }
2596 }
2597 catch(std::bad_alloc&)
2598 {
2599 return error(GL_OUT_OF_MEMORY);
2600 }
2601}
2602
2603void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2604{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002605 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002606
2607 try
2608 {
2609 gl::Context *context = gl::getContext();
2610
2611 if (context)
2612 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002613 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002614 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002615 GLenum nativeType;
2616 unsigned int numParams = 0;
2617 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2618 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002619
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002620 if (numParams == 0)
2621 return; // it is known that pname is valid, but there are no parameters to return
2622
2623 if (nativeType == GL_BOOL)
2624 {
2625 GLboolean *boolParams = NULL;
2626 boolParams = new GLboolean[numParams];
2627
2628 context->getBooleanv(pname, boolParams);
2629
2630 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002631 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002632 if (boolParams[i] == GL_FALSE)
2633 params[i] = 0;
2634 else
2635 params[i] = 1;
2636 }
2637
2638 delete [] boolParams;
2639 }
2640 else if (nativeType == GL_FLOAT)
2641 {
2642 GLfloat *floatParams = NULL;
2643 floatParams = new GLfloat[numParams];
2644
2645 context->getFloatv(pname, floatParams);
2646
2647 for (unsigned int i = 0; i < numParams; ++i)
2648 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002649 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 +00002650 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002651 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002652 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002653 else
2654 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 +00002655 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002656
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002657 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002658 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002659 }
2660 }
2661 }
2662 catch(std::bad_alloc&)
2663 {
2664 return error(GL_OUT_OF_MEMORY);
2665 }
2666}
2667
2668void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2669{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002670 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002671
2672 try
2673 {
2674 gl::Context *context = gl::getContext();
2675
2676 if (context)
2677 {
2678 gl::Program *programObject = context->getProgram(program);
2679
2680 if (!programObject)
2681 {
2682 return error(GL_INVALID_VALUE);
2683 }
2684
2685 switch (pname)
2686 {
2687 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002688 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002689 return;
2690 case GL_LINK_STATUS:
2691 *params = programObject->isLinked();
2692 return;
2693 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002694 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002695 return;
2696 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002697 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002698 return;
2699 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002700 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002701 return;
2702 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002703 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002704 return;
2705 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002706 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002707 return;
2708 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002709 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002710 return;
2711 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002712 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002713 return;
2714 default:
2715 return error(GL_INVALID_ENUM);
2716 }
2717 }
2718 }
2719 catch(std::bad_alloc&)
2720 {
2721 return error(GL_OUT_OF_MEMORY);
2722 }
2723}
2724
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002725void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002726{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002727 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 +00002728 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002729
2730 try
2731 {
2732 if (bufsize < 0)
2733 {
2734 return error(GL_INVALID_VALUE);
2735 }
2736
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002737 gl::Context *context = gl::getContext();
2738
2739 if (context)
2740 {
2741 gl::Program *programObject = context->getProgram(program);
2742
2743 if (!programObject)
2744 {
2745 return error(GL_INVALID_VALUE);
2746 }
2747
2748 programObject->getInfoLog(bufsize, length, infolog);
2749 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002750 }
2751 catch(std::bad_alloc&)
2752 {
2753 return error(GL_OUT_OF_MEMORY);
2754 }
2755}
2756
2757void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2758{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002759 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 +00002760
2761 try
2762 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002763 gl::Context *context = gl::getContext();
2764
2765 if (context)
2766 {
2767 if (target != GL_RENDERBUFFER)
2768 {
2769 return error(GL_INVALID_ENUM);
2770 }
2771
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002772 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002773 {
2774 return error(GL_INVALID_OPERATION);
2775 }
2776
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002777 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002778
2779 switch (pname)
2780 {
2781 case GL_RENDERBUFFER_WIDTH:
2782 *params = renderbuffer->getWidth();
2783 break;
2784 case GL_RENDERBUFFER_HEIGHT:
2785 *params = renderbuffer->getHeight();
2786 break;
2787 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2788 *params = renderbuffer->getFormat();
2789 break;
2790 case GL_RENDERBUFFER_RED_SIZE:
2791 if (renderbuffer->isColorbuffer())
2792 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002793 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002794 }
2795 else
2796 {
2797 *params = 0;
2798 }
2799 break;
2800 case GL_RENDERBUFFER_GREEN_SIZE:
2801 if (renderbuffer->isColorbuffer())
2802 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002803 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002804 }
2805 else
2806 {
2807 *params = 0;
2808 }
2809 break;
2810 case GL_RENDERBUFFER_BLUE_SIZE:
2811 if (renderbuffer->isColorbuffer())
2812 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002813 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002814 }
2815 else
2816 {
2817 *params = 0;
2818 }
2819 break;
2820 case GL_RENDERBUFFER_ALPHA_SIZE:
2821 if (renderbuffer->isColorbuffer())
2822 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002823 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002824 }
2825 else
2826 {
2827 *params = 0;
2828 }
2829 break;
2830 case GL_RENDERBUFFER_DEPTH_SIZE:
2831 if (renderbuffer->isDepthbuffer())
2832 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002833 *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002834 }
2835 else
2836 {
2837 *params = 0;
2838 }
2839 break;
2840 case GL_RENDERBUFFER_STENCIL_SIZE:
2841 if (renderbuffer->isStencilbuffer())
2842 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002843 *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002844 }
2845 else
2846 {
2847 *params = 0;
2848 }
2849 break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002850 case GL_RENDERBUFFER_SAMPLES_ANGLE:
2851 {
2852 if (context->getMaxSupportedSamples() != 0)
2853 {
2854 *params = renderbuffer->getStorage()->getSamples();
2855 }
2856 else
2857 {
2858 return error(GL_INVALID_ENUM);
2859 }
2860 }
2861 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002862 default:
2863 return error(GL_INVALID_ENUM);
2864 }
2865 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002866 }
2867 catch(std::bad_alloc&)
2868 {
2869 return error(GL_OUT_OF_MEMORY);
2870 }
2871}
2872
2873void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2874{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002875 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002876
2877 try
2878 {
2879 gl::Context *context = gl::getContext();
2880
2881 if (context)
2882 {
2883 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002884
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002885 if (!shaderObject)
2886 {
2887 return error(GL_INVALID_VALUE);
2888 }
2889
2890 switch (pname)
2891 {
2892 case GL_SHADER_TYPE:
2893 *params = shaderObject->getType();
2894 return;
2895 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002896 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002897 return;
2898 case GL_COMPILE_STATUS:
2899 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2900 return;
2901 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002902 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002903 return;
2904 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002905 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002906 return;
2907 default:
2908 return error(GL_INVALID_ENUM);
2909 }
2910 }
2911 }
2912 catch(std::bad_alloc&)
2913 {
2914 return error(GL_OUT_OF_MEMORY);
2915 }
2916}
2917
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002918void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002919{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002920 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 +00002921 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002922
2923 try
2924 {
2925 if (bufsize < 0)
2926 {
2927 return error(GL_INVALID_VALUE);
2928 }
2929
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002930 gl::Context *context = gl::getContext();
2931
2932 if (context)
2933 {
2934 gl::Shader *shaderObject = context->getShader(shader);
2935
2936 if (!shaderObject)
2937 {
2938 return error(GL_INVALID_VALUE);
2939 }
2940
2941 shaderObject->getInfoLog(bufsize, length, infolog);
2942 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002943 }
2944 catch(std::bad_alloc&)
2945 {
2946 return error(GL_OUT_OF_MEMORY);
2947 }
2948}
2949
2950void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2951{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002952 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2953 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002954
2955 try
2956 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002957 switch (shadertype)
2958 {
2959 case GL_VERTEX_SHADER:
2960 case GL_FRAGMENT_SHADER:
2961 break;
2962 default:
2963 return error(GL_INVALID_ENUM);
2964 }
2965
2966 switch (precisiontype)
2967 {
2968 case GL_LOW_FLOAT:
2969 case GL_MEDIUM_FLOAT:
2970 case GL_HIGH_FLOAT:
2971 // Assume IEEE 754 precision
2972 range[0] = 127;
2973 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002974 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002975 break;
2976 case GL_LOW_INT:
2977 case GL_MEDIUM_INT:
2978 case GL_HIGH_INT:
2979 // Some (most) hardware only supports single-precision floating-point numbers,
2980 // which can accurately represent integers up to +/-16777216
2981 range[0] = 24;
2982 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002983 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002984 break;
2985 default:
2986 return error(GL_INVALID_ENUM);
2987 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002988 }
2989 catch(std::bad_alloc&)
2990 {
2991 return error(GL_OUT_OF_MEMORY);
2992 }
2993}
2994
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002995void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002996{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002997 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 +00002998 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002999
3000 try
3001 {
3002 if (bufsize < 0)
3003 {
3004 return error(GL_INVALID_VALUE);
3005 }
3006
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003007 gl::Context *context = gl::getContext();
3008
3009 if (context)
3010 {
3011 gl::Shader *shaderObject = context->getShader(shader);
3012
3013 if (!shaderObject)
3014 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003015 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00003016 }
3017
3018 shaderObject->getSource(bufsize, length, source);
3019 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003020 }
3021 catch(std::bad_alloc&)
3022 {
3023 return error(GL_OUT_OF_MEMORY);
3024 }
3025}
3026
3027const GLubyte* __stdcall glGetString(GLenum name)
3028{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003029 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003030
3031 try
3032 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003033 gl::Context *context = gl::getContext();
3034
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003035 switch (name)
3036 {
3037 case GL_VENDOR:
3038 return (GLubyte*)"TransGaming Inc.";
3039 case GL_RENDERER:
3040 return (GLubyte*)"ANGLE";
3041 case GL_VERSION:
3042 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
3043 case GL_SHADING_LANGUAGE_VERSION:
3044 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
3045 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00003046 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003047 default:
3048 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3049 }
3050 }
3051 catch(std::bad_alloc&)
3052 {
3053 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3054 }
3055
3056 return NULL;
3057}
3058
3059void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3060{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003061 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 +00003062
3063 try
3064 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003065 gl::Context *context = gl::getContext();
3066
3067 if (context)
3068 {
3069 gl::Texture *texture;
3070
3071 switch (target)
3072 {
3073 case GL_TEXTURE_2D:
3074 texture = context->getTexture2D();
3075 break;
3076 case GL_TEXTURE_CUBE_MAP:
3077 texture = context->getTextureCubeMap();
3078 break;
3079 default:
3080 return error(GL_INVALID_ENUM);
3081 }
3082
3083 switch (pname)
3084 {
3085 case GL_TEXTURE_MAG_FILTER:
3086 *params = (GLfloat)texture->getMagFilter();
3087 break;
3088 case GL_TEXTURE_MIN_FILTER:
3089 *params = (GLfloat)texture->getMinFilter();
3090 break;
3091 case GL_TEXTURE_WRAP_S:
3092 *params = (GLfloat)texture->getWrapS();
3093 break;
3094 case GL_TEXTURE_WRAP_T:
3095 *params = (GLfloat)texture->getWrapT();
3096 break;
3097 default:
3098 return error(GL_INVALID_ENUM);
3099 }
3100 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003101 }
3102 catch(std::bad_alloc&)
3103 {
3104 return error(GL_OUT_OF_MEMORY);
3105 }
3106}
3107
3108void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3109{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003110 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 +00003111
3112 try
3113 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00003114 gl::Context *context = gl::getContext();
3115
3116 if (context)
3117 {
3118 gl::Texture *texture;
3119
3120 switch (target)
3121 {
3122 case GL_TEXTURE_2D:
3123 texture = context->getTexture2D();
3124 break;
3125 case GL_TEXTURE_CUBE_MAP:
3126 texture = context->getTextureCubeMap();
3127 break;
3128 default:
3129 return error(GL_INVALID_ENUM);
3130 }
3131
3132 switch (pname)
3133 {
3134 case GL_TEXTURE_MAG_FILTER:
3135 *params = texture->getMagFilter();
3136 break;
3137 case GL_TEXTURE_MIN_FILTER:
3138 *params = texture->getMinFilter();
3139 break;
3140 case GL_TEXTURE_WRAP_S:
3141 *params = texture->getWrapS();
3142 break;
3143 case GL_TEXTURE_WRAP_T:
3144 *params = texture->getWrapT();
3145 break;
3146 default:
3147 return error(GL_INVALID_ENUM);
3148 }
3149 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003150 }
3151 catch(std::bad_alloc&)
3152 {
3153 return error(GL_OUT_OF_MEMORY);
3154 }
3155}
3156
3157void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3158{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003159 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003160
3161 try
3162 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003163 gl::Context *context = gl::getContext();
3164
3165 if (context)
3166 {
3167 if (program == 0)
3168 {
3169 return error(GL_INVALID_VALUE);
3170 }
3171
3172 gl::Program *programObject = context->getProgram(program);
3173
3174 if (!programObject || !programObject->isLinked())
3175 {
3176 return error(GL_INVALID_OPERATION);
3177 }
3178
3179 if (!programObject->getUniformfv(location, params))
3180 {
3181 return error(GL_INVALID_OPERATION);
3182 }
3183 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003184 }
3185 catch(std::bad_alloc&)
3186 {
3187 return error(GL_OUT_OF_MEMORY);
3188 }
3189}
3190
3191void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3192{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003193 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003194
3195 try
3196 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00003197 gl::Context *context = gl::getContext();
3198
3199 if (context)
3200 {
3201 if (program == 0)
3202 {
3203 return error(GL_INVALID_VALUE);
3204 }
3205
3206 gl::Program *programObject = context->getProgram(program);
3207
3208 if (!programObject || !programObject->isLinked())
3209 {
3210 return error(GL_INVALID_OPERATION);
3211 }
3212
3213 if (!programObject)
3214 {
3215 return error(GL_INVALID_OPERATION);
3216 }
3217
3218 if (!programObject->getUniformiv(location, params))
3219 {
3220 return error(GL_INVALID_OPERATION);
3221 }
3222 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003223 }
3224 catch(std::bad_alloc&)
3225 {
3226 return error(GL_OUT_OF_MEMORY);
3227 }
3228}
3229
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003230int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003231{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003232 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003233
3234 try
3235 {
3236 gl::Context *context = gl::getContext();
3237
3238 if (strstr(name, "gl_") == name)
3239 {
3240 return -1;
3241 }
3242
3243 if (context)
3244 {
3245 gl::Program *programObject = context->getProgram(program);
3246
3247 if (!programObject)
3248 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003249 if (context->getShader(program))
3250 {
3251 return error(GL_INVALID_OPERATION, -1);
3252 }
3253 else
3254 {
3255 return error(GL_INVALID_VALUE, -1);
3256 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003257 }
3258
3259 if (!programObject->isLinked())
3260 {
3261 return error(GL_INVALID_OPERATION, -1);
3262 }
3263
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003264 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003265 }
3266 }
3267 catch(std::bad_alloc&)
3268 {
3269 return error(GL_OUT_OF_MEMORY, -1);
3270 }
3271
3272 return -1;
3273}
3274
3275void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3276{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003277 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003278
3279 try
3280 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003281 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003282
daniel@transgaming.come0078962010-04-15 20:45:08 +00003283 if (context)
3284 {
3285 if (index >= gl::MAX_VERTEX_ATTRIBS)
3286 {
3287 return error(GL_INVALID_VALUE);
3288 }
3289
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003290 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003291
daniel@transgaming.come0078962010-04-15 20:45:08 +00003292 switch (pname)
3293 {
3294 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003295 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003296 break;
3297 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003298 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003299 break;
3300 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003301 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003302 break;
3303 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003304 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003305 break;
3306 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003307 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003308 break;
3309 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003310 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003311 break;
3312 case GL_CURRENT_VERTEX_ATTRIB:
3313 for (int i = 0; i < 4; ++i)
3314 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003315 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003316 }
3317 break;
3318 default: return error(GL_INVALID_ENUM);
3319 }
3320 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003321 }
3322 catch(std::bad_alloc&)
3323 {
3324 return error(GL_OUT_OF_MEMORY);
3325 }
3326}
3327
3328void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3329{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003330 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003331
3332 try
3333 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003334 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003335
daniel@transgaming.come0078962010-04-15 20:45:08 +00003336 if (context)
3337 {
3338 if (index >= gl::MAX_VERTEX_ATTRIBS)
3339 {
3340 return error(GL_INVALID_VALUE);
3341 }
3342
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003343 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003344
daniel@transgaming.come0078962010-04-15 20:45:08 +00003345 switch (pname)
3346 {
3347 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003348 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003349 break;
3350 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003351 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003352 break;
3353 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003354 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003355 break;
3356 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003357 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003358 break;
3359 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003360 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003361 break;
3362 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003363 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003364 break;
3365 case GL_CURRENT_VERTEX_ATTRIB:
3366 for (int i = 0; i < 4; ++i)
3367 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003368 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003369 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3370 }
3371 break;
3372 default: return error(GL_INVALID_ENUM);
3373 }
3374 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003375 }
3376 catch(std::bad_alloc&)
3377 {
3378 return error(GL_OUT_OF_MEMORY);
3379 }
3380}
3381
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003382void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003383{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003384 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003385
3386 try
3387 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003388 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003389
daniel@transgaming.come0078962010-04-15 20:45:08 +00003390 if (context)
3391 {
3392 if (index >= gl::MAX_VERTEX_ATTRIBS)
3393 {
3394 return error(GL_INVALID_VALUE);
3395 }
3396
3397 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3398 {
3399 return error(GL_INVALID_ENUM);
3400 }
3401
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003402 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003403 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003404 }
3405 catch(std::bad_alloc&)
3406 {
3407 return error(GL_OUT_OF_MEMORY);
3408 }
3409}
3410
3411void __stdcall glHint(GLenum target, GLenum mode)
3412{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003413 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003414
3415 try
3416 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003417 switch (target)
3418 {
3419 case GL_GENERATE_MIPMAP_HINT:
3420 switch (mode)
3421 {
3422 case GL_FASTEST:
3423 case GL_NICEST:
3424 case GL_DONT_CARE:
3425 break;
3426 default:
3427 return error(GL_INVALID_ENUM);
3428 }
3429 break;
3430 default:
3431 return error(GL_INVALID_ENUM);
3432 }
3433
3434 gl::Context *context = gl::getContext();
3435 if (context)
3436 {
3437 if (target == GL_GENERATE_MIPMAP_HINT)
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003438 context->setGenerateMipmapHint(mode);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003439 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003440 }
3441 catch(std::bad_alloc&)
3442 {
3443 return error(GL_OUT_OF_MEMORY);
3444 }
3445}
3446
3447GLboolean __stdcall glIsBuffer(GLuint buffer)
3448{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003449 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003450
3451 try
3452 {
3453 gl::Context *context = gl::getContext();
3454
3455 if (context && buffer)
3456 {
3457 gl::Buffer *bufferObject = context->getBuffer(buffer);
3458
3459 if (bufferObject)
3460 {
3461 return GL_TRUE;
3462 }
3463 }
3464 }
3465 catch(std::bad_alloc&)
3466 {
3467 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3468 }
3469
3470 return GL_FALSE;
3471}
3472
3473GLboolean __stdcall glIsEnabled(GLenum cap)
3474{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003475 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003476
3477 try
3478 {
3479 gl::Context *context = gl::getContext();
3480
3481 if (context)
3482 {
3483 switch (cap)
3484 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003485 case GL_CULL_FACE: return context->isCullFaceEnabled();
3486 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3487 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3488 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3489 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3490 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3491 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3492 case GL_BLEND: return context->isBlendEnabled();
3493 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003494 default:
3495 return error(GL_INVALID_ENUM, false);
3496 }
3497 }
3498 }
3499 catch(std::bad_alloc&)
3500 {
3501 return error(GL_OUT_OF_MEMORY, false);
3502 }
3503
3504 return false;
3505}
3506
3507GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3508{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003509 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003510
3511 try
3512 {
3513 gl::Context *context = gl::getContext();
3514
3515 if (context && framebuffer)
3516 {
3517 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3518
3519 if (framebufferObject)
3520 {
3521 return GL_TRUE;
3522 }
3523 }
3524 }
3525 catch(std::bad_alloc&)
3526 {
3527 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3528 }
3529
3530 return GL_FALSE;
3531}
3532
3533GLboolean __stdcall glIsProgram(GLuint program)
3534{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003535 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003536
3537 try
3538 {
3539 gl::Context *context = gl::getContext();
3540
3541 if (context && program)
3542 {
3543 gl::Program *programObject = context->getProgram(program);
3544
3545 if (programObject)
3546 {
3547 return GL_TRUE;
3548 }
3549 }
3550 }
3551 catch(std::bad_alloc&)
3552 {
3553 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3554 }
3555
3556 return GL_FALSE;
3557}
3558
3559GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3560{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003561 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003562
3563 try
3564 {
3565 gl::Context *context = gl::getContext();
3566
3567 if (context && renderbuffer)
3568 {
3569 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3570
3571 if (renderbufferObject)
3572 {
3573 return GL_TRUE;
3574 }
3575 }
3576 }
3577 catch(std::bad_alloc&)
3578 {
3579 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3580 }
3581
3582 return GL_FALSE;
3583}
3584
3585GLboolean __stdcall glIsShader(GLuint shader)
3586{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003587 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003588
3589 try
3590 {
3591 gl::Context *context = gl::getContext();
3592
3593 if (context && shader)
3594 {
3595 gl::Shader *shaderObject = context->getShader(shader);
3596
3597 if (shaderObject)
3598 {
3599 return GL_TRUE;
3600 }
3601 }
3602 }
3603 catch(std::bad_alloc&)
3604 {
3605 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3606 }
3607
3608 return GL_FALSE;
3609}
3610
3611GLboolean __stdcall glIsTexture(GLuint texture)
3612{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003613 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003614
3615 try
3616 {
3617 gl::Context *context = gl::getContext();
3618
3619 if (context && texture)
3620 {
3621 gl::Texture *textureObject = context->getTexture(texture);
3622
3623 if (textureObject)
3624 {
3625 return GL_TRUE;
3626 }
3627 }
3628 }
3629 catch(std::bad_alloc&)
3630 {
3631 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3632 }
3633
3634 return GL_FALSE;
3635}
3636
3637void __stdcall glLineWidth(GLfloat width)
3638{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003639 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003640
3641 try
3642 {
3643 if (width <= 0.0f)
3644 {
3645 return error(GL_INVALID_VALUE);
3646 }
3647
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003648 gl::Context *context = gl::getContext();
3649
3650 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003651 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003652 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003653 }
3654 }
3655 catch(std::bad_alloc&)
3656 {
3657 return error(GL_OUT_OF_MEMORY);
3658 }
3659}
3660
3661void __stdcall glLinkProgram(GLuint program)
3662{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003663 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003664
3665 try
3666 {
3667 gl::Context *context = gl::getContext();
3668
3669 if (context)
3670 {
3671 gl::Program *programObject = context->getProgram(program);
3672
3673 if (!programObject)
3674 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003675 if (context->getShader(program))
3676 {
3677 return error(GL_INVALID_OPERATION);
3678 }
3679 else
3680 {
3681 return error(GL_INVALID_VALUE);
3682 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003683 }
3684
3685 programObject->link();
3686 }
3687 }
3688 catch(std::bad_alloc&)
3689 {
3690 return error(GL_OUT_OF_MEMORY);
3691 }
3692}
3693
3694void __stdcall glPixelStorei(GLenum pname, GLint param)
3695{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003696 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003697
3698 try
3699 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003700 gl::Context *context = gl::getContext();
3701
3702 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003703 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003704 switch (pname)
3705 {
3706 case GL_UNPACK_ALIGNMENT:
3707 if (param != 1 && param != 2 && param != 4 && param != 8)
3708 {
3709 return error(GL_INVALID_VALUE);
3710 }
3711
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003712 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003713 break;
3714
3715 case GL_PACK_ALIGNMENT:
3716 if (param != 1 && param != 2 && param != 4 && param != 8)
3717 {
3718 return error(GL_INVALID_VALUE);
3719 }
3720
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003721 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003722 break;
3723
3724 default:
3725 return error(GL_INVALID_ENUM);
3726 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003727 }
3728 }
3729 catch(std::bad_alloc&)
3730 {
3731 return error(GL_OUT_OF_MEMORY);
3732 }
3733}
3734
3735void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3736{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003737 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003738
3739 try
3740 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003741 gl::Context *context = gl::getContext();
3742
3743 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003744 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003745 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003746 }
3747 }
3748 catch(std::bad_alloc&)
3749 {
3750 return error(GL_OUT_OF_MEMORY);
3751 }
3752}
3753
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003754void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003755{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003756 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003757 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003758 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003759
3760 try
3761 {
3762 if (width < 0 || height < 0)
3763 {
3764 return error(GL_INVALID_VALUE);
3765 }
3766
3767 switch (format)
3768 {
3769 case GL_RGBA:
3770 switch (type)
3771 {
3772 case GL_UNSIGNED_BYTE:
3773 break;
3774 default:
3775 return error(GL_INVALID_OPERATION);
3776 }
3777 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003778 case GL_BGRA_EXT:
3779 switch (type)
3780 {
3781 case GL_UNSIGNED_BYTE:
3782 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3783 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3784 break;
3785 default:
3786 return error(GL_INVALID_OPERATION);
3787 }
3788 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003789 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3790 switch (type)
3791 {
3792 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3793 break;
3794 default:
3795 return error(GL_INVALID_OPERATION);
3796 }
3797 break;
3798 default:
3799 return error(GL_INVALID_OPERATION);
3800 }
3801
3802 gl::Context *context = gl::getContext();
3803
3804 if (context)
3805 {
3806 context->readPixels(x, y, width, height, format, type, pixels);
3807 }
3808 }
3809 catch(std::bad_alloc&)
3810 {
3811 return error(GL_OUT_OF_MEMORY);
3812 }
3813}
3814
3815void __stdcall glReleaseShaderCompiler(void)
3816{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003817 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003818
3819 try
3820 {
3821 gl::Shader::releaseCompiler();
3822 }
3823 catch(std::bad_alloc&)
3824 {
3825 return error(GL_OUT_OF_MEMORY);
3826 }
3827}
3828
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003829void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003830{
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003831 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3832 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003833
3834 try
3835 {
3836 switch (target)
3837 {
3838 case GL_RENDERBUFFER:
3839 break;
3840 default:
3841 return error(GL_INVALID_ENUM);
3842 }
3843
3844 switch (internalformat)
3845 {
3846 case GL_DEPTH_COMPONENT16:
3847 case GL_RGBA4:
3848 case GL_RGB5_A1:
3849 case GL_RGB565:
3850 case GL_STENCIL_INDEX8:
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003851 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com63977542010-08-24 19:21:02 +00003852 case GL_RGB8_OES:
3853 case GL_RGBA8_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003854 break;
3855 default:
3856 return error(GL_INVALID_ENUM);
3857 }
3858
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003859 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 +00003860 {
3861 return error(GL_INVALID_VALUE);
3862 }
3863
3864 gl::Context *context = gl::getContext();
3865
3866 if (context)
3867 {
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003868 if (samples > context->getMaxSupportedSamples())
3869 {
3870 return error(GL_INVALID_VALUE);
3871 }
3872
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003873 GLuint handle = context->getRenderbufferHandle();
3874 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003875 {
3876 return error(GL_INVALID_OPERATION);
3877 }
3878
3879 switch (internalformat)
3880 {
3881 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003882 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003883 break;
3884 case GL_RGBA4:
3885 case GL_RGB5_A1:
3886 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00003887 case GL_RGB8_OES:
3888 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003889 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003890 break;
3891 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003892 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003893 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003894 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003895 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003896 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003897 default:
3898 return error(GL_INVALID_ENUM);
3899 }
3900 }
3901 }
3902 catch(std::bad_alloc&)
3903 {
3904 return error(GL_OUT_OF_MEMORY);
3905 }
3906}
3907
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003908void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3909{
3910 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
3911}
3912
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003913void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3914{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003915 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003916
3917 try
3918 {
3919 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003920
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003921 if (context)
3922 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00003923 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003924 }
3925 }
3926 catch(std::bad_alloc&)
3927 {
3928 return error(GL_OUT_OF_MEMORY);
3929 }
3930}
3931
3932void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3933{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003934 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 +00003935
3936 try
3937 {
3938 if (width < 0 || height < 0)
3939 {
3940 return error(GL_INVALID_VALUE);
3941 }
3942
3943 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003944
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003945 if (context)
3946 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003947 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003948 }
3949 }
3950 catch(std::bad_alloc&)
3951 {
3952 return error(GL_OUT_OF_MEMORY);
3953 }
3954}
3955
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003956void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003957{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003958 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003959 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003960 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003961
3962 try
3963 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00003964 // No binary shader formats are supported.
3965 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003966 }
3967 catch(std::bad_alloc&)
3968 {
3969 return error(GL_OUT_OF_MEMORY);
3970 }
3971}
3972
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003973void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003974{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003975 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 +00003976 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003977
3978 try
3979 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003980 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003981 {
3982 return error(GL_INVALID_VALUE);
3983 }
3984
3985 gl::Context *context = gl::getContext();
3986
3987 if (context)
3988 {
3989 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003990
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003991 if (!shaderObject)
3992 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003993 if (context->getProgram(shader))
3994 {
3995 return error(GL_INVALID_OPERATION);
3996 }
3997 else
3998 {
3999 return error(GL_INVALID_VALUE);
4000 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004001 }
4002
4003 shaderObject->setSource(count, string, length);
4004 }
4005 }
4006 catch(std::bad_alloc&)
4007 {
4008 return error(GL_OUT_OF_MEMORY);
4009 }
4010}
4011
4012void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4013{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004014 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004015}
4016
4017void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4018{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004019 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 +00004020
4021 try
4022 {
4023 switch (face)
4024 {
4025 case GL_FRONT:
4026 case GL_BACK:
4027 case GL_FRONT_AND_BACK:
4028 break;
4029 default:
4030 return error(GL_INVALID_ENUM);
4031 }
4032
4033 switch (func)
4034 {
4035 case GL_NEVER:
4036 case GL_ALWAYS:
4037 case GL_LESS:
4038 case GL_LEQUAL:
4039 case GL_EQUAL:
4040 case GL_GEQUAL:
4041 case GL_GREATER:
4042 case GL_NOTEQUAL:
4043 break;
4044 default:
4045 return error(GL_INVALID_ENUM);
4046 }
4047
4048 gl::Context *context = gl::getContext();
4049
4050 if (context)
4051 {
4052 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4053 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004054 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004055 }
4056
4057 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4058 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004059 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004060 }
4061 }
4062 }
4063 catch(std::bad_alloc&)
4064 {
4065 return error(GL_OUT_OF_MEMORY);
4066 }
4067}
4068
4069void __stdcall glStencilMask(GLuint mask)
4070{
4071 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4072}
4073
4074void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4075{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004076 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004077
4078 try
4079 {
4080 switch (face)
4081 {
4082 case GL_FRONT:
4083 case GL_BACK:
4084 case GL_FRONT_AND_BACK:
4085 break;
4086 default:
4087 return error(GL_INVALID_ENUM);
4088 }
4089
4090 gl::Context *context = gl::getContext();
4091
4092 if (context)
4093 {
4094 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4095 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004096 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004097 }
4098
4099 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4100 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004101 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004102 }
4103 }
4104 }
4105 catch(std::bad_alloc&)
4106 {
4107 return error(GL_OUT_OF_MEMORY);
4108 }
4109}
4110
4111void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4112{
4113 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4114}
4115
4116void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4117{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004118 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4119 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004120
4121 try
4122 {
4123 switch (face)
4124 {
4125 case GL_FRONT:
4126 case GL_BACK:
4127 case GL_FRONT_AND_BACK:
4128 break;
4129 default:
4130 return error(GL_INVALID_ENUM);
4131 }
4132
4133 switch (fail)
4134 {
4135 case GL_ZERO:
4136 case GL_KEEP:
4137 case GL_REPLACE:
4138 case GL_INCR:
4139 case GL_DECR:
4140 case GL_INVERT:
4141 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004142 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004143 break;
4144 default:
4145 return error(GL_INVALID_ENUM);
4146 }
4147
4148 switch (zfail)
4149 {
4150 case GL_ZERO:
4151 case GL_KEEP:
4152 case GL_REPLACE:
4153 case GL_INCR:
4154 case GL_DECR:
4155 case GL_INVERT:
4156 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004157 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004158 break;
4159 default:
4160 return error(GL_INVALID_ENUM);
4161 }
4162
4163 switch (zpass)
4164 {
4165 case GL_ZERO:
4166 case GL_KEEP:
4167 case GL_REPLACE:
4168 case GL_INCR:
4169 case GL_DECR:
4170 case GL_INVERT:
4171 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004172 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004173 break;
4174 default:
4175 return error(GL_INVALID_ENUM);
4176 }
4177
4178 gl::Context *context = gl::getContext();
4179
4180 if (context)
4181 {
4182 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4183 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004184 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004185 }
4186
4187 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4188 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004189 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004190 }
4191 }
4192 }
4193 catch(std::bad_alloc&)
4194 {
4195 return error(GL_OUT_OF_MEMORY);
4196 }
4197}
4198
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004199void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4200 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004201{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004202 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 +00004203 "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 +00004204 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004205
4206 try
4207 {
4208 if (level < 0 || width < 0 || height < 0)
4209 {
4210 return error(GL_INVALID_VALUE);
4211 }
4212
4213 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
4214 {
4215 return error(GL_INVALID_VALUE);
4216 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004217
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004218 switch (target)
4219 {
4220 case GL_TEXTURE_2D:
4221 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
4222 {
4223 return error(GL_INVALID_VALUE);
4224 }
4225 break;
4226 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4227 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4228 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4229 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4230 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4231 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00004232 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004233 {
4234 return error(GL_INVALID_VALUE);
4235 }
4236
4237 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
4238 {
4239 return error(GL_INVALID_VALUE);
4240 }
4241 break;
4242 default:
4243 return error(GL_INVALID_ENUM);
4244 }
4245
4246 if (internalformat != format)
4247 {
4248 return error(GL_INVALID_OPERATION);
4249 }
4250
4251 switch (internalformat)
4252 {
4253 case GL_ALPHA:
4254 case GL_LUMINANCE:
4255 case GL_LUMINANCE_ALPHA:
4256 switch (type)
4257 {
4258 case GL_UNSIGNED_BYTE:
4259 break;
4260 default:
4261 return error(GL_INVALID_ENUM);
4262 }
4263 break;
4264 case GL_RGB:
4265 switch (type)
4266 {
4267 case GL_UNSIGNED_BYTE:
4268 case GL_UNSIGNED_SHORT_5_6_5:
4269 break;
4270 default:
4271 return error(GL_INVALID_ENUM);
4272 }
4273 break;
4274 case GL_RGBA:
4275 switch (type)
4276 {
4277 case GL_UNSIGNED_BYTE:
4278 case GL_UNSIGNED_SHORT_4_4_4_4:
4279 case GL_UNSIGNED_SHORT_5_5_5_1:
4280 break;
4281 default:
4282 return error(GL_INVALID_ENUM);
4283 }
4284 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004285 case GL_BGRA_EXT:
4286 switch (type)
4287 {
4288 case GL_UNSIGNED_BYTE:
4289 break;
4290 default:
4291 return error(GL_INVALID_ENUM);
4292 }
4293 break;
daniel@transgaming.com01868132010-08-24 19:21:17 +00004294 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
4295 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4296 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004297 default:
4298 return error(GL_INVALID_VALUE);
4299 }
4300
4301 if (border != 0)
4302 {
4303 return error(GL_INVALID_VALUE);
4304 }
4305
4306 gl::Context *context = gl::getContext();
4307
4308 if (context)
4309 {
daniel@transgaming.com01868132010-08-24 19:21:17 +00004310 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4311 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
4312 {
4313 if (context->supportsCompressedTextures())
4314 {
4315 return error(GL_INVALID_OPERATION);
4316 }
4317 else
4318 {
4319 return error(GL_INVALID_ENUM);
4320 }
4321 }
4322
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004323 if (target == GL_TEXTURE_2D)
4324 {
4325 gl::Texture2D *texture = context->getTexture2D();
4326
4327 if (!texture)
4328 {
4329 return error(GL_INVALID_OPERATION);
4330 }
4331
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004332 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004333 }
4334 else
4335 {
4336 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4337
4338 if (!texture)
4339 {
4340 return error(GL_INVALID_OPERATION);
4341 }
4342
4343 switch (target)
4344 {
4345 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004346 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004347 break;
4348 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004349 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004350 break;
4351 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004352 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004353 break;
4354 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004355 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004356 break;
4357 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004358 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004359 break;
4360 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004361 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004362 break;
4363 default: UNREACHABLE();
4364 }
4365 }
4366 }
4367 }
4368 catch(std::bad_alloc&)
4369 {
4370 return error(GL_OUT_OF_MEMORY);
4371 }
4372}
4373
4374void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4375{
4376 glTexParameteri(target, pname, (GLint)param);
4377}
4378
4379void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4380{
4381 glTexParameteri(target, pname, (GLint)*params);
4382}
4383
4384void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4385{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004386 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004387
4388 try
4389 {
4390 gl::Context *context = gl::getContext();
4391
4392 if (context)
4393 {
4394 gl::Texture *texture;
4395
4396 switch (target)
4397 {
4398 case GL_TEXTURE_2D:
4399 texture = context->getTexture2D();
4400 break;
4401 case GL_TEXTURE_CUBE_MAP:
4402 texture = context->getTextureCubeMap();
4403 break;
4404 default:
4405 return error(GL_INVALID_ENUM);
4406 }
4407
4408 switch (pname)
4409 {
4410 case GL_TEXTURE_WRAP_S:
4411 if (!texture->setWrapS((GLenum)param))
4412 {
4413 return error(GL_INVALID_ENUM);
4414 }
4415 break;
4416 case GL_TEXTURE_WRAP_T:
4417 if (!texture->setWrapT((GLenum)param))
4418 {
4419 return error(GL_INVALID_ENUM);
4420 }
4421 break;
4422 case GL_TEXTURE_MIN_FILTER:
4423 if (!texture->setMinFilter((GLenum)param))
4424 {
4425 return error(GL_INVALID_ENUM);
4426 }
4427 break;
4428 case GL_TEXTURE_MAG_FILTER:
4429 if (!texture->setMagFilter((GLenum)param))
4430 {
4431 return error(GL_INVALID_ENUM);
4432 }
4433 break;
4434 default:
4435 return error(GL_INVALID_ENUM);
4436 }
4437 }
4438 }
4439 catch(std::bad_alloc&)
4440 {
4441 return error(GL_OUT_OF_MEMORY);
4442 }
4443}
4444
4445void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4446{
4447 glTexParameteri(target, pname, *params);
4448}
4449
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004450void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4451 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004452{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004453 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4454 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004455 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004456 target, level, xoffset, yoffset, width, height, format, type, pixels);
4457
4458 try
4459 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004460 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004461 {
4462 return error(GL_INVALID_ENUM);
4463 }
4464
4465 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004466 {
4467 return error(GL_INVALID_VALUE);
4468 }
4469
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004470 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4471 {
4472 return error(GL_INVALID_VALUE);
4473 }
4474
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004475 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004476 {
4477 return error(GL_INVALID_ENUM);
4478 }
4479
4480 if (width == 0 || height == 0 || pixels == NULL)
4481 {
4482 return;
4483 }
4484
4485 gl::Context *context = gl::getContext();
4486
4487 if (context)
4488 {
4489 if (target == GL_TEXTURE_2D)
4490 {
4491 gl::Texture2D *texture = context->getTexture2D();
4492
4493 if (!texture)
4494 {
4495 return error(GL_INVALID_OPERATION);
4496 }
4497
daniel@transgaming.com01868132010-08-24 19:21:17 +00004498 if (texture->isCompressed())
4499 {
4500 return error(GL_INVALID_OPERATION);
4501 }
4502
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004503 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004504 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004505 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004506 {
4507 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4508
4509 if (!texture)
4510 {
4511 return error(GL_INVALID_OPERATION);
4512 }
4513
daniel@transgaming.com01868132010-08-24 19:21:17 +00004514 if (texture->isCompressed())
4515 {
4516 return error(GL_INVALID_OPERATION);
4517 }
4518
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004519 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004520 }
4521 else
4522 {
4523 UNREACHABLE();
4524 }
4525 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004526 }
4527 catch(std::bad_alloc&)
4528 {
4529 return error(GL_OUT_OF_MEMORY);
4530 }
4531}
4532
4533void __stdcall glUniform1f(GLint location, GLfloat x)
4534{
4535 glUniform1fv(location, 1, &x);
4536}
4537
4538void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4539{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004540 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004541
4542 try
4543 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004544 if (count < 0)
4545 {
4546 return error(GL_INVALID_VALUE);
4547 }
4548
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004549 if (location == -1)
4550 {
4551 return;
4552 }
4553
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004554 gl::Context *context = gl::getContext();
4555
4556 if (context)
4557 {
4558 gl::Program *program = context->getCurrentProgram();
4559
4560 if (!program)
4561 {
4562 return error(GL_INVALID_OPERATION);
4563 }
4564
4565 if (!program->setUniform1fv(location, count, v))
4566 {
4567 return error(GL_INVALID_OPERATION);
4568 }
4569 }
4570 }
4571 catch(std::bad_alloc&)
4572 {
4573 return error(GL_OUT_OF_MEMORY);
4574 }
4575}
4576
4577void __stdcall glUniform1i(GLint location, GLint x)
4578{
4579 glUniform1iv(location, 1, &x);
4580}
4581
4582void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4583{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004584 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004585
4586 try
4587 {
4588 if (count < 0)
4589 {
4590 return error(GL_INVALID_VALUE);
4591 }
4592
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004593 if (location == -1)
4594 {
4595 return;
4596 }
4597
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004598 gl::Context *context = gl::getContext();
4599
4600 if (context)
4601 {
4602 gl::Program *program = context->getCurrentProgram();
4603
4604 if (!program)
4605 {
4606 return error(GL_INVALID_OPERATION);
4607 }
4608
4609 if (!program->setUniform1iv(location, count, v))
4610 {
4611 return error(GL_INVALID_OPERATION);
4612 }
4613 }
4614 }
4615 catch(std::bad_alloc&)
4616 {
4617 return error(GL_OUT_OF_MEMORY);
4618 }
4619}
4620
4621void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4622{
4623 GLfloat xy[2] = {x, y};
4624
4625 glUniform2fv(location, 1, (GLfloat*)&xy);
4626}
4627
4628void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4629{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004630 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004631
4632 try
4633 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004634 if (count < 0)
4635 {
4636 return error(GL_INVALID_VALUE);
4637 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004638
4639 if (location == -1)
4640 {
4641 return;
4642 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004643
4644 gl::Context *context = gl::getContext();
4645
4646 if (context)
4647 {
4648 gl::Program *program = context->getCurrentProgram();
4649
4650 if (!program)
4651 {
4652 return error(GL_INVALID_OPERATION);
4653 }
4654
4655 if (!program->setUniform2fv(location, count, v))
4656 {
4657 return error(GL_INVALID_OPERATION);
4658 }
4659 }
4660 }
4661 catch(std::bad_alloc&)
4662 {
4663 return error(GL_OUT_OF_MEMORY);
4664 }
4665}
4666
4667void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4668{
4669 GLint xy[4] = {x, y};
4670
4671 glUniform2iv(location, 1, (GLint*)&xy);
4672}
4673
4674void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4675{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004676 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004677
4678 try
4679 {
4680 if (count < 0)
4681 {
4682 return error(GL_INVALID_VALUE);
4683 }
4684
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004685 if (location == -1)
4686 {
4687 return;
4688 }
4689
4690 gl::Context *context = gl::getContext();
4691
4692 if (context)
4693 {
4694 gl::Program *program = context->getCurrentProgram();
4695
4696 if (!program)
4697 {
4698 return error(GL_INVALID_OPERATION);
4699 }
4700
4701 if (!program->setUniform2iv(location, count, v))
4702 {
4703 return error(GL_INVALID_OPERATION);
4704 }
4705 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004706 }
4707 catch(std::bad_alloc&)
4708 {
4709 return error(GL_OUT_OF_MEMORY);
4710 }
4711}
4712
4713void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4714{
4715 GLfloat xyz[3] = {x, y, z};
4716
4717 glUniform3fv(location, 1, (GLfloat*)&xyz);
4718}
4719
4720void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4721{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004722 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004723
4724 try
4725 {
4726 if (count < 0)
4727 {
4728 return error(GL_INVALID_VALUE);
4729 }
4730
4731 if (location == -1)
4732 {
4733 return;
4734 }
4735
4736 gl::Context *context = gl::getContext();
4737
4738 if (context)
4739 {
4740 gl::Program *program = context->getCurrentProgram();
4741
4742 if (!program)
4743 {
4744 return error(GL_INVALID_OPERATION);
4745 }
4746
4747 if (!program->setUniform3fv(location, count, v))
4748 {
4749 return error(GL_INVALID_OPERATION);
4750 }
4751 }
4752 }
4753 catch(std::bad_alloc&)
4754 {
4755 return error(GL_OUT_OF_MEMORY);
4756 }
4757}
4758
4759void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4760{
4761 GLint xyz[3] = {x, y, z};
4762
4763 glUniform3iv(location, 1, (GLint*)&xyz);
4764}
4765
4766void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4767{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004768 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004769
4770 try
4771 {
4772 if (count < 0)
4773 {
4774 return error(GL_INVALID_VALUE);
4775 }
4776
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004777 if (location == -1)
4778 {
4779 return;
4780 }
4781
4782 gl::Context *context = gl::getContext();
4783
4784 if (context)
4785 {
4786 gl::Program *program = context->getCurrentProgram();
4787
4788 if (!program)
4789 {
4790 return error(GL_INVALID_OPERATION);
4791 }
4792
4793 if (!program->setUniform3iv(location, count, v))
4794 {
4795 return error(GL_INVALID_OPERATION);
4796 }
4797 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004798 }
4799 catch(std::bad_alloc&)
4800 {
4801 return error(GL_OUT_OF_MEMORY);
4802 }
4803}
4804
4805void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4806{
4807 GLfloat xyzw[4] = {x, y, z, w};
4808
4809 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4810}
4811
4812void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4813{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004814 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004815
4816 try
4817 {
4818 if (count < 0)
4819 {
4820 return error(GL_INVALID_VALUE);
4821 }
4822
4823 if (location == -1)
4824 {
4825 return;
4826 }
4827
4828 gl::Context *context = gl::getContext();
4829
4830 if (context)
4831 {
4832 gl::Program *program = context->getCurrentProgram();
4833
4834 if (!program)
4835 {
4836 return error(GL_INVALID_OPERATION);
4837 }
4838
4839 if (!program->setUniform4fv(location, count, v))
4840 {
4841 return error(GL_INVALID_OPERATION);
4842 }
4843 }
4844 }
4845 catch(std::bad_alloc&)
4846 {
4847 return error(GL_OUT_OF_MEMORY);
4848 }
4849}
4850
4851void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4852{
4853 GLint xyzw[4] = {x, y, z, w};
4854
4855 glUniform4iv(location, 1, (GLint*)&xyzw);
4856}
4857
4858void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4859{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004860 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004861
4862 try
4863 {
4864 if (count < 0)
4865 {
4866 return error(GL_INVALID_VALUE);
4867 }
4868
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004869 if (location == -1)
4870 {
4871 return;
4872 }
4873
4874 gl::Context *context = gl::getContext();
4875
4876 if (context)
4877 {
4878 gl::Program *program = context->getCurrentProgram();
4879
4880 if (!program)
4881 {
4882 return error(GL_INVALID_OPERATION);
4883 }
4884
4885 if (!program->setUniform4iv(location, count, v))
4886 {
4887 return error(GL_INVALID_OPERATION);
4888 }
4889 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004890 }
4891 catch(std::bad_alloc&)
4892 {
4893 return error(GL_OUT_OF_MEMORY);
4894 }
4895}
4896
4897void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4898{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004899 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4900 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004901
4902 try
4903 {
4904 if (count < 0 || transpose != GL_FALSE)
4905 {
4906 return error(GL_INVALID_VALUE);
4907 }
4908
4909 if (location == -1)
4910 {
4911 return;
4912 }
4913
4914 gl::Context *context = gl::getContext();
4915
4916 if (context)
4917 {
4918 gl::Program *program = context->getCurrentProgram();
4919
4920 if (!program)
4921 {
4922 return error(GL_INVALID_OPERATION);
4923 }
4924
4925 if (!program->setUniformMatrix2fv(location, count, value))
4926 {
4927 return error(GL_INVALID_OPERATION);
4928 }
4929 }
4930 }
4931 catch(std::bad_alloc&)
4932 {
4933 return error(GL_OUT_OF_MEMORY);
4934 }
4935}
4936
4937void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4938{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004939 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4940 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004941
4942 try
4943 {
4944 if (count < 0 || transpose != GL_FALSE)
4945 {
4946 return error(GL_INVALID_VALUE);
4947 }
4948
4949 if (location == -1)
4950 {
4951 return;
4952 }
4953
4954 gl::Context *context = gl::getContext();
4955
4956 if (context)
4957 {
4958 gl::Program *program = context->getCurrentProgram();
4959
4960 if (!program)
4961 {
4962 return error(GL_INVALID_OPERATION);
4963 }
4964
4965 if (!program->setUniformMatrix3fv(location, count, value))
4966 {
4967 return error(GL_INVALID_OPERATION);
4968 }
4969 }
4970 }
4971 catch(std::bad_alloc&)
4972 {
4973 return error(GL_OUT_OF_MEMORY);
4974 }
4975}
4976
4977void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4978{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004979 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4980 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004981
4982 try
4983 {
4984 if (count < 0 || transpose != GL_FALSE)
4985 {
4986 return error(GL_INVALID_VALUE);
4987 }
4988
4989 if (location == -1)
4990 {
4991 return;
4992 }
4993
4994 gl::Context *context = gl::getContext();
4995
4996 if (context)
4997 {
4998 gl::Program *program = context->getCurrentProgram();
4999
5000 if (!program)
5001 {
5002 return error(GL_INVALID_OPERATION);
5003 }
5004
5005 if (!program->setUniformMatrix4fv(location, count, value))
5006 {
5007 return error(GL_INVALID_OPERATION);
5008 }
5009 }
5010 }
5011 catch(std::bad_alloc&)
5012 {
5013 return error(GL_OUT_OF_MEMORY);
5014 }
5015}
5016
5017void __stdcall glUseProgram(GLuint program)
5018{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005019 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005020
5021 try
5022 {
5023 gl::Context *context = gl::getContext();
5024
5025 if (context)
5026 {
5027 gl::Program *programObject = context->getProgram(program);
5028
daniel@transgaming.comc8478202010-04-13 19:53:35 +00005029 if (!programObject && program != 0)
5030 {
5031 if (context->getShader(program))
5032 {
5033 return error(GL_INVALID_OPERATION);
5034 }
5035 else
5036 {
5037 return error(GL_INVALID_VALUE);
5038 }
5039 }
5040
5041 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005042 {
5043 return error(GL_INVALID_OPERATION);
5044 }
5045
5046 context->useProgram(program);
5047 }
5048 }
5049 catch(std::bad_alloc&)
5050 {
5051 return error(GL_OUT_OF_MEMORY);
5052 }
5053}
5054
5055void __stdcall glValidateProgram(GLuint program)
5056{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005057 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005058
5059 try
5060 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00005061 gl::Context *context = gl::getContext();
5062
5063 if (context)
5064 {
5065 gl::Program *programObject = context->getProgram(program);
5066
5067 if (!programObject)
5068 {
5069 if (context->getShader(program))
5070 {
5071 return error(GL_INVALID_OPERATION);
5072 }
5073 else
5074 {
5075 return error(GL_INVALID_VALUE);
5076 }
5077 }
5078
5079 programObject->validate();
5080 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005081 }
5082 catch(std::bad_alloc&)
5083 {
5084 return error(GL_OUT_OF_MEMORY);
5085 }
5086}
5087
5088void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5089{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005090 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005091
5092 try
5093 {
5094 if (index >= gl::MAX_VERTEX_ATTRIBS)
5095 {
5096 return error(GL_INVALID_VALUE);
5097 }
5098
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005099 gl::Context *context = gl::getContext();
5100
5101 if (context)
5102 {
5103 GLfloat vals[4] = { x, 0, 0, 1 };
5104 context->setVertexAttrib(index, vals);
5105 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005106 }
5107 catch(std::bad_alloc&)
5108 {
5109 return error(GL_OUT_OF_MEMORY);
5110 }
5111}
5112
5113void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5114{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005115 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005116
5117 try
5118 {
5119 if (index >= gl::MAX_VERTEX_ATTRIBS)
5120 {
5121 return error(GL_INVALID_VALUE);
5122 }
5123
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005124 gl::Context *context = gl::getContext();
5125
5126 if (context)
5127 {
5128 GLfloat vals[4] = { values[0], 0, 0, 1 };
5129 context->setVertexAttrib(index, vals);
5130 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005131 }
5132 catch(std::bad_alloc&)
5133 {
5134 return error(GL_OUT_OF_MEMORY);
5135 }
5136}
5137
5138void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5139{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005140 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005141
5142 try
5143 {
5144 if (index >= gl::MAX_VERTEX_ATTRIBS)
5145 {
5146 return error(GL_INVALID_VALUE);
5147 }
5148
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005149 gl::Context *context = gl::getContext();
5150
5151 if (context)
5152 {
5153 GLfloat vals[4] = { x, y, 0, 1 };
5154 context->setVertexAttrib(index, vals);
5155 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005156 }
5157 catch(std::bad_alloc&)
5158 {
5159 return error(GL_OUT_OF_MEMORY);
5160 }
5161}
5162
5163void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5164{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005165 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005166
5167 try
5168 {
5169 if (index >= gl::MAX_VERTEX_ATTRIBS)
5170 {
5171 return error(GL_INVALID_VALUE);
5172 }
5173
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005174 gl::Context *context = gl::getContext();
5175
5176 if (context)
5177 {
5178 GLfloat vals[4] = { values[0], values[1], 0, 1 };
5179 context->setVertexAttrib(index, vals);
5180 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005181 }
5182 catch(std::bad_alloc&)
5183 {
5184 return error(GL_OUT_OF_MEMORY);
5185 }
5186}
5187
5188void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5189{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005190 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 +00005191
5192 try
5193 {
5194 if (index >= gl::MAX_VERTEX_ATTRIBS)
5195 {
5196 return error(GL_INVALID_VALUE);
5197 }
5198
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005199 gl::Context *context = gl::getContext();
5200
5201 if (context)
5202 {
5203 GLfloat vals[4] = { x, y, z, 1 };
5204 context->setVertexAttrib(index, vals);
5205 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005206 }
5207 catch(std::bad_alloc&)
5208 {
5209 return error(GL_OUT_OF_MEMORY);
5210 }
5211}
5212
5213void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5214{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005215 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005216
5217 try
5218 {
5219 if (index >= gl::MAX_VERTEX_ATTRIBS)
5220 {
5221 return error(GL_INVALID_VALUE);
5222 }
5223
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005224 gl::Context *context = gl::getContext();
5225
5226 if (context)
5227 {
5228 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5229 context->setVertexAttrib(index, vals);
5230 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005231 }
5232 catch(std::bad_alloc&)
5233 {
5234 return error(GL_OUT_OF_MEMORY);
5235 }
5236}
5237
5238void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5239{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005240 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 +00005241
5242 try
5243 {
5244 if (index >= gl::MAX_VERTEX_ATTRIBS)
5245 {
5246 return error(GL_INVALID_VALUE);
5247 }
5248
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005249 gl::Context *context = gl::getContext();
5250
5251 if (context)
5252 {
5253 GLfloat vals[4] = { x, y, z, w };
5254 context->setVertexAttrib(index, vals);
5255 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005256 }
5257 catch(std::bad_alloc&)
5258 {
5259 return error(GL_OUT_OF_MEMORY);
5260 }
5261}
5262
5263void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5264{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005265 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005266
5267 try
5268 {
5269 if (index >= gl::MAX_VERTEX_ATTRIBS)
5270 {
5271 return error(GL_INVALID_VALUE);
5272 }
5273
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005274 gl::Context *context = gl::getContext();
5275
5276 if (context)
5277 {
5278 context->setVertexAttrib(index, values);
5279 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005280 }
5281 catch(std::bad_alloc&)
5282 {
5283 return error(GL_OUT_OF_MEMORY);
5284 }
5285}
5286
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005287void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005288{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005289 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005290 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005291 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005292
5293 try
5294 {
5295 if (index >= gl::MAX_VERTEX_ATTRIBS)
5296 {
5297 return error(GL_INVALID_VALUE);
5298 }
5299
5300 if (size < 1 || size > 4)
5301 {
5302 return error(GL_INVALID_VALUE);
5303 }
5304
5305 switch (type)
5306 {
5307 case GL_BYTE:
5308 case GL_UNSIGNED_BYTE:
5309 case GL_SHORT:
5310 case GL_UNSIGNED_SHORT:
5311 case GL_FIXED:
5312 case GL_FLOAT:
5313 break;
5314 default:
5315 return error(GL_INVALID_ENUM);
5316 }
5317
5318 if (stride < 0)
5319 {
5320 return error(GL_INVALID_VALUE);
5321 }
5322
5323 gl::Context *context = gl::getContext();
5324
5325 if (context)
5326 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005327 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005328 }
5329 }
5330 catch(std::bad_alloc&)
5331 {
5332 return error(GL_OUT_OF_MEMORY);
5333 }
5334}
5335
5336void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5337{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005338 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 +00005339
5340 try
5341 {
5342 if (width < 0 || height < 0)
5343 {
5344 return error(GL_INVALID_VALUE);
5345 }
5346
5347 gl::Context *context = gl::getContext();
5348
5349 if (context)
5350 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005351 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005352 }
5353 }
5354 catch(std::bad_alloc&)
5355 {
5356 return error(GL_OUT_OF_MEMORY);
5357 }
5358}
5359
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005360void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5361 GLbitfield mask, GLenum filter)
5362{
5363 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5364 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5365 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5366 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5367
5368 try
5369 {
5370 switch (filter)
5371 {
5372 case GL_NEAREST:
5373 break;
5374 default:
5375 return error(GL_INVALID_ENUM);
5376 }
5377
5378 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5379 {
5380 return error(GL_INVALID_VALUE);
5381 }
5382
5383 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5384 {
5385 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5386 return error(GL_INVALID_OPERATION);
5387 }
5388
5389 gl::Context *context = gl::getContext();
5390
5391 if (context)
5392 {
5393 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5394 {
5395 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5396 return error(GL_INVALID_OPERATION);
5397 }
5398
5399 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5400 }
5401 }
5402 catch(std::bad_alloc&)
5403 {
5404 return error(GL_OUT_OF_MEMORY);
5405 }
5406}
5407
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005408void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5409 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005410{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005411 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5412 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005413 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005414 target, level, internalformat, width, height, depth, border, format, type, pixels);
5415
5416 try
5417 {
5418 UNIMPLEMENTED(); // FIXME
5419 }
5420 catch(std::bad_alloc&)
5421 {
5422 return error(GL_OUT_OF_MEMORY);
5423 }
5424}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005425
5426__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5427{
5428 struct Extension
5429 {
5430 const char *name;
5431 __eglMustCastToProperFunctionPointerType address;
5432 };
5433
5434 static const Extension glExtensions[] =
5435 {
5436 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com01868132010-08-24 19:21:17 +00005437 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005438 };
5439
5440 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5441 {
5442 if (strcmp(procname, glExtensions[ext].name) == 0)
5443 {
5444 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5445 }
5446 }
5447
5448 return NULL;
5449}
5450
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005451}