blob: 7a4b9ab6422ce6af660fe4588630a535888e4b8d [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.com19ffc242010-05-04 03:35:21 +0000739 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000740 {
741 return error(GL_INVALID_ENUM);
742 }
743
744 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000745 {
746 return error(GL_INVALID_VALUE);
747 }
748
daniel@transgaming.com41430492010-03-11 20:36:18 +0000749 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
750 {
751 return error(GL_INVALID_VALUE);
752 }
753
754 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000755 }
756 catch(std::bad_alloc&)
757 {
758 return error(GL_OUT_OF_MEMORY);
759 }
760}
761
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000762void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
763 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000764{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000765 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
766 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000767 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000768 target, level, xoffset, yoffset, width, height, format, imageSize, data);
769
770 try
771 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000772 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000773 {
774 return error(GL_INVALID_ENUM);
775 }
776
777 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000778 {
779 return error(GL_INVALID_VALUE);
780 }
781
daniel@transgaming.com41430492010-03-11 20:36:18 +0000782 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
783 {
784 return error(GL_INVALID_VALUE);
785 }
786
787 if (xoffset != 0 || yoffset != 0)
788 {
789 return error(GL_INVALID_OPERATION);
790 }
791
792 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000793 }
794 catch(std::bad_alloc&)
795 {
796 return error(GL_OUT_OF_MEMORY);
797 }
798}
799
800void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
801{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000802 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
803 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000804 target, level, internalformat, x, y, width, height, border);
805
806 try
807 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000808 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000809 {
810 return error(GL_INVALID_VALUE);
811 }
812
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000813 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
814 {
815 return error(GL_INVALID_VALUE);
816 }
817
818 switch (target)
819 {
820 case GL_TEXTURE_2D:
821 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
822 {
823 return error(GL_INVALID_VALUE);
824 }
825 break;
826 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
827 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
828 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
829 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
830 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
831 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +0000832 if (width != height)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000833 {
834 return error(GL_INVALID_VALUE);
835 }
836
837 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
838 {
839 return error(GL_INVALID_VALUE);
840 }
841 break;
842 default:
843 return error(GL_INVALID_ENUM);
844 }
845
846 switch (internalformat)
847 {
848 case GL_ALPHA:
849 case GL_LUMINANCE:
850 case GL_LUMINANCE_ALPHA:
851 case GL_RGB:
852 case GL_RGBA:
853 break;
854 default:
855 return error(GL_INVALID_VALUE);
856 }
857
858 if (border != 0)
859 {
860 return error(GL_INVALID_VALUE);
861 }
862
863 gl::Context *context = gl::getContext();
864
865 if (context)
866 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000867 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +0000868 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
869 {
870 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
871 }
872
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000873 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
874 {
875 return error(GL_INVALID_OPERATION);
876 }
877
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000878 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000879 if (target == GL_TEXTURE_2D)
880 {
881 gl::Texture2D *texture = context->getTexture2D();
882
883 if (!texture)
884 {
885 return error(GL_INVALID_OPERATION);
886 }
887
888 texture->copyImage(level, internalformat, x, y, width, height, source);
889 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000890 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000891 {
892 gl::TextureCubeMap *texture = context->getTextureCubeMap();
893
894 if (!texture)
895 {
896 return error(GL_INVALID_OPERATION);
897 }
898
899 texture->copyImage(target, level, internalformat, x, y, width, height, source);
900 }
901 else
902 {
903 UNREACHABLE();
904 }
905 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000906 }
907 catch(std::bad_alloc&)
908 {
909 return error(GL_OUT_OF_MEMORY);
910 }
911}
912
913void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
914{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000915 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
916 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000917 target, level, xoffset, yoffset, x, y, width, height);
918
919 try
920 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000921 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000922 {
923 return error(GL_INVALID_ENUM);
924 }
925
926 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000927 {
928 return error(GL_INVALID_VALUE);
929 }
930
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000931 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
932 {
933 return error(GL_INVALID_VALUE);
934 }
935
936 if (width == 0 || height == 0)
937 {
938 return;
939 }
940
941 gl::Context *context = gl::getContext();
942
943 if (context)
944 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000945 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +0000946 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
947 {
948 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
949 }
950
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000951 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
952 {
953 return error(GL_INVALID_OPERATION);
954 }
955
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000956 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000957 if (target == GL_TEXTURE_2D)
958 {
959 gl::Texture2D *texture = context->getTexture2D();
960
961 if (!texture)
962 {
963 return error(GL_INVALID_OPERATION);
964 }
965
966 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
967 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000968 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000969 {
970 gl::TextureCubeMap *texture = context->getTextureCubeMap();
971
972 if (!texture)
973 {
974 return error(GL_INVALID_OPERATION);
975 }
976
977 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
978 }
979 else
980 {
981 UNREACHABLE();
982 }
983 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000984 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000985
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000986 catch(std::bad_alloc&)
987 {
988 return error(GL_OUT_OF_MEMORY);
989 }
990}
991
992GLuint __stdcall glCreateProgram(void)
993{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000994 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000995
996 try
997 {
998 gl::Context *context = gl::getContext();
999
1000 if (context)
1001 {
1002 return context->createProgram();
1003 }
1004 }
1005 catch(std::bad_alloc&)
1006 {
1007 return error(GL_OUT_OF_MEMORY, 0);
1008 }
1009
1010 return 0;
1011}
1012
1013GLuint __stdcall glCreateShader(GLenum type)
1014{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001015 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001016
1017 try
1018 {
1019 gl::Context *context = gl::getContext();
1020
1021 if (context)
1022 {
1023 switch (type)
1024 {
1025 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001026 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001027 return context->createShader(type);
1028 default:
1029 return error(GL_INVALID_ENUM, 0);
1030 }
1031 }
1032 }
1033 catch(std::bad_alloc&)
1034 {
1035 return error(GL_OUT_OF_MEMORY, 0);
1036 }
1037
1038 return 0;
1039}
1040
1041void __stdcall glCullFace(GLenum mode)
1042{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001043 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001044
1045 try
1046 {
1047 switch (mode)
1048 {
1049 case GL_FRONT:
1050 case GL_BACK:
1051 case GL_FRONT_AND_BACK:
1052 {
1053 gl::Context *context = gl::getContext();
1054
1055 if (context)
1056 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001057 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001058 }
1059 }
1060 break;
1061 default:
1062 return error(GL_INVALID_ENUM);
1063 }
1064 }
1065 catch(std::bad_alloc&)
1066 {
1067 return error(GL_OUT_OF_MEMORY);
1068 }
1069}
1070
1071void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1072{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001073 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001074
1075 try
1076 {
1077 if (n < 0)
1078 {
1079 return error(GL_INVALID_VALUE);
1080 }
1081
1082 gl::Context *context = gl::getContext();
1083
1084 if (context)
1085 {
1086 for (int i = 0; i < n; i++)
1087 {
1088 context->deleteBuffer(buffers[i]);
1089 }
1090 }
1091 }
1092 catch(std::bad_alloc&)
1093 {
1094 return error(GL_OUT_OF_MEMORY);
1095 }
1096}
1097
1098void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1099{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001100 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001101
1102 try
1103 {
1104 if (n < 0)
1105 {
1106 return error(GL_INVALID_VALUE);
1107 }
1108
1109 gl::Context *context = gl::getContext();
1110
1111 if (context)
1112 {
1113 for (int i = 0; i < n; i++)
1114 {
1115 if (framebuffers[i] != 0)
1116 {
1117 context->deleteFramebuffer(framebuffers[i]);
1118 }
1119 }
1120 }
1121 }
1122 catch(std::bad_alloc&)
1123 {
1124 return error(GL_OUT_OF_MEMORY);
1125 }
1126}
1127
1128void __stdcall glDeleteProgram(GLuint program)
1129{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001130 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001131
1132 try
1133 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001134 if (program == 0)
1135 {
1136 return;
1137 }
1138
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001139 gl::Context *context = gl::getContext();
1140
1141 if (context)
1142 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001143 if (!context->getProgram(program))
1144 {
1145 if(context->getShader(program))
1146 {
1147 return error(GL_INVALID_OPERATION);
1148 }
1149 else
1150 {
1151 return error(GL_INVALID_VALUE);
1152 }
1153 }
1154
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001155 context->deleteProgram(program);
1156 }
1157 }
1158 catch(std::bad_alloc&)
1159 {
1160 return error(GL_OUT_OF_MEMORY);
1161 }
1162}
1163
1164void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1165{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001166 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001167
1168 try
1169 {
1170 if (n < 0)
1171 {
1172 return error(GL_INVALID_VALUE);
1173 }
1174
1175 gl::Context *context = gl::getContext();
1176
1177 if (context)
1178 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001179 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001180 {
1181 context->deleteRenderbuffer(renderbuffers[i]);
1182 }
1183 }
1184 }
1185 catch(std::bad_alloc&)
1186 {
1187 return error(GL_OUT_OF_MEMORY);
1188 }
1189}
1190
1191void __stdcall glDeleteShader(GLuint shader)
1192{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001193 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001194
1195 try
1196 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001197 if (shader == 0)
1198 {
1199 return;
1200 }
1201
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001202 gl::Context *context = gl::getContext();
1203
1204 if (context)
1205 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001206 if (!context->getShader(shader))
1207 {
1208 if(context->getProgram(shader))
1209 {
1210 return error(GL_INVALID_OPERATION);
1211 }
1212 else
1213 {
1214 return error(GL_INVALID_VALUE);
1215 }
1216 }
1217
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001218 context->deleteShader(shader);
1219 }
1220 }
1221 catch(std::bad_alloc&)
1222 {
1223 return error(GL_OUT_OF_MEMORY);
1224 }
1225}
1226
1227void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1228{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001229 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001230
1231 try
1232 {
1233 if (n < 0)
1234 {
1235 return error(GL_INVALID_VALUE);
1236 }
1237
1238 gl::Context *context = gl::getContext();
1239
1240 if (context)
1241 {
1242 for (int i = 0; i < n; i++)
1243 {
1244 if (textures[i] != 0)
1245 {
1246 context->deleteTexture(textures[i]);
1247 }
1248 }
1249 }
1250 }
1251 catch(std::bad_alloc&)
1252 {
1253 return error(GL_OUT_OF_MEMORY);
1254 }
1255}
1256
1257void __stdcall glDepthFunc(GLenum func)
1258{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001259 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001260
1261 try
1262 {
1263 switch (func)
1264 {
1265 case GL_NEVER:
1266 case GL_ALWAYS:
1267 case GL_LESS:
1268 case GL_LEQUAL:
1269 case GL_EQUAL:
1270 case GL_GREATER:
1271 case GL_GEQUAL:
1272 case GL_NOTEQUAL:
1273 break;
1274 default:
1275 return error(GL_INVALID_ENUM);
1276 }
1277
1278 gl::Context *context = gl::getContext();
1279
1280 if (context)
1281 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001282 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001283 }
1284 }
1285 catch(std::bad_alloc&)
1286 {
1287 return error(GL_OUT_OF_MEMORY);
1288 }
1289}
1290
1291void __stdcall glDepthMask(GLboolean flag)
1292{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001293 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001294
1295 try
1296 {
1297 gl::Context *context = gl::getContext();
1298
1299 if (context)
1300 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001301 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001302 }
1303 }
1304 catch(std::bad_alloc&)
1305 {
1306 return error(GL_OUT_OF_MEMORY);
1307 }
1308}
1309
1310void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1311{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001312 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001313
1314 try
1315 {
1316 gl::Context *context = gl::getContext();
1317
1318 if (context)
1319 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001320 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001321 }
1322 }
1323 catch(std::bad_alloc&)
1324 {
1325 return error(GL_OUT_OF_MEMORY);
1326 }
1327}
1328
1329void __stdcall glDetachShader(GLuint program, GLuint shader)
1330{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001331 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001332
1333 try
1334 {
1335 gl::Context *context = gl::getContext();
1336
1337 if (context)
1338 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001339
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001340 gl::Program *programObject = context->getProgram(program);
1341 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001342
1343 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001344 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001345 gl::Shader *shaderByProgramHandle;
1346 shaderByProgramHandle = context->getShader(program);
1347 if (!shaderByProgramHandle)
1348 {
1349 return error(GL_INVALID_VALUE);
1350 }
1351 else
1352 {
1353 return error(GL_INVALID_OPERATION);
1354 }
1355 }
1356
1357 if (!shaderObject)
1358 {
1359 gl::Program *programByShaderHandle = context->getProgram(shader);
1360 if (!programByShaderHandle)
1361 {
1362 return error(GL_INVALID_VALUE);
1363 }
1364 else
1365 {
1366 return error(GL_INVALID_OPERATION);
1367 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001368 }
1369
1370 if (!programObject->detachShader(shaderObject))
1371 {
1372 return error(GL_INVALID_OPERATION);
1373 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001374 }
1375 }
1376 catch(std::bad_alloc&)
1377 {
1378 return error(GL_OUT_OF_MEMORY);
1379 }
1380}
1381
1382void __stdcall glDisable(GLenum cap)
1383{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001384 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001385
1386 try
1387 {
1388 gl::Context *context = gl::getContext();
1389
1390 if (context)
1391 {
1392 switch (cap)
1393 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001394 case GL_CULL_FACE: context->setCullFace(false); break;
1395 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1396 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1397 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1398 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1399 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1400 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1401 case GL_BLEND: context->setBlend(false); break;
1402 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001403 default:
1404 return error(GL_INVALID_ENUM);
1405 }
1406 }
1407 }
1408 catch(std::bad_alloc&)
1409 {
1410 return error(GL_OUT_OF_MEMORY);
1411 }
1412}
1413
1414void __stdcall glDisableVertexAttribArray(GLuint index)
1415{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001416 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001417
1418 try
1419 {
1420 if (index >= gl::MAX_VERTEX_ATTRIBS)
1421 {
1422 return error(GL_INVALID_VALUE);
1423 }
1424
1425 gl::Context *context = gl::getContext();
1426
1427 if (context)
1428 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001429 context->setVertexAttribEnabled(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001430 }
1431 }
1432 catch(std::bad_alloc&)
1433 {
1434 return error(GL_OUT_OF_MEMORY);
1435 }
1436}
1437
1438void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1439{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001440 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001441
1442 try
1443 {
1444 if (count < 0 || first < 0)
1445 {
1446 return error(GL_INVALID_VALUE);
1447 }
1448
1449 gl::Context *context = gl::getContext();
1450
1451 if (context)
1452 {
1453 context->drawArrays(mode, first, count);
1454 }
1455 }
1456 catch(std::bad_alloc&)
1457 {
1458 return error(GL_OUT_OF_MEMORY);
1459 }
1460}
1461
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001462void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001463{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001464 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 +00001465 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001466
1467 try
1468 {
1469 if (count < 0)
1470 {
1471 return error(GL_INVALID_VALUE);
1472 }
1473
1474 switch (type)
1475 {
1476 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001477 case GL_UNSIGNED_SHORT:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00001478 case GL_UNSIGNED_INT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001479 break;
1480 default:
1481 return error(GL_INVALID_ENUM);
1482 }
1483
1484 gl::Context *context = gl::getContext();
1485
1486 if (context)
1487 {
1488 context->drawElements(mode, count, type, indices);
1489 }
1490 }
1491 catch(std::bad_alloc&)
1492 {
1493 return error(GL_OUT_OF_MEMORY);
1494 }
1495}
1496
1497void __stdcall glEnable(GLenum cap)
1498{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001499 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001500
1501 try
1502 {
1503 gl::Context *context = gl::getContext();
1504
1505 if (context)
1506 {
1507 switch (cap)
1508 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001509 case GL_CULL_FACE: context->setCullFace(true); break;
1510 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1511 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1512 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1513 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1514 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1515 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1516 case GL_BLEND: context->setBlend(true); break;
1517 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001518 default:
1519 return error(GL_INVALID_ENUM);
1520 }
1521 }
1522 }
1523 catch(std::bad_alloc&)
1524 {
1525 return error(GL_OUT_OF_MEMORY);
1526 }
1527}
1528
1529void __stdcall glEnableVertexAttribArray(GLuint index)
1530{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001531 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001532
1533 try
1534 {
1535 if (index >= gl::MAX_VERTEX_ATTRIBS)
1536 {
1537 return error(GL_INVALID_VALUE);
1538 }
1539
1540 gl::Context *context = gl::getContext();
1541
1542 if (context)
1543 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001544 context->setVertexAttribEnabled(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001545 }
1546 }
1547 catch(std::bad_alloc&)
1548 {
1549 return error(GL_OUT_OF_MEMORY);
1550 }
1551}
1552
1553void __stdcall glFinish(void)
1554{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001555 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001556
1557 try
1558 {
1559 gl::Context *context = gl::getContext();
1560
1561 if (context)
1562 {
1563 context->finish();
1564 }
1565 }
1566 catch(std::bad_alloc&)
1567 {
1568 return error(GL_OUT_OF_MEMORY);
1569 }
1570}
1571
1572void __stdcall glFlush(void)
1573{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001574 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001575
1576 try
1577 {
1578 gl::Context *context = gl::getContext();
1579
1580 if (context)
1581 {
1582 context->flush();
1583 }
1584 }
1585 catch(std::bad_alloc&)
1586 {
1587 return error(GL_OUT_OF_MEMORY);
1588 }
1589}
1590
1591void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1592{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001593 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1594 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001595
1596 try
1597 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001598 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1599 || renderbuffertarget != GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001600 {
1601 return error(GL_INVALID_ENUM);
1602 }
1603
1604 gl::Context *context = gl::getContext();
1605
1606 if (context)
1607 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001608 gl::Framebuffer *framebuffer = NULL;
1609 GLuint framebufferHandle = 0;
1610 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1611 {
1612 framebuffer = context->getReadFramebuffer();
1613 framebufferHandle = context->getReadFramebufferHandle();
1614 }
1615 else
1616 {
1617 framebuffer = context->getDrawFramebuffer();
1618 framebufferHandle = context->getDrawFramebufferHandle();
1619 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001620
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001621 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001622 {
1623 return error(GL_INVALID_OPERATION);
1624 }
1625
1626 switch (attachment)
1627 {
1628 case GL_COLOR_ATTACHMENT0:
1629 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1630 break;
1631 case GL_DEPTH_ATTACHMENT:
1632 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1633 break;
1634 case GL_STENCIL_ATTACHMENT:
1635 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1636 break;
1637 default:
1638 return error(GL_INVALID_ENUM);
1639 }
1640 }
1641 }
1642 catch(std::bad_alloc&)
1643 {
1644 return error(GL_OUT_OF_MEMORY);
1645 }
1646}
1647
1648void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001650 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1651 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001652
1653 try
1654 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001655 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001656 {
1657 return error(GL_INVALID_ENUM);
1658 }
1659
1660 switch (attachment)
1661 {
1662 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001663 case GL_DEPTH_ATTACHMENT:
1664 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001665 break;
1666 default:
1667 return error(GL_INVALID_ENUM);
1668 }
1669
1670 gl::Context *context = gl::getContext();
1671
1672 if (context)
1673 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001674 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001675 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001676 textarget = GL_NONE;
1677 }
1678 else
1679 {
1680 gl::Texture *tex = context->getTexture(texture);
1681
1682 if (tex == NULL)
1683 {
1684 return error(GL_INVALID_OPERATION);
1685 }
1686
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001687 switch (textarget)
1688 {
1689 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001690 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001691 {
1692 return error(GL_INVALID_OPERATION);
1693 }
1694 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001695
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001696 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001697 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001698 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001699 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001700 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001701 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001702 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1703 {
1704 return error(GL_INVALID_OPERATION);
1705 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001706 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001707
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001708 default:
1709 return error(GL_INVALID_ENUM);
1710 }
1711
1712 if (level != 0)
1713 {
1714 return error(GL_INVALID_VALUE);
1715 }
1716 }
1717
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001718 gl::Framebuffer *framebuffer = NULL;
1719 GLuint framebufferHandle = 0;
1720 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1721 {
1722 framebuffer = context->getReadFramebuffer();
1723 framebufferHandle = context->getReadFramebufferHandle();
1724 }
1725 else
1726 {
1727 framebuffer = context->getDrawFramebuffer();
1728 framebufferHandle = context->getDrawFramebufferHandle();
1729 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001730
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001731 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001732 {
1733 return error(GL_INVALID_OPERATION);
1734 }
1735
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001736 switch (attachment)
1737 {
1738 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
1739 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
1740 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
1741 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001742 }
1743 }
1744 catch(std::bad_alloc&)
1745 {
1746 return error(GL_OUT_OF_MEMORY);
1747 }
1748}
1749
1750void __stdcall glFrontFace(GLenum mode)
1751{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001752 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001753
1754 try
1755 {
1756 switch (mode)
1757 {
1758 case GL_CW:
1759 case GL_CCW:
1760 {
1761 gl::Context *context = gl::getContext();
1762
1763 if (context)
1764 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001765 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001766 }
1767 }
1768 break;
1769 default:
1770 return error(GL_INVALID_ENUM);
1771 }
1772 }
1773 catch(std::bad_alloc&)
1774 {
1775 return error(GL_OUT_OF_MEMORY);
1776 }
1777}
1778
1779void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1780{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001781 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001782
1783 try
1784 {
1785 if (n < 0)
1786 {
1787 return error(GL_INVALID_VALUE);
1788 }
1789
1790 gl::Context *context = gl::getContext();
1791
1792 if (context)
1793 {
1794 for (int i = 0; i < n; i++)
1795 {
1796 buffers[i] = context->createBuffer();
1797 }
1798 }
1799 }
1800 catch(std::bad_alloc&)
1801 {
1802 return error(GL_OUT_OF_MEMORY);
1803 }
1804}
1805
1806void __stdcall glGenerateMipmap(GLenum target)
1807{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001808 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001809
1810 try
1811 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00001812 gl::Context *context = gl::getContext();
1813
1814 if (context)
1815 {
1816 gl::Texture *texture;
1817
1818 switch (target)
1819 {
1820 case GL_TEXTURE_2D:
1821 texture = context->getTexture2D();
1822 break;
1823
1824 case GL_TEXTURE_CUBE_MAP:
1825 texture = context->getTextureCubeMap();
1826 break;
1827
1828 default:
1829 return error(GL_INVALID_ENUM);
1830 }
1831
1832 texture->generateMipmaps();
1833 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001834 }
1835 catch(std::bad_alloc&)
1836 {
1837 return error(GL_OUT_OF_MEMORY);
1838 }
1839}
1840
1841void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1842{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001843 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001844
1845 try
1846 {
1847 if (n < 0)
1848 {
1849 return error(GL_INVALID_VALUE);
1850 }
1851
1852 gl::Context *context = gl::getContext();
1853
1854 if (context)
1855 {
1856 for (int i = 0; i < n; i++)
1857 {
1858 framebuffers[i] = context->createFramebuffer();
1859 }
1860 }
1861 }
1862 catch(std::bad_alloc&)
1863 {
1864 return error(GL_OUT_OF_MEMORY);
1865 }
1866}
1867
1868void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1869{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001870 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001871
1872 try
1873 {
1874 if (n < 0)
1875 {
1876 return error(GL_INVALID_VALUE);
1877 }
1878
1879 gl::Context *context = gl::getContext();
1880
1881 if (context)
1882 {
1883 for (int i = 0; i < n; i++)
1884 {
1885 renderbuffers[i] = context->createRenderbuffer();
1886 }
1887 }
1888 }
1889 catch(std::bad_alloc&)
1890 {
1891 return error(GL_OUT_OF_MEMORY);
1892 }
1893}
1894
1895void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1896{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001897 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001898
1899 try
1900 {
1901 if (n < 0)
1902 {
1903 return error(GL_INVALID_VALUE);
1904 }
1905
1906 gl::Context *context = gl::getContext();
1907
1908 if (context)
1909 {
1910 for (int i = 0; i < n; i++)
1911 {
1912 textures[i] = context->createTexture();
1913 }
1914 }
1915 }
1916 catch(std::bad_alloc&)
1917 {
1918 return error(GL_OUT_OF_MEMORY);
1919 }
1920}
1921
daniel@transgaming.com85423182010-04-22 13:35:27 +00001922void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001923{
daniel@transgaming.com85423182010-04-22 13:35:27 +00001924 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
1925 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001926 program, index, bufsize, length, size, type, name);
1927
1928 try
1929 {
1930 if (bufsize < 0)
1931 {
1932 return error(GL_INVALID_VALUE);
1933 }
1934
daniel@transgaming.com85423182010-04-22 13:35:27 +00001935 gl::Context *context = gl::getContext();
1936
1937 if (context)
1938 {
1939 gl::Program *programObject = context->getProgram(program);
1940
1941 if (!programObject)
1942 {
1943 if (context->getShader(program))
1944 {
1945 return error(GL_INVALID_OPERATION);
1946 }
1947 else
1948 {
1949 return error(GL_INVALID_VALUE);
1950 }
1951 }
1952
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001953 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00001954 {
1955 return error(GL_INVALID_VALUE);
1956 }
1957
1958 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
1959 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001960 }
1961 catch(std::bad_alloc&)
1962 {
1963 return error(GL_OUT_OF_MEMORY);
1964 }
1965}
1966
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001967void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001968{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001969 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001970 "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 +00001971 program, index, bufsize, length, size, type, name);
1972
1973 try
1974 {
1975 if (bufsize < 0)
1976 {
1977 return error(GL_INVALID_VALUE);
1978 }
1979
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001980 gl::Context *context = gl::getContext();
1981
1982 if (context)
1983 {
1984 gl::Program *programObject = context->getProgram(program);
1985
1986 if (!programObject)
1987 {
1988 if (context->getShader(program))
1989 {
1990 return error(GL_INVALID_OPERATION);
1991 }
1992 else
1993 {
1994 return error(GL_INVALID_VALUE);
1995 }
1996 }
1997
1998 if (index >= (GLuint)programObject->getActiveUniformCount())
1999 {
2000 return error(GL_INVALID_VALUE);
2001 }
2002
2003 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2004 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002005 }
2006 catch(std::bad_alloc&)
2007 {
2008 return error(GL_OUT_OF_MEMORY);
2009 }
2010}
2011
2012void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2013{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002014 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2015 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002016
2017 try
2018 {
2019 if (maxcount < 0)
2020 {
2021 return error(GL_INVALID_VALUE);
2022 }
2023
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002024 gl::Context *context = gl::getContext();
2025
2026 if (context)
2027 {
2028 gl::Program *programObject = context->getProgram(program);
2029
2030 if (!programObject)
2031 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002032 if (context->getShader(program))
2033 {
2034 return error(GL_INVALID_OPERATION);
2035 }
2036 else
2037 {
2038 return error(GL_INVALID_VALUE);
2039 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002040 }
2041
2042 return programObject->getAttachedShaders(maxcount, count, shaders);
2043 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002044 }
2045 catch(std::bad_alloc&)
2046 {
2047 return error(GL_OUT_OF_MEMORY);
2048 }
2049}
2050
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002051int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002052{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002053 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002054
2055 try
2056 {
2057 gl::Context *context = gl::getContext();
2058
2059 if (context)
2060 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002061
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002062 gl::Program *programObject = context->getProgram(program);
2063
2064 if (!programObject)
2065 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002066 if (context->getShader(program))
2067 {
2068 return error(GL_INVALID_OPERATION, -1);
2069 }
2070 else
2071 {
2072 return error(GL_INVALID_VALUE, -1);
2073 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002074 }
2075
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002076 if (!programObject->isLinked())
2077 {
2078 return error(GL_INVALID_OPERATION, -1);
2079 }
2080
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002081 return programObject->getAttributeLocation(name);
2082 }
2083 }
2084 catch(std::bad_alloc&)
2085 {
2086 return error(GL_OUT_OF_MEMORY, -1);
2087 }
2088
2089 return -1;
2090}
2091
2092void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2093{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002094 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002095
2096 try
2097 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002098 gl::Context *context = gl::getContext();
2099
2100 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002101 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002102 if (!(context->getBooleanv(pname, params)))
2103 {
2104 GLenum nativeType;
2105 unsigned int numParams = 0;
2106 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2107 return error(GL_INVALID_ENUM);
2108
2109 if (numParams == 0)
2110 return; // it is known that the pname is valid, but there are no parameters to return
2111
2112 if (nativeType == GL_FLOAT)
2113 {
2114 GLfloat *floatParams = NULL;
2115 floatParams = new GLfloat[numParams];
2116
2117 context->getFloatv(pname, floatParams);
2118
2119 for (unsigned int i = 0; i < numParams; ++i)
2120 {
2121 if (floatParams[i] == 0.0f)
2122 params[i] = GL_FALSE;
2123 else
2124 params[i] = GL_TRUE;
2125 }
2126
2127 delete [] floatParams;
2128 }
2129 else if (nativeType == GL_INT)
2130 {
2131 GLint *intParams = NULL;
2132 intParams = new GLint[numParams];
2133
2134 context->getIntegerv(pname, intParams);
2135
2136 for (unsigned int i = 0; i < numParams; ++i)
2137 {
2138 if (intParams[i] == 0)
2139 params[i] = GL_FALSE;
2140 else
2141 params[i] = GL_TRUE;
2142 }
2143
2144 delete [] intParams;
2145 }
2146 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002147 }
2148 }
2149 catch(std::bad_alloc&)
2150 {
2151 return error(GL_OUT_OF_MEMORY);
2152 }
2153}
2154
2155void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2156{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002157 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 +00002158
2159 try
2160 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002161 gl::Context *context = gl::getContext();
2162
2163 if (context)
2164 {
2165 gl::Buffer *buffer;
2166
2167 switch (target)
2168 {
2169 case GL_ARRAY_BUFFER:
2170 buffer = context->getArrayBuffer();
2171 break;
2172 case GL_ELEMENT_ARRAY_BUFFER:
2173 buffer = context->getElementArrayBuffer();
2174 break;
2175 default: return error(GL_INVALID_ENUM);
2176 }
2177
2178 if (!buffer)
2179 {
2180 // A null buffer means that "0" is bound to the requested buffer target
2181 return error(GL_INVALID_OPERATION);
2182 }
2183
2184 switch (pname)
2185 {
2186 case GL_BUFFER_USAGE:
2187 *params = buffer->usage();
2188 break;
2189 case GL_BUFFER_SIZE:
2190 *params = buffer->size();
2191 break;
2192 default: return error(GL_INVALID_ENUM);
2193 }
2194 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002195 }
2196 catch(std::bad_alloc&)
2197 {
2198 return error(GL_OUT_OF_MEMORY);
2199 }
2200}
2201
2202GLenum __stdcall glGetError(void)
2203{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002204 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002205
2206 gl::Context *context = gl::getContext();
2207
2208 if (context)
2209 {
2210 return context->getError();
2211 }
2212
2213 return GL_NO_ERROR;
2214}
2215
2216void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2217{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002218 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002219
2220 try
2221 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002222 gl::Context *context = gl::getContext();
2223
2224 if (context)
2225 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002226 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002227 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002228 GLenum nativeType;
2229 unsigned int numParams = 0;
2230 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2231 return error(GL_INVALID_ENUM);
2232
2233 if (numParams == 0)
2234 return; // it is known that the pname is valid, but that there are no parameters to return.
2235
2236 if (nativeType == GL_BOOL)
2237 {
2238 GLboolean *boolParams = NULL;
2239 boolParams = new GLboolean[numParams];
2240
2241 context->getBooleanv(pname, boolParams);
2242
2243 for (unsigned int i = 0; i < numParams; ++i)
2244 {
2245 if (boolParams[i] == GL_FALSE)
2246 params[i] = 0.0f;
2247 else
2248 params[i] = 1.0f;
2249 }
2250
2251 delete [] boolParams;
2252 }
2253 else if (nativeType == GL_INT)
2254 {
2255 GLint *intParams = NULL;
2256 intParams = new GLint[numParams];
2257
2258 context->getIntegerv(pname, intParams);
2259
2260 for (unsigned int i = 0; i < numParams; ++i)
2261 {
2262 params[i] = (GLfloat)intParams[i];
2263 }
2264
2265 delete [] intParams;
2266 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002267 }
2268 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002269 }
2270 catch(std::bad_alloc&)
2271 {
2272 return error(GL_OUT_OF_MEMORY);
2273 }
2274}
2275
2276void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2277{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002278 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2279 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002280
2281 try
2282 {
2283 gl::Context *context = gl::getContext();
2284
2285 if (context)
2286 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002287 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002288 {
2289 return error(GL_INVALID_ENUM);
2290 }
2291
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002292 gl::Framebuffer *framebuffer = NULL;
2293 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2294 {
2295 if(context->getReadFramebufferHandle() == 0)
2296 {
2297 return error(GL_INVALID_OPERATION);
2298 }
2299
2300 framebuffer = context->getReadFramebuffer();
2301 }
2302 else
2303 {
2304 if (context->getDrawFramebufferHandle() == 0)
2305 {
2306 return error(GL_INVALID_OPERATION);
2307 }
2308
2309 framebuffer = context->getDrawFramebuffer();
2310 }
2311
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002312 GLenum attachmentType;
2313 GLuint attachmentHandle;
2314 switch (attachment)
2315 {
2316 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002317 attachmentType = framebuffer->getColorbufferType();
2318 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002319 break;
2320 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002321 attachmentType = framebuffer->getDepthbufferType();
2322 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002323 break;
2324 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002325 attachmentType = framebuffer->getStencilbufferType();
2326 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002327 break;
2328 default: return error(GL_INVALID_ENUM);
2329 }
2330
2331 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002332 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002333 {
2334 attachmentObjectType = attachmentType;
2335 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002336 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002337 {
2338 attachmentObjectType = GL_TEXTURE;
2339 }
2340 else UNREACHABLE();
2341
2342 switch (pname)
2343 {
2344 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2345 *params = attachmentObjectType;
2346 break;
2347 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2348 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2349 {
2350 *params = attachmentHandle;
2351 }
2352 else
2353 {
2354 return error(GL_INVALID_ENUM);
2355 }
2356 break;
2357 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2358 if (attachmentObjectType == GL_TEXTURE)
2359 {
2360 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2361 }
2362 else
2363 {
2364 return error(GL_INVALID_ENUM);
2365 }
2366 break;
2367 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2368 if (attachmentObjectType == GL_TEXTURE)
2369 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002370 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002371 {
2372 *params = attachmentType;
2373 }
2374 else
2375 {
2376 *params = 0;
2377 }
2378 }
2379 else
2380 {
2381 return error(GL_INVALID_ENUM);
2382 }
2383 break;
2384 default:
2385 return error(GL_INVALID_ENUM);
2386 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002387 }
2388 }
2389 catch(std::bad_alloc&)
2390 {
2391 return error(GL_OUT_OF_MEMORY);
2392 }
2393}
2394
2395void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2396{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002397 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002398
2399 try
2400 {
2401 gl::Context *context = gl::getContext();
2402
2403 if (context)
2404 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002405 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002406 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002407 GLenum nativeType;
2408 unsigned int numParams = 0;
2409 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2410 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002411
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002412 if (numParams == 0)
2413 return; // it is known that pname is valid, but there are no parameters to return
2414
2415 if (nativeType == GL_BOOL)
2416 {
2417 GLboolean *boolParams = NULL;
2418 boolParams = new GLboolean[numParams];
2419
2420 context->getBooleanv(pname, boolParams);
2421
2422 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002423 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002424 if (boolParams[i] == GL_FALSE)
2425 params[i] = 0;
2426 else
2427 params[i] = 1;
2428 }
2429
2430 delete [] boolParams;
2431 }
2432 else if (nativeType == GL_FLOAT)
2433 {
2434 GLfloat *floatParams = NULL;
2435 floatParams = new GLfloat[numParams];
2436
2437 context->getFloatv(pname, floatParams);
2438
2439 for (unsigned int i = 0; i < numParams; ++i)
2440 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002441 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 +00002442 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002443 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002444 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002445 else
2446 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 +00002447 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002448
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002449 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002450 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002451 }
2452 }
2453 }
2454 catch(std::bad_alloc&)
2455 {
2456 return error(GL_OUT_OF_MEMORY);
2457 }
2458}
2459
2460void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2461{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002462 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002463
2464 try
2465 {
2466 gl::Context *context = gl::getContext();
2467
2468 if (context)
2469 {
2470 gl::Program *programObject = context->getProgram(program);
2471
2472 if (!programObject)
2473 {
2474 return error(GL_INVALID_VALUE);
2475 }
2476
2477 switch (pname)
2478 {
2479 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002480 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002481 return;
2482 case GL_LINK_STATUS:
2483 *params = programObject->isLinked();
2484 return;
2485 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002486 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002487 return;
2488 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002489 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002490 return;
2491 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002492 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002493 return;
2494 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002495 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002496 return;
2497 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002498 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002499 return;
2500 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002501 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002502 return;
2503 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002504 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002505 return;
2506 default:
2507 return error(GL_INVALID_ENUM);
2508 }
2509 }
2510 }
2511 catch(std::bad_alloc&)
2512 {
2513 return error(GL_OUT_OF_MEMORY);
2514 }
2515}
2516
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002517void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002518{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002519 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 +00002520 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002521
2522 try
2523 {
2524 if (bufsize < 0)
2525 {
2526 return error(GL_INVALID_VALUE);
2527 }
2528
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002529 gl::Context *context = gl::getContext();
2530
2531 if (context)
2532 {
2533 gl::Program *programObject = context->getProgram(program);
2534
2535 if (!programObject)
2536 {
2537 return error(GL_INVALID_VALUE);
2538 }
2539
2540 programObject->getInfoLog(bufsize, length, infolog);
2541 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002542 }
2543 catch(std::bad_alloc&)
2544 {
2545 return error(GL_OUT_OF_MEMORY);
2546 }
2547}
2548
2549void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2550{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002551 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 +00002552
2553 try
2554 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002555 gl::Context *context = gl::getContext();
2556
2557 if (context)
2558 {
2559 if (target != GL_RENDERBUFFER)
2560 {
2561 return error(GL_INVALID_ENUM);
2562 }
2563
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002564 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002565 {
2566 return error(GL_INVALID_OPERATION);
2567 }
2568
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002569 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002570
2571 switch (pname)
2572 {
2573 case GL_RENDERBUFFER_WIDTH:
2574 *params = renderbuffer->getWidth();
2575 break;
2576 case GL_RENDERBUFFER_HEIGHT:
2577 *params = renderbuffer->getHeight();
2578 break;
2579 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2580 *params = renderbuffer->getFormat();
2581 break;
2582 case GL_RENDERBUFFER_RED_SIZE:
2583 if (renderbuffer->isColorbuffer())
2584 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002585 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002586 }
2587 else
2588 {
2589 *params = 0;
2590 }
2591 break;
2592 case GL_RENDERBUFFER_GREEN_SIZE:
2593 if (renderbuffer->isColorbuffer())
2594 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002595 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002596 }
2597 else
2598 {
2599 *params = 0;
2600 }
2601 break;
2602 case GL_RENDERBUFFER_BLUE_SIZE:
2603 if (renderbuffer->isColorbuffer())
2604 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002605 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002606 }
2607 else
2608 {
2609 *params = 0;
2610 }
2611 break;
2612 case GL_RENDERBUFFER_ALPHA_SIZE:
2613 if (renderbuffer->isColorbuffer())
2614 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002615 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002616 }
2617 else
2618 {
2619 *params = 0;
2620 }
2621 break;
2622 case GL_RENDERBUFFER_DEPTH_SIZE:
2623 if (renderbuffer->isDepthbuffer())
2624 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002625 *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002626 }
2627 else
2628 {
2629 *params = 0;
2630 }
2631 break;
2632 case GL_RENDERBUFFER_STENCIL_SIZE:
2633 if (renderbuffer->isStencilbuffer())
2634 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002635 *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002636 }
2637 else
2638 {
2639 *params = 0;
2640 }
2641 break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002642 case GL_RENDERBUFFER_SAMPLES_ANGLE:
2643 {
2644 if (context->getMaxSupportedSamples() != 0)
2645 {
2646 *params = renderbuffer->getStorage()->getSamples();
2647 }
2648 else
2649 {
2650 return error(GL_INVALID_ENUM);
2651 }
2652 }
2653 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002654 default:
2655 return error(GL_INVALID_ENUM);
2656 }
2657 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002658 }
2659 catch(std::bad_alloc&)
2660 {
2661 return error(GL_OUT_OF_MEMORY);
2662 }
2663}
2664
2665void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2666{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002667 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002668
2669 try
2670 {
2671 gl::Context *context = gl::getContext();
2672
2673 if (context)
2674 {
2675 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002676
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002677 if (!shaderObject)
2678 {
2679 return error(GL_INVALID_VALUE);
2680 }
2681
2682 switch (pname)
2683 {
2684 case GL_SHADER_TYPE:
2685 *params = shaderObject->getType();
2686 return;
2687 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002688 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002689 return;
2690 case GL_COMPILE_STATUS:
2691 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2692 return;
2693 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002694 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002695 return;
2696 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002697 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002698 return;
2699 default:
2700 return error(GL_INVALID_ENUM);
2701 }
2702 }
2703 }
2704 catch(std::bad_alloc&)
2705 {
2706 return error(GL_OUT_OF_MEMORY);
2707 }
2708}
2709
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002710void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002711{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002712 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 +00002713 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002714
2715 try
2716 {
2717 if (bufsize < 0)
2718 {
2719 return error(GL_INVALID_VALUE);
2720 }
2721
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002722 gl::Context *context = gl::getContext();
2723
2724 if (context)
2725 {
2726 gl::Shader *shaderObject = context->getShader(shader);
2727
2728 if (!shaderObject)
2729 {
2730 return error(GL_INVALID_VALUE);
2731 }
2732
2733 shaderObject->getInfoLog(bufsize, length, infolog);
2734 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002735 }
2736 catch(std::bad_alloc&)
2737 {
2738 return error(GL_OUT_OF_MEMORY);
2739 }
2740}
2741
2742void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2743{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002744 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2745 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002746
2747 try
2748 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002749 switch (shadertype)
2750 {
2751 case GL_VERTEX_SHADER:
2752 case GL_FRAGMENT_SHADER:
2753 break;
2754 default:
2755 return error(GL_INVALID_ENUM);
2756 }
2757
2758 switch (precisiontype)
2759 {
2760 case GL_LOW_FLOAT:
2761 case GL_MEDIUM_FLOAT:
2762 case GL_HIGH_FLOAT:
2763 // Assume IEEE 754 precision
2764 range[0] = 127;
2765 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002766 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002767 break;
2768 case GL_LOW_INT:
2769 case GL_MEDIUM_INT:
2770 case GL_HIGH_INT:
2771 // Some (most) hardware only supports single-precision floating-point numbers,
2772 // which can accurately represent integers up to +/-16777216
2773 range[0] = 24;
2774 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002775 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002776 break;
2777 default:
2778 return error(GL_INVALID_ENUM);
2779 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002780 }
2781 catch(std::bad_alloc&)
2782 {
2783 return error(GL_OUT_OF_MEMORY);
2784 }
2785}
2786
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002787void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002788{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002789 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 +00002790 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002791
2792 try
2793 {
2794 if (bufsize < 0)
2795 {
2796 return error(GL_INVALID_VALUE);
2797 }
2798
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002799 gl::Context *context = gl::getContext();
2800
2801 if (context)
2802 {
2803 gl::Shader *shaderObject = context->getShader(shader);
2804
2805 if (!shaderObject)
2806 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002807 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002808 }
2809
2810 shaderObject->getSource(bufsize, length, source);
2811 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002812 }
2813 catch(std::bad_alloc&)
2814 {
2815 return error(GL_OUT_OF_MEMORY);
2816 }
2817}
2818
2819const GLubyte* __stdcall glGetString(GLenum name)
2820{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002821 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002822
2823 try
2824 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002825 gl::Context *context = gl::getContext();
2826
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002827 switch (name)
2828 {
2829 case GL_VENDOR:
2830 return (GLubyte*)"TransGaming Inc.";
2831 case GL_RENDERER:
2832 return (GLubyte*)"ANGLE";
2833 case GL_VERSION:
2834 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2835 case GL_SHADING_LANGUAGE_VERSION:
2836 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2837 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002838 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002839 default:
2840 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2841 }
2842 }
2843 catch(std::bad_alloc&)
2844 {
2845 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2846 }
2847
2848 return NULL;
2849}
2850
2851void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2852{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002853 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 +00002854
2855 try
2856 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002857 gl::Context *context = gl::getContext();
2858
2859 if (context)
2860 {
2861 gl::Texture *texture;
2862
2863 switch (target)
2864 {
2865 case GL_TEXTURE_2D:
2866 texture = context->getTexture2D();
2867 break;
2868 case GL_TEXTURE_CUBE_MAP:
2869 texture = context->getTextureCubeMap();
2870 break;
2871 default:
2872 return error(GL_INVALID_ENUM);
2873 }
2874
2875 switch (pname)
2876 {
2877 case GL_TEXTURE_MAG_FILTER:
2878 *params = (GLfloat)texture->getMagFilter();
2879 break;
2880 case GL_TEXTURE_MIN_FILTER:
2881 *params = (GLfloat)texture->getMinFilter();
2882 break;
2883 case GL_TEXTURE_WRAP_S:
2884 *params = (GLfloat)texture->getWrapS();
2885 break;
2886 case GL_TEXTURE_WRAP_T:
2887 *params = (GLfloat)texture->getWrapT();
2888 break;
2889 default:
2890 return error(GL_INVALID_ENUM);
2891 }
2892 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002893 }
2894 catch(std::bad_alloc&)
2895 {
2896 return error(GL_OUT_OF_MEMORY);
2897 }
2898}
2899
2900void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2901{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002902 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 +00002903
2904 try
2905 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002906 gl::Context *context = gl::getContext();
2907
2908 if (context)
2909 {
2910 gl::Texture *texture;
2911
2912 switch (target)
2913 {
2914 case GL_TEXTURE_2D:
2915 texture = context->getTexture2D();
2916 break;
2917 case GL_TEXTURE_CUBE_MAP:
2918 texture = context->getTextureCubeMap();
2919 break;
2920 default:
2921 return error(GL_INVALID_ENUM);
2922 }
2923
2924 switch (pname)
2925 {
2926 case GL_TEXTURE_MAG_FILTER:
2927 *params = texture->getMagFilter();
2928 break;
2929 case GL_TEXTURE_MIN_FILTER:
2930 *params = texture->getMinFilter();
2931 break;
2932 case GL_TEXTURE_WRAP_S:
2933 *params = texture->getWrapS();
2934 break;
2935 case GL_TEXTURE_WRAP_T:
2936 *params = texture->getWrapT();
2937 break;
2938 default:
2939 return error(GL_INVALID_ENUM);
2940 }
2941 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002942 }
2943 catch(std::bad_alloc&)
2944 {
2945 return error(GL_OUT_OF_MEMORY);
2946 }
2947}
2948
2949void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2950{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002951 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002952
2953 try
2954 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002955 gl::Context *context = gl::getContext();
2956
2957 if (context)
2958 {
2959 if (program == 0)
2960 {
2961 return error(GL_INVALID_VALUE);
2962 }
2963
2964 gl::Program *programObject = context->getProgram(program);
2965
2966 if (!programObject || !programObject->isLinked())
2967 {
2968 return error(GL_INVALID_OPERATION);
2969 }
2970
2971 if (!programObject->getUniformfv(location, params))
2972 {
2973 return error(GL_INVALID_OPERATION);
2974 }
2975 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002976 }
2977 catch(std::bad_alloc&)
2978 {
2979 return error(GL_OUT_OF_MEMORY);
2980 }
2981}
2982
2983void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2984{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002985 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002986
2987 try
2988 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002989 gl::Context *context = gl::getContext();
2990
2991 if (context)
2992 {
2993 if (program == 0)
2994 {
2995 return error(GL_INVALID_VALUE);
2996 }
2997
2998 gl::Program *programObject = context->getProgram(program);
2999
3000 if (!programObject || !programObject->isLinked())
3001 {
3002 return error(GL_INVALID_OPERATION);
3003 }
3004
3005 if (!programObject)
3006 {
3007 return error(GL_INVALID_OPERATION);
3008 }
3009
3010 if (!programObject->getUniformiv(location, params))
3011 {
3012 return error(GL_INVALID_OPERATION);
3013 }
3014 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003015 }
3016 catch(std::bad_alloc&)
3017 {
3018 return error(GL_OUT_OF_MEMORY);
3019 }
3020}
3021
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003022int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003023{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003024 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003025
3026 try
3027 {
3028 gl::Context *context = gl::getContext();
3029
3030 if (strstr(name, "gl_") == name)
3031 {
3032 return -1;
3033 }
3034
3035 if (context)
3036 {
3037 gl::Program *programObject = context->getProgram(program);
3038
3039 if (!programObject)
3040 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003041 if (context->getShader(program))
3042 {
3043 return error(GL_INVALID_OPERATION, -1);
3044 }
3045 else
3046 {
3047 return error(GL_INVALID_VALUE, -1);
3048 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003049 }
3050
3051 if (!programObject->isLinked())
3052 {
3053 return error(GL_INVALID_OPERATION, -1);
3054 }
3055
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003056 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003057 }
3058 }
3059 catch(std::bad_alloc&)
3060 {
3061 return error(GL_OUT_OF_MEMORY, -1);
3062 }
3063
3064 return -1;
3065}
3066
3067void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3068{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003069 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003070
3071 try
3072 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003073 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003074
daniel@transgaming.come0078962010-04-15 20:45:08 +00003075 if (context)
3076 {
3077 if (index >= gl::MAX_VERTEX_ATTRIBS)
3078 {
3079 return error(GL_INVALID_VALUE);
3080 }
3081
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003082 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003083
daniel@transgaming.come0078962010-04-15 20:45:08 +00003084 switch (pname)
3085 {
3086 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003087 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003088 break;
3089 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003090 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003091 break;
3092 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003093 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003094 break;
3095 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003096 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003097 break;
3098 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003099 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003100 break;
3101 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003102 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003103 break;
3104 case GL_CURRENT_VERTEX_ATTRIB:
3105 for (int i = 0; i < 4; ++i)
3106 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003107 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003108 }
3109 break;
3110 default: return error(GL_INVALID_ENUM);
3111 }
3112 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003113 }
3114 catch(std::bad_alloc&)
3115 {
3116 return error(GL_OUT_OF_MEMORY);
3117 }
3118}
3119
3120void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3121{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003122 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003123
3124 try
3125 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003126 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003127
daniel@transgaming.come0078962010-04-15 20:45:08 +00003128 if (context)
3129 {
3130 if (index >= gl::MAX_VERTEX_ATTRIBS)
3131 {
3132 return error(GL_INVALID_VALUE);
3133 }
3134
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003135 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003136
daniel@transgaming.come0078962010-04-15 20:45:08 +00003137 switch (pname)
3138 {
3139 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003140 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003141 break;
3142 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003143 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003144 break;
3145 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003146 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003147 break;
3148 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003149 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003150 break;
3151 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003152 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003153 break;
3154 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003155 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003156 break;
3157 case GL_CURRENT_VERTEX_ATTRIB:
3158 for (int i = 0; i < 4; ++i)
3159 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003160 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003161 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3162 }
3163 break;
3164 default: return error(GL_INVALID_ENUM);
3165 }
3166 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003167 }
3168 catch(std::bad_alloc&)
3169 {
3170 return error(GL_OUT_OF_MEMORY);
3171 }
3172}
3173
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003174void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003175{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003176 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003177
3178 try
3179 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003180 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003181
daniel@transgaming.come0078962010-04-15 20:45:08 +00003182 if (context)
3183 {
3184 if (index >= gl::MAX_VERTEX_ATTRIBS)
3185 {
3186 return error(GL_INVALID_VALUE);
3187 }
3188
3189 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3190 {
3191 return error(GL_INVALID_ENUM);
3192 }
3193
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003194 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003195 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003196 }
3197 catch(std::bad_alloc&)
3198 {
3199 return error(GL_OUT_OF_MEMORY);
3200 }
3201}
3202
3203void __stdcall glHint(GLenum target, GLenum mode)
3204{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003205 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003206
3207 try
3208 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003209 switch (target)
3210 {
3211 case GL_GENERATE_MIPMAP_HINT:
3212 switch (mode)
3213 {
3214 case GL_FASTEST:
3215 case GL_NICEST:
3216 case GL_DONT_CARE:
3217 break;
3218 default:
3219 return error(GL_INVALID_ENUM);
3220 }
3221 break;
3222 default:
3223 return error(GL_INVALID_ENUM);
3224 }
3225
3226 gl::Context *context = gl::getContext();
3227 if (context)
3228 {
3229 if (target == GL_GENERATE_MIPMAP_HINT)
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003230 context->setGenerateMipmapHint(mode);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003231 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003232 }
3233 catch(std::bad_alloc&)
3234 {
3235 return error(GL_OUT_OF_MEMORY);
3236 }
3237}
3238
3239GLboolean __stdcall glIsBuffer(GLuint buffer)
3240{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003241 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003242
3243 try
3244 {
3245 gl::Context *context = gl::getContext();
3246
3247 if (context && buffer)
3248 {
3249 gl::Buffer *bufferObject = context->getBuffer(buffer);
3250
3251 if (bufferObject)
3252 {
3253 return GL_TRUE;
3254 }
3255 }
3256 }
3257 catch(std::bad_alloc&)
3258 {
3259 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3260 }
3261
3262 return GL_FALSE;
3263}
3264
3265GLboolean __stdcall glIsEnabled(GLenum cap)
3266{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003267 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003268
3269 try
3270 {
3271 gl::Context *context = gl::getContext();
3272
3273 if (context)
3274 {
3275 switch (cap)
3276 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003277 case GL_CULL_FACE: return context->isCullFaceEnabled();
3278 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3279 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3280 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3281 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3282 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3283 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3284 case GL_BLEND: return context->isBlendEnabled();
3285 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003286 default:
3287 return error(GL_INVALID_ENUM, false);
3288 }
3289 }
3290 }
3291 catch(std::bad_alloc&)
3292 {
3293 return error(GL_OUT_OF_MEMORY, false);
3294 }
3295
3296 return false;
3297}
3298
3299GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3300{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003301 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003302
3303 try
3304 {
3305 gl::Context *context = gl::getContext();
3306
3307 if (context && framebuffer)
3308 {
3309 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3310
3311 if (framebufferObject)
3312 {
3313 return GL_TRUE;
3314 }
3315 }
3316 }
3317 catch(std::bad_alloc&)
3318 {
3319 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3320 }
3321
3322 return GL_FALSE;
3323}
3324
3325GLboolean __stdcall glIsProgram(GLuint program)
3326{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003327 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003328
3329 try
3330 {
3331 gl::Context *context = gl::getContext();
3332
3333 if (context && program)
3334 {
3335 gl::Program *programObject = context->getProgram(program);
3336
3337 if (programObject)
3338 {
3339 return GL_TRUE;
3340 }
3341 }
3342 }
3343 catch(std::bad_alloc&)
3344 {
3345 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3346 }
3347
3348 return GL_FALSE;
3349}
3350
3351GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3352{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003353 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003354
3355 try
3356 {
3357 gl::Context *context = gl::getContext();
3358
3359 if (context && renderbuffer)
3360 {
3361 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3362
3363 if (renderbufferObject)
3364 {
3365 return GL_TRUE;
3366 }
3367 }
3368 }
3369 catch(std::bad_alloc&)
3370 {
3371 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3372 }
3373
3374 return GL_FALSE;
3375}
3376
3377GLboolean __stdcall glIsShader(GLuint shader)
3378{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003379 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003380
3381 try
3382 {
3383 gl::Context *context = gl::getContext();
3384
3385 if (context && shader)
3386 {
3387 gl::Shader *shaderObject = context->getShader(shader);
3388
3389 if (shaderObject)
3390 {
3391 return GL_TRUE;
3392 }
3393 }
3394 }
3395 catch(std::bad_alloc&)
3396 {
3397 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3398 }
3399
3400 return GL_FALSE;
3401}
3402
3403GLboolean __stdcall glIsTexture(GLuint texture)
3404{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003405 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003406
3407 try
3408 {
3409 gl::Context *context = gl::getContext();
3410
3411 if (context && texture)
3412 {
3413 gl::Texture *textureObject = context->getTexture(texture);
3414
3415 if (textureObject)
3416 {
3417 return GL_TRUE;
3418 }
3419 }
3420 }
3421 catch(std::bad_alloc&)
3422 {
3423 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3424 }
3425
3426 return GL_FALSE;
3427}
3428
3429void __stdcall glLineWidth(GLfloat width)
3430{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003431 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003432
3433 try
3434 {
3435 if (width <= 0.0f)
3436 {
3437 return error(GL_INVALID_VALUE);
3438 }
3439
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003440 gl::Context *context = gl::getContext();
3441
3442 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003443 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003444 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003445 }
3446 }
3447 catch(std::bad_alloc&)
3448 {
3449 return error(GL_OUT_OF_MEMORY);
3450 }
3451}
3452
3453void __stdcall glLinkProgram(GLuint program)
3454{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003455 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003456
3457 try
3458 {
3459 gl::Context *context = gl::getContext();
3460
3461 if (context)
3462 {
3463 gl::Program *programObject = context->getProgram(program);
3464
3465 if (!programObject)
3466 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003467 if (context->getShader(program))
3468 {
3469 return error(GL_INVALID_OPERATION);
3470 }
3471 else
3472 {
3473 return error(GL_INVALID_VALUE);
3474 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003475 }
3476
3477 programObject->link();
3478 }
3479 }
3480 catch(std::bad_alloc&)
3481 {
3482 return error(GL_OUT_OF_MEMORY);
3483 }
3484}
3485
3486void __stdcall glPixelStorei(GLenum pname, GLint param)
3487{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003488 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003489
3490 try
3491 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003492 gl::Context *context = gl::getContext();
3493
3494 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003495 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003496 switch (pname)
3497 {
3498 case GL_UNPACK_ALIGNMENT:
3499 if (param != 1 && param != 2 && param != 4 && param != 8)
3500 {
3501 return error(GL_INVALID_VALUE);
3502 }
3503
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003504 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003505 break;
3506
3507 case GL_PACK_ALIGNMENT:
3508 if (param != 1 && param != 2 && param != 4 && param != 8)
3509 {
3510 return error(GL_INVALID_VALUE);
3511 }
3512
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003513 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003514 break;
3515
3516 default:
3517 return error(GL_INVALID_ENUM);
3518 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003519 }
3520 }
3521 catch(std::bad_alloc&)
3522 {
3523 return error(GL_OUT_OF_MEMORY);
3524 }
3525}
3526
3527void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3528{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003529 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003530
3531 try
3532 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003533 gl::Context *context = gl::getContext();
3534
3535 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003536 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003537 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003538 }
3539 }
3540 catch(std::bad_alloc&)
3541 {
3542 return error(GL_OUT_OF_MEMORY);
3543 }
3544}
3545
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003546void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003547{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003548 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003549 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003550 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003551
3552 try
3553 {
3554 if (width < 0 || height < 0)
3555 {
3556 return error(GL_INVALID_VALUE);
3557 }
3558
3559 switch (format)
3560 {
3561 case GL_RGBA:
3562 switch (type)
3563 {
3564 case GL_UNSIGNED_BYTE:
3565 break;
3566 default:
3567 return error(GL_INVALID_OPERATION);
3568 }
3569 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003570 case GL_BGRA_EXT:
3571 switch (type)
3572 {
3573 case GL_UNSIGNED_BYTE:
3574 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3575 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3576 break;
3577 default:
3578 return error(GL_INVALID_OPERATION);
3579 }
3580 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003581 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3582 switch (type)
3583 {
3584 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3585 break;
3586 default:
3587 return error(GL_INVALID_OPERATION);
3588 }
3589 break;
3590 default:
3591 return error(GL_INVALID_OPERATION);
3592 }
3593
3594 gl::Context *context = gl::getContext();
3595
3596 if (context)
3597 {
3598 context->readPixels(x, y, width, height, format, type, pixels);
3599 }
3600 }
3601 catch(std::bad_alloc&)
3602 {
3603 return error(GL_OUT_OF_MEMORY);
3604 }
3605}
3606
3607void __stdcall glReleaseShaderCompiler(void)
3608{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003609 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003610
3611 try
3612 {
3613 gl::Shader::releaseCompiler();
3614 }
3615 catch(std::bad_alloc&)
3616 {
3617 return error(GL_OUT_OF_MEMORY);
3618 }
3619}
3620
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003621void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003622{
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003623 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3624 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003625
3626 try
3627 {
3628 switch (target)
3629 {
3630 case GL_RENDERBUFFER:
3631 break;
3632 default:
3633 return error(GL_INVALID_ENUM);
3634 }
3635
3636 switch (internalformat)
3637 {
3638 case GL_DEPTH_COMPONENT16:
3639 case GL_RGBA4:
3640 case GL_RGB5_A1:
3641 case GL_RGB565:
3642 case GL_STENCIL_INDEX8:
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003643 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003644 break;
3645 default:
3646 return error(GL_INVALID_ENUM);
3647 }
3648
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003649 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 +00003650 {
3651 return error(GL_INVALID_VALUE);
3652 }
3653
3654 gl::Context *context = gl::getContext();
3655
3656 if (context)
3657 {
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003658 if (samples > context->getMaxSupportedSamples())
3659 {
3660 return error(GL_INVALID_VALUE);
3661 }
3662
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003663 GLuint handle = context->getRenderbufferHandle();
3664 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003665 {
3666 return error(GL_INVALID_OPERATION);
3667 }
3668
3669 switch (internalformat)
3670 {
3671 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003672 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003673 break;
3674 case GL_RGBA4:
3675 case GL_RGB5_A1:
3676 case GL_RGB565:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003677 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003678 break;
3679 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003680 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003681 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003682 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003683 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003684 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003685 default:
3686 return error(GL_INVALID_ENUM);
3687 }
3688 }
3689 }
3690 catch(std::bad_alloc&)
3691 {
3692 return error(GL_OUT_OF_MEMORY);
3693 }
3694}
3695
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003696void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3697{
3698 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
3699}
3700
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003701void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3702{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003703 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003704
3705 try
3706 {
3707 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003708
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003709 if (context)
3710 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00003711 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003712 }
3713 }
3714 catch(std::bad_alloc&)
3715 {
3716 return error(GL_OUT_OF_MEMORY);
3717 }
3718}
3719
3720void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3721{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003722 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 +00003723
3724 try
3725 {
3726 if (width < 0 || height < 0)
3727 {
3728 return error(GL_INVALID_VALUE);
3729 }
3730
3731 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003732
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003733 if (context)
3734 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003735 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003736 }
3737 }
3738 catch(std::bad_alloc&)
3739 {
3740 return error(GL_OUT_OF_MEMORY);
3741 }
3742}
3743
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003744void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003745{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003746 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003747 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003748 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003749
3750 try
3751 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00003752 // No binary shader formats are supported.
3753 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003754 }
3755 catch(std::bad_alloc&)
3756 {
3757 return error(GL_OUT_OF_MEMORY);
3758 }
3759}
3760
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003761void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003762{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003763 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 +00003764 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003765
3766 try
3767 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003768 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003769 {
3770 return error(GL_INVALID_VALUE);
3771 }
3772
3773 gl::Context *context = gl::getContext();
3774
3775 if (context)
3776 {
3777 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003778
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003779 if (!shaderObject)
3780 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003781 if (context->getProgram(shader))
3782 {
3783 return error(GL_INVALID_OPERATION);
3784 }
3785 else
3786 {
3787 return error(GL_INVALID_VALUE);
3788 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003789 }
3790
3791 shaderObject->setSource(count, string, length);
3792 }
3793 }
3794 catch(std::bad_alloc&)
3795 {
3796 return error(GL_OUT_OF_MEMORY);
3797 }
3798}
3799
3800void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3801{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003802 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003803}
3804
3805void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3806{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003807 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 +00003808
3809 try
3810 {
3811 switch (face)
3812 {
3813 case GL_FRONT:
3814 case GL_BACK:
3815 case GL_FRONT_AND_BACK:
3816 break;
3817 default:
3818 return error(GL_INVALID_ENUM);
3819 }
3820
3821 switch (func)
3822 {
3823 case GL_NEVER:
3824 case GL_ALWAYS:
3825 case GL_LESS:
3826 case GL_LEQUAL:
3827 case GL_EQUAL:
3828 case GL_GEQUAL:
3829 case GL_GREATER:
3830 case GL_NOTEQUAL:
3831 break;
3832 default:
3833 return error(GL_INVALID_ENUM);
3834 }
3835
3836 gl::Context *context = gl::getContext();
3837
3838 if (context)
3839 {
3840 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3841 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003842 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003843 }
3844
3845 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3846 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003847 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003848 }
3849 }
3850 }
3851 catch(std::bad_alloc&)
3852 {
3853 return error(GL_OUT_OF_MEMORY);
3854 }
3855}
3856
3857void __stdcall glStencilMask(GLuint mask)
3858{
3859 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3860}
3861
3862void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3863{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003864 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003865
3866 try
3867 {
3868 switch (face)
3869 {
3870 case GL_FRONT:
3871 case GL_BACK:
3872 case GL_FRONT_AND_BACK:
3873 break;
3874 default:
3875 return error(GL_INVALID_ENUM);
3876 }
3877
3878 gl::Context *context = gl::getContext();
3879
3880 if (context)
3881 {
3882 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3883 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003884 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003885 }
3886
3887 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3888 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003889 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003890 }
3891 }
3892 }
3893 catch(std::bad_alloc&)
3894 {
3895 return error(GL_OUT_OF_MEMORY);
3896 }
3897}
3898
3899void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3900{
3901 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3902}
3903
3904void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3905{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003906 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3907 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003908
3909 try
3910 {
3911 switch (face)
3912 {
3913 case GL_FRONT:
3914 case GL_BACK:
3915 case GL_FRONT_AND_BACK:
3916 break;
3917 default:
3918 return error(GL_INVALID_ENUM);
3919 }
3920
3921 switch (fail)
3922 {
3923 case GL_ZERO:
3924 case GL_KEEP:
3925 case GL_REPLACE:
3926 case GL_INCR:
3927 case GL_DECR:
3928 case GL_INVERT:
3929 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003930 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003931 break;
3932 default:
3933 return error(GL_INVALID_ENUM);
3934 }
3935
3936 switch (zfail)
3937 {
3938 case GL_ZERO:
3939 case GL_KEEP:
3940 case GL_REPLACE:
3941 case GL_INCR:
3942 case GL_DECR:
3943 case GL_INVERT:
3944 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003945 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003946 break;
3947 default:
3948 return error(GL_INVALID_ENUM);
3949 }
3950
3951 switch (zpass)
3952 {
3953 case GL_ZERO:
3954 case GL_KEEP:
3955 case GL_REPLACE:
3956 case GL_INCR:
3957 case GL_DECR:
3958 case GL_INVERT:
3959 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003960 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003961 break;
3962 default:
3963 return error(GL_INVALID_ENUM);
3964 }
3965
3966 gl::Context *context = gl::getContext();
3967
3968 if (context)
3969 {
3970 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3971 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003972 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003973 }
3974
3975 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3976 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003977 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003978 }
3979 }
3980 }
3981 catch(std::bad_alloc&)
3982 {
3983 return error(GL_OUT_OF_MEMORY);
3984 }
3985}
3986
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003987void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3988 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003989{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003990 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 +00003991 "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 +00003992 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003993
3994 try
3995 {
3996 if (level < 0 || width < 0 || height < 0)
3997 {
3998 return error(GL_INVALID_VALUE);
3999 }
4000
4001 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
4002 {
4003 return error(GL_INVALID_VALUE);
4004 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004005
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004006 switch (target)
4007 {
4008 case GL_TEXTURE_2D:
4009 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
4010 {
4011 return error(GL_INVALID_VALUE);
4012 }
4013 break;
4014 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4015 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4016 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4017 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4018 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4019 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00004020 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004021 {
4022 return error(GL_INVALID_VALUE);
4023 }
4024
4025 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
4026 {
4027 return error(GL_INVALID_VALUE);
4028 }
4029 break;
4030 default:
4031 return error(GL_INVALID_ENUM);
4032 }
4033
4034 if (internalformat != format)
4035 {
4036 return error(GL_INVALID_OPERATION);
4037 }
4038
4039 switch (internalformat)
4040 {
4041 case GL_ALPHA:
4042 case GL_LUMINANCE:
4043 case GL_LUMINANCE_ALPHA:
4044 switch (type)
4045 {
4046 case GL_UNSIGNED_BYTE:
4047 break;
4048 default:
4049 return error(GL_INVALID_ENUM);
4050 }
4051 break;
4052 case GL_RGB:
4053 switch (type)
4054 {
4055 case GL_UNSIGNED_BYTE:
4056 case GL_UNSIGNED_SHORT_5_6_5:
4057 break;
4058 default:
4059 return error(GL_INVALID_ENUM);
4060 }
4061 break;
4062 case GL_RGBA:
4063 switch (type)
4064 {
4065 case GL_UNSIGNED_BYTE:
4066 case GL_UNSIGNED_SHORT_4_4_4_4:
4067 case GL_UNSIGNED_SHORT_5_5_5_1:
4068 break;
4069 default:
4070 return error(GL_INVALID_ENUM);
4071 }
4072 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004073 case GL_BGRA_EXT:
4074 switch (type)
4075 {
4076 case GL_UNSIGNED_BYTE:
4077 break;
4078 default:
4079 return error(GL_INVALID_ENUM);
4080 }
4081 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004082 default:
4083 return error(GL_INVALID_VALUE);
4084 }
4085
4086 if (border != 0)
4087 {
4088 return error(GL_INVALID_VALUE);
4089 }
4090
4091 gl::Context *context = gl::getContext();
4092
4093 if (context)
4094 {
4095 if (target == GL_TEXTURE_2D)
4096 {
4097 gl::Texture2D *texture = context->getTexture2D();
4098
4099 if (!texture)
4100 {
4101 return error(GL_INVALID_OPERATION);
4102 }
4103
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004104 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004105 }
4106 else
4107 {
4108 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4109
4110 if (!texture)
4111 {
4112 return error(GL_INVALID_OPERATION);
4113 }
4114
4115 switch (target)
4116 {
4117 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004118 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004119 break;
4120 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004121 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004122 break;
4123 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004124 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004125 break;
4126 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004127 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004128 break;
4129 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004130 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004131 break;
4132 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004133 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004134 break;
4135 default: UNREACHABLE();
4136 }
4137 }
4138 }
4139 }
4140 catch(std::bad_alloc&)
4141 {
4142 return error(GL_OUT_OF_MEMORY);
4143 }
4144}
4145
4146void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4147{
4148 glTexParameteri(target, pname, (GLint)param);
4149}
4150
4151void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4152{
4153 glTexParameteri(target, pname, (GLint)*params);
4154}
4155
4156void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4157{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004158 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004159
4160 try
4161 {
4162 gl::Context *context = gl::getContext();
4163
4164 if (context)
4165 {
4166 gl::Texture *texture;
4167
4168 switch (target)
4169 {
4170 case GL_TEXTURE_2D:
4171 texture = context->getTexture2D();
4172 break;
4173 case GL_TEXTURE_CUBE_MAP:
4174 texture = context->getTextureCubeMap();
4175 break;
4176 default:
4177 return error(GL_INVALID_ENUM);
4178 }
4179
4180 switch (pname)
4181 {
4182 case GL_TEXTURE_WRAP_S:
4183 if (!texture->setWrapS((GLenum)param))
4184 {
4185 return error(GL_INVALID_ENUM);
4186 }
4187 break;
4188 case GL_TEXTURE_WRAP_T:
4189 if (!texture->setWrapT((GLenum)param))
4190 {
4191 return error(GL_INVALID_ENUM);
4192 }
4193 break;
4194 case GL_TEXTURE_MIN_FILTER:
4195 if (!texture->setMinFilter((GLenum)param))
4196 {
4197 return error(GL_INVALID_ENUM);
4198 }
4199 break;
4200 case GL_TEXTURE_MAG_FILTER:
4201 if (!texture->setMagFilter((GLenum)param))
4202 {
4203 return error(GL_INVALID_ENUM);
4204 }
4205 break;
4206 default:
4207 return error(GL_INVALID_ENUM);
4208 }
4209 }
4210 }
4211 catch(std::bad_alloc&)
4212 {
4213 return error(GL_OUT_OF_MEMORY);
4214 }
4215}
4216
4217void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4218{
4219 glTexParameteri(target, pname, *params);
4220}
4221
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004222void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4223 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004224{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004225 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4226 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004227 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004228 target, level, xoffset, yoffset, width, height, format, type, pixels);
4229
4230 try
4231 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004232 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004233 {
4234 return error(GL_INVALID_ENUM);
4235 }
4236
4237 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004238 {
4239 return error(GL_INVALID_VALUE);
4240 }
4241
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004242 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4243 {
4244 return error(GL_INVALID_VALUE);
4245 }
4246
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004247 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004248 {
4249 return error(GL_INVALID_ENUM);
4250 }
4251
4252 if (width == 0 || height == 0 || pixels == NULL)
4253 {
4254 return;
4255 }
4256
4257 gl::Context *context = gl::getContext();
4258
4259 if (context)
4260 {
4261 if (target == GL_TEXTURE_2D)
4262 {
4263 gl::Texture2D *texture = context->getTexture2D();
4264
4265 if (!texture)
4266 {
4267 return error(GL_INVALID_OPERATION);
4268 }
4269
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004270 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004271 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004272 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004273 {
4274 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4275
4276 if (!texture)
4277 {
4278 return error(GL_INVALID_OPERATION);
4279 }
4280
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004281 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004282 }
4283 else
4284 {
4285 UNREACHABLE();
4286 }
4287 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004288 }
4289 catch(std::bad_alloc&)
4290 {
4291 return error(GL_OUT_OF_MEMORY);
4292 }
4293}
4294
4295void __stdcall glUniform1f(GLint location, GLfloat x)
4296{
4297 glUniform1fv(location, 1, &x);
4298}
4299
4300void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4301{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004302 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004303
4304 try
4305 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004306 if (count < 0)
4307 {
4308 return error(GL_INVALID_VALUE);
4309 }
4310
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004311 if (location == -1)
4312 {
4313 return;
4314 }
4315
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004316 gl::Context *context = gl::getContext();
4317
4318 if (context)
4319 {
4320 gl::Program *program = context->getCurrentProgram();
4321
4322 if (!program)
4323 {
4324 return error(GL_INVALID_OPERATION);
4325 }
4326
4327 if (!program->setUniform1fv(location, count, v))
4328 {
4329 return error(GL_INVALID_OPERATION);
4330 }
4331 }
4332 }
4333 catch(std::bad_alloc&)
4334 {
4335 return error(GL_OUT_OF_MEMORY);
4336 }
4337}
4338
4339void __stdcall glUniform1i(GLint location, GLint x)
4340{
4341 glUniform1iv(location, 1, &x);
4342}
4343
4344void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4345{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004346 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004347
4348 try
4349 {
4350 if (count < 0)
4351 {
4352 return error(GL_INVALID_VALUE);
4353 }
4354
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004355 if (location == -1)
4356 {
4357 return;
4358 }
4359
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004360 gl::Context *context = gl::getContext();
4361
4362 if (context)
4363 {
4364 gl::Program *program = context->getCurrentProgram();
4365
4366 if (!program)
4367 {
4368 return error(GL_INVALID_OPERATION);
4369 }
4370
4371 if (!program->setUniform1iv(location, count, v))
4372 {
4373 return error(GL_INVALID_OPERATION);
4374 }
4375 }
4376 }
4377 catch(std::bad_alloc&)
4378 {
4379 return error(GL_OUT_OF_MEMORY);
4380 }
4381}
4382
4383void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4384{
4385 GLfloat xy[2] = {x, y};
4386
4387 glUniform2fv(location, 1, (GLfloat*)&xy);
4388}
4389
4390void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4391{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004392 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004393
4394 try
4395 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004396 if (count < 0)
4397 {
4398 return error(GL_INVALID_VALUE);
4399 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004400
4401 if (location == -1)
4402 {
4403 return;
4404 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004405
4406 gl::Context *context = gl::getContext();
4407
4408 if (context)
4409 {
4410 gl::Program *program = context->getCurrentProgram();
4411
4412 if (!program)
4413 {
4414 return error(GL_INVALID_OPERATION);
4415 }
4416
4417 if (!program->setUniform2fv(location, count, v))
4418 {
4419 return error(GL_INVALID_OPERATION);
4420 }
4421 }
4422 }
4423 catch(std::bad_alloc&)
4424 {
4425 return error(GL_OUT_OF_MEMORY);
4426 }
4427}
4428
4429void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4430{
4431 GLint xy[4] = {x, y};
4432
4433 glUniform2iv(location, 1, (GLint*)&xy);
4434}
4435
4436void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4437{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004438 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004439
4440 try
4441 {
4442 if (count < 0)
4443 {
4444 return error(GL_INVALID_VALUE);
4445 }
4446
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004447 if (location == -1)
4448 {
4449 return;
4450 }
4451
4452 gl::Context *context = gl::getContext();
4453
4454 if (context)
4455 {
4456 gl::Program *program = context->getCurrentProgram();
4457
4458 if (!program)
4459 {
4460 return error(GL_INVALID_OPERATION);
4461 }
4462
4463 if (!program->setUniform2iv(location, count, v))
4464 {
4465 return error(GL_INVALID_OPERATION);
4466 }
4467 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004468 }
4469 catch(std::bad_alloc&)
4470 {
4471 return error(GL_OUT_OF_MEMORY);
4472 }
4473}
4474
4475void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4476{
4477 GLfloat xyz[3] = {x, y, z};
4478
4479 glUniform3fv(location, 1, (GLfloat*)&xyz);
4480}
4481
4482void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4483{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004484 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004485
4486 try
4487 {
4488 if (count < 0)
4489 {
4490 return error(GL_INVALID_VALUE);
4491 }
4492
4493 if (location == -1)
4494 {
4495 return;
4496 }
4497
4498 gl::Context *context = gl::getContext();
4499
4500 if (context)
4501 {
4502 gl::Program *program = context->getCurrentProgram();
4503
4504 if (!program)
4505 {
4506 return error(GL_INVALID_OPERATION);
4507 }
4508
4509 if (!program->setUniform3fv(location, count, v))
4510 {
4511 return error(GL_INVALID_OPERATION);
4512 }
4513 }
4514 }
4515 catch(std::bad_alloc&)
4516 {
4517 return error(GL_OUT_OF_MEMORY);
4518 }
4519}
4520
4521void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4522{
4523 GLint xyz[3] = {x, y, z};
4524
4525 glUniform3iv(location, 1, (GLint*)&xyz);
4526}
4527
4528void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4529{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004530 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004531
4532 try
4533 {
4534 if (count < 0)
4535 {
4536 return error(GL_INVALID_VALUE);
4537 }
4538
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004539 if (location == -1)
4540 {
4541 return;
4542 }
4543
4544 gl::Context *context = gl::getContext();
4545
4546 if (context)
4547 {
4548 gl::Program *program = context->getCurrentProgram();
4549
4550 if (!program)
4551 {
4552 return error(GL_INVALID_OPERATION);
4553 }
4554
4555 if (!program->setUniform3iv(location, count, v))
4556 {
4557 return error(GL_INVALID_OPERATION);
4558 }
4559 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004560 }
4561 catch(std::bad_alloc&)
4562 {
4563 return error(GL_OUT_OF_MEMORY);
4564 }
4565}
4566
4567void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4568{
4569 GLfloat xyzw[4] = {x, y, z, w};
4570
4571 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4572}
4573
4574void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4575{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004576 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004577
4578 try
4579 {
4580 if (count < 0)
4581 {
4582 return error(GL_INVALID_VALUE);
4583 }
4584
4585 if (location == -1)
4586 {
4587 return;
4588 }
4589
4590 gl::Context *context = gl::getContext();
4591
4592 if (context)
4593 {
4594 gl::Program *program = context->getCurrentProgram();
4595
4596 if (!program)
4597 {
4598 return error(GL_INVALID_OPERATION);
4599 }
4600
4601 if (!program->setUniform4fv(location, count, v))
4602 {
4603 return error(GL_INVALID_OPERATION);
4604 }
4605 }
4606 }
4607 catch(std::bad_alloc&)
4608 {
4609 return error(GL_OUT_OF_MEMORY);
4610 }
4611}
4612
4613void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4614{
4615 GLint xyzw[4] = {x, y, z, w};
4616
4617 glUniform4iv(location, 1, (GLint*)&xyzw);
4618}
4619
4620void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4621{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004622 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004623
4624 try
4625 {
4626 if (count < 0)
4627 {
4628 return error(GL_INVALID_VALUE);
4629 }
4630
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004631 if (location == -1)
4632 {
4633 return;
4634 }
4635
4636 gl::Context *context = gl::getContext();
4637
4638 if (context)
4639 {
4640 gl::Program *program = context->getCurrentProgram();
4641
4642 if (!program)
4643 {
4644 return error(GL_INVALID_OPERATION);
4645 }
4646
4647 if (!program->setUniform4iv(location, count, v))
4648 {
4649 return error(GL_INVALID_OPERATION);
4650 }
4651 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004652 }
4653 catch(std::bad_alloc&)
4654 {
4655 return error(GL_OUT_OF_MEMORY);
4656 }
4657}
4658
4659void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4660{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004661 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4662 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004663
4664 try
4665 {
4666 if (count < 0 || transpose != GL_FALSE)
4667 {
4668 return error(GL_INVALID_VALUE);
4669 }
4670
4671 if (location == -1)
4672 {
4673 return;
4674 }
4675
4676 gl::Context *context = gl::getContext();
4677
4678 if (context)
4679 {
4680 gl::Program *program = context->getCurrentProgram();
4681
4682 if (!program)
4683 {
4684 return error(GL_INVALID_OPERATION);
4685 }
4686
4687 if (!program->setUniformMatrix2fv(location, count, value))
4688 {
4689 return error(GL_INVALID_OPERATION);
4690 }
4691 }
4692 }
4693 catch(std::bad_alloc&)
4694 {
4695 return error(GL_OUT_OF_MEMORY);
4696 }
4697}
4698
4699void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4700{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004701 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4702 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004703
4704 try
4705 {
4706 if (count < 0 || transpose != GL_FALSE)
4707 {
4708 return error(GL_INVALID_VALUE);
4709 }
4710
4711 if (location == -1)
4712 {
4713 return;
4714 }
4715
4716 gl::Context *context = gl::getContext();
4717
4718 if (context)
4719 {
4720 gl::Program *program = context->getCurrentProgram();
4721
4722 if (!program)
4723 {
4724 return error(GL_INVALID_OPERATION);
4725 }
4726
4727 if (!program->setUniformMatrix3fv(location, count, value))
4728 {
4729 return error(GL_INVALID_OPERATION);
4730 }
4731 }
4732 }
4733 catch(std::bad_alloc&)
4734 {
4735 return error(GL_OUT_OF_MEMORY);
4736 }
4737}
4738
4739void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4740{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004741 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4742 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004743
4744 try
4745 {
4746 if (count < 0 || transpose != GL_FALSE)
4747 {
4748 return error(GL_INVALID_VALUE);
4749 }
4750
4751 if (location == -1)
4752 {
4753 return;
4754 }
4755
4756 gl::Context *context = gl::getContext();
4757
4758 if (context)
4759 {
4760 gl::Program *program = context->getCurrentProgram();
4761
4762 if (!program)
4763 {
4764 return error(GL_INVALID_OPERATION);
4765 }
4766
4767 if (!program->setUniformMatrix4fv(location, count, value))
4768 {
4769 return error(GL_INVALID_OPERATION);
4770 }
4771 }
4772 }
4773 catch(std::bad_alloc&)
4774 {
4775 return error(GL_OUT_OF_MEMORY);
4776 }
4777}
4778
4779void __stdcall glUseProgram(GLuint program)
4780{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004781 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004782
4783 try
4784 {
4785 gl::Context *context = gl::getContext();
4786
4787 if (context)
4788 {
4789 gl::Program *programObject = context->getProgram(program);
4790
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004791 if (!programObject && program != 0)
4792 {
4793 if (context->getShader(program))
4794 {
4795 return error(GL_INVALID_OPERATION);
4796 }
4797 else
4798 {
4799 return error(GL_INVALID_VALUE);
4800 }
4801 }
4802
4803 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004804 {
4805 return error(GL_INVALID_OPERATION);
4806 }
4807
4808 context->useProgram(program);
4809 }
4810 }
4811 catch(std::bad_alloc&)
4812 {
4813 return error(GL_OUT_OF_MEMORY);
4814 }
4815}
4816
4817void __stdcall glValidateProgram(GLuint program)
4818{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004819 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004820
4821 try
4822 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00004823 gl::Context *context = gl::getContext();
4824
4825 if (context)
4826 {
4827 gl::Program *programObject = context->getProgram(program);
4828
4829 if (!programObject)
4830 {
4831 if (context->getShader(program))
4832 {
4833 return error(GL_INVALID_OPERATION);
4834 }
4835 else
4836 {
4837 return error(GL_INVALID_VALUE);
4838 }
4839 }
4840
4841 programObject->validate();
4842 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004843 }
4844 catch(std::bad_alloc&)
4845 {
4846 return error(GL_OUT_OF_MEMORY);
4847 }
4848}
4849
4850void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4851{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004852 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004853
4854 try
4855 {
4856 if (index >= gl::MAX_VERTEX_ATTRIBS)
4857 {
4858 return error(GL_INVALID_VALUE);
4859 }
4860
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004861 gl::Context *context = gl::getContext();
4862
4863 if (context)
4864 {
4865 GLfloat vals[4] = { x, 0, 0, 1 };
4866 context->setVertexAttrib(index, vals);
4867 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004868 }
4869 catch(std::bad_alloc&)
4870 {
4871 return error(GL_OUT_OF_MEMORY);
4872 }
4873}
4874
4875void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4876{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004877 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004878
4879 try
4880 {
4881 if (index >= gl::MAX_VERTEX_ATTRIBS)
4882 {
4883 return error(GL_INVALID_VALUE);
4884 }
4885
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004886 gl::Context *context = gl::getContext();
4887
4888 if (context)
4889 {
4890 GLfloat vals[4] = { values[0], 0, 0, 1 };
4891 context->setVertexAttrib(index, vals);
4892 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004893 }
4894 catch(std::bad_alloc&)
4895 {
4896 return error(GL_OUT_OF_MEMORY);
4897 }
4898}
4899
4900void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4901{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004902 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004903
4904 try
4905 {
4906 if (index >= gl::MAX_VERTEX_ATTRIBS)
4907 {
4908 return error(GL_INVALID_VALUE);
4909 }
4910
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004911 gl::Context *context = gl::getContext();
4912
4913 if (context)
4914 {
4915 GLfloat vals[4] = { x, y, 0, 1 };
4916 context->setVertexAttrib(index, vals);
4917 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004918 }
4919 catch(std::bad_alloc&)
4920 {
4921 return error(GL_OUT_OF_MEMORY);
4922 }
4923}
4924
4925void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4926{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004927 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004928
4929 try
4930 {
4931 if (index >= gl::MAX_VERTEX_ATTRIBS)
4932 {
4933 return error(GL_INVALID_VALUE);
4934 }
4935
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004936 gl::Context *context = gl::getContext();
4937
4938 if (context)
4939 {
4940 GLfloat vals[4] = { values[0], values[1], 0, 1 };
4941 context->setVertexAttrib(index, vals);
4942 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004943 }
4944 catch(std::bad_alloc&)
4945 {
4946 return error(GL_OUT_OF_MEMORY);
4947 }
4948}
4949
4950void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4951{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004952 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 +00004953
4954 try
4955 {
4956 if (index >= gl::MAX_VERTEX_ATTRIBS)
4957 {
4958 return error(GL_INVALID_VALUE);
4959 }
4960
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004961 gl::Context *context = gl::getContext();
4962
4963 if (context)
4964 {
4965 GLfloat vals[4] = { x, y, z, 1 };
4966 context->setVertexAttrib(index, vals);
4967 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004968 }
4969 catch(std::bad_alloc&)
4970 {
4971 return error(GL_OUT_OF_MEMORY);
4972 }
4973}
4974
4975void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4976{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004977 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004978
4979 try
4980 {
4981 if (index >= gl::MAX_VERTEX_ATTRIBS)
4982 {
4983 return error(GL_INVALID_VALUE);
4984 }
4985
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004986 gl::Context *context = gl::getContext();
4987
4988 if (context)
4989 {
4990 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
4991 context->setVertexAttrib(index, vals);
4992 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004993 }
4994 catch(std::bad_alloc&)
4995 {
4996 return error(GL_OUT_OF_MEMORY);
4997 }
4998}
4999
5000void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5001{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005002 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 +00005003
5004 try
5005 {
5006 if (index >= gl::MAX_VERTEX_ATTRIBS)
5007 {
5008 return error(GL_INVALID_VALUE);
5009 }
5010
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005011 gl::Context *context = gl::getContext();
5012
5013 if (context)
5014 {
5015 GLfloat vals[4] = { x, y, z, w };
5016 context->setVertexAttrib(index, vals);
5017 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005018 }
5019 catch(std::bad_alloc&)
5020 {
5021 return error(GL_OUT_OF_MEMORY);
5022 }
5023}
5024
5025void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5026{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005027 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005028
5029 try
5030 {
5031 if (index >= gl::MAX_VERTEX_ATTRIBS)
5032 {
5033 return error(GL_INVALID_VALUE);
5034 }
5035
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005036 gl::Context *context = gl::getContext();
5037
5038 if (context)
5039 {
5040 context->setVertexAttrib(index, values);
5041 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005042 }
5043 catch(std::bad_alloc&)
5044 {
5045 return error(GL_OUT_OF_MEMORY);
5046 }
5047}
5048
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005049void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005050{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005051 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005052 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005053 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005054
5055 try
5056 {
5057 if (index >= gl::MAX_VERTEX_ATTRIBS)
5058 {
5059 return error(GL_INVALID_VALUE);
5060 }
5061
5062 if (size < 1 || size > 4)
5063 {
5064 return error(GL_INVALID_VALUE);
5065 }
5066
5067 switch (type)
5068 {
5069 case GL_BYTE:
5070 case GL_UNSIGNED_BYTE:
5071 case GL_SHORT:
5072 case GL_UNSIGNED_SHORT:
5073 case GL_FIXED:
5074 case GL_FLOAT:
5075 break;
5076 default:
5077 return error(GL_INVALID_ENUM);
5078 }
5079
5080 if (stride < 0)
5081 {
5082 return error(GL_INVALID_VALUE);
5083 }
5084
5085 gl::Context *context = gl::getContext();
5086
5087 if (context)
5088 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005089 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005090 }
5091 }
5092 catch(std::bad_alloc&)
5093 {
5094 return error(GL_OUT_OF_MEMORY);
5095 }
5096}
5097
5098void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5099{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005100 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 +00005101
5102 try
5103 {
5104 if (width < 0 || height < 0)
5105 {
5106 return error(GL_INVALID_VALUE);
5107 }
5108
5109 gl::Context *context = gl::getContext();
5110
5111 if (context)
5112 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005113 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005114 }
5115 }
5116 catch(std::bad_alloc&)
5117 {
5118 return error(GL_OUT_OF_MEMORY);
5119 }
5120}
5121
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005122void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5123 GLbitfield mask, GLenum filter)
5124{
5125 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5126 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5127 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5128 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5129
5130 try
5131 {
5132 switch (filter)
5133 {
5134 case GL_NEAREST:
5135 break;
5136 default:
5137 return error(GL_INVALID_ENUM);
5138 }
5139
5140 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5141 {
5142 return error(GL_INVALID_VALUE);
5143 }
5144
5145 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5146 {
5147 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5148 return error(GL_INVALID_OPERATION);
5149 }
5150
5151 gl::Context *context = gl::getContext();
5152
5153 if (context)
5154 {
5155 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5156 {
5157 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5158 return error(GL_INVALID_OPERATION);
5159 }
5160
5161 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5162 }
5163 }
5164 catch(std::bad_alloc&)
5165 {
5166 return error(GL_OUT_OF_MEMORY);
5167 }
5168}
5169
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005170void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5171 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005172{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005173 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5174 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005175 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005176 target, level, internalformat, width, height, depth, border, format, type, pixels);
5177
5178 try
5179 {
5180 UNIMPLEMENTED(); // FIXME
5181 }
5182 catch(std::bad_alloc&)
5183 {
5184 return error(GL_OUT_OF_MEMORY);
5185 }
5186}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005187
5188__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5189{
5190 struct Extension
5191 {
5192 const char *name;
5193 __eglMustCastToProperFunctionPointerType address;
5194 };
5195
5196 static const Extension glExtensions[] =
5197 {
5198 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005199 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005200 };
5201
5202 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5203 {
5204 if (strcmp(procname, glExtensions[ext].name) == 0)
5205 {
5206 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5207 }
5208 }
5209
5210 return NULL;
5211}
5212
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005213}