blob: cb464962fb0c7647447e8b09a5044528b759e9db [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.com9ecb9f92010-07-28 19:21:12 +0000873 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000874 if (target == GL_TEXTURE_2D)
875 {
876 gl::Texture2D *texture = context->getTexture2D();
877
878 if (!texture)
879 {
880 return error(GL_INVALID_OPERATION);
881 }
882
883 texture->copyImage(level, internalformat, x, y, width, height, source);
884 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000885 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000886 {
887 gl::TextureCubeMap *texture = context->getTextureCubeMap();
888
889 if (!texture)
890 {
891 return error(GL_INVALID_OPERATION);
892 }
893
894 texture->copyImage(target, level, internalformat, x, y, width, height, source);
895 }
896 else
897 {
898 UNREACHABLE();
899 }
900 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000901 }
902 catch(std::bad_alloc&)
903 {
904 return error(GL_OUT_OF_MEMORY);
905 }
906}
907
908void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
909{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000910 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
911 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000912 target, level, xoffset, yoffset, x, y, width, height);
913
914 try
915 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000916 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000917 {
918 return error(GL_INVALID_ENUM);
919 }
920
921 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000922 {
923 return error(GL_INVALID_VALUE);
924 }
925
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000926 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
927 {
928 return error(GL_INVALID_VALUE);
929 }
930
931 if (width == 0 || height == 0)
932 {
933 return;
934 }
935
936 gl::Context *context = gl::getContext();
937
938 if (context)
939 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000940 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +0000941 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
942 {
943 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
944 }
945
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000946 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000947 if (target == GL_TEXTURE_2D)
948 {
949 gl::Texture2D *texture = context->getTexture2D();
950
951 if (!texture)
952 {
953 return error(GL_INVALID_OPERATION);
954 }
955
956 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
957 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000958 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000959 {
960 gl::TextureCubeMap *texture = context->getTextureCubeMap();
961
962 if (!texture)
963 {
964 return error(GL_INVALID_OPERATION);
965 }
966
967 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
968 }
969 else
970 {
971 UNREACHABLE();
972 }
973 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000974 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000975
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000976 catch(std::bad_alloc&)
977 {
978 return error(GL_OUT_OF_MEMORY);
979 }
980}
981
982GLuint __stdcall glCreateProgram(void)
983{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000984 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000985
986 try
987 {
988 gl::Context *context = gl::getContext();
989
990 if (context)
991 {
992 return context->createProgram();
993 }
994 }
995 catch(std::bad_alloc&)
996 {
997 return error(GL_OUT_OF_MEMORY, 0);
998 }
999
1000 return 0;
1001}
1002
1003GLuint __stdcall glCreateShader(GLenum type)
1004{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001005 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001006
1007 try
1008 {
1009 gl::Context *context = gl::getContext();
1010
1011 if (context)
1012 {
1013 switch (type)
1014 {
1015 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001016 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001017 return context->createShader(type);
1018 default:
1019 return error(GL_INVALID_ENUM, 0);
1020 }
1021 }
1022 }
1023 catch(std::bad_alloc&)
1024 {
1025 return error(GL_OUT_OF_MEMORY, 0);
1026 }
1027
1028 return 0;
1029}
1030
1031void __stdcall glCullFace(GLenum mode)
1032{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001033 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001034
1035 try
1036 {
1037 switch (mode)
1038 {
1039 case GL_FRONT:
1040 case GL_BACK:
1041 case GL_FRONT_AND_BACK:
1042 {
1043 gl::Context *context = gl::getContext();
1044
1045 if (context)
1046 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001047 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001048 }
1049 }
1050 break;
1051 default:
1052 return error(GL_INVALID_ENUM);
1053 }
1054 }
1055 catch(std::bad_alloc&)
1056 {
1057 return error(GL_OUT_OF_MEMORY);
1058 }
1059}
1060
1061void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1062{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001063 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001064
1065 try
1066 {
1067 if (n < 0)
1068 {
1069 return error(GL_INVALID_VALUE);
1070 }
1071
1072 gl::Context *context = gl::getContext();
1073
1074 if (context)
1075 {
1076 for (int i = 0; i < n; i++)
1077 {
1078 context->deleteBuffer(buffers[i]);
1079 }
1080 }
1081 }
1082 catch(std::bad_alloc&)
1083 {
1084 return error(GL_OUT_OF_MEMORY);
1085 }
1086}
1087
1088void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1089{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001090 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001091
1092 try
1093 {
1094 if (n < 0)
1095 {
1096 return error(GL_INVALID_VALUE);
1097 }
1098
1099 gl::Context *context = gl::getContext();
1100
1101 if (context)
1102 {
1103 for (int i = 0; i < n; i++)
1104 {
1105 if (framebuffers[i] != 0)
1106 {
1107 context->deleteFramebuffer(framebuffers[i]);
1108 }
1109 }
1110 }
1111 }
1112 catch(std::bad_alloc&)
1113 {
1114 return error(GL_OUT_OF_MEMORY);
1115 }
1116}
1117
1118void __stdcall glDeleteProgram(GLuint program)
1119{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001120 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001121
1122 try
1123 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001124 if (program == 0)
1125 {
1126 return;
1127 }
1128
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001129 gl::Context *context = gl::getContext();
1130
1131 if (context)
1132 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001133 if (!context->getProgram(program))
1134 {
1135 if(context->getShader(program))
1136 {
1137 return error(GL_INVALID_OPERATION);
1138 }
1139 else
1140 {
1141 return error(GL_INVALID_VALUE);
1142 }
1143 }
1144
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001145 context->deleteProgram(program);
1146 }
1147 }
1148 catch(std::bad_alloc&)
1149 {
1150 return error(GL_OUT_OF_MEMORY);
1151 }
1152}
1153
1154void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1155{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001156 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001157
1158 try
1159 {
1160 if (n < 0)
1161 {
1162 return error(GL_INVALID_VALUE);
1163 }
1164
1165 gl::Context *context = gl::getContext();
1166
1167 if (context)
1168 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001169 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001170 {
1171 context->deleteRenderbuffer(renderbuffers[i]);
1172 }
1173 }
1174 }
1175 catch(std::bad_alloc&)
1176 {
1177 return error(GL_OUT_OF_MEMORY);
1178 }
1179}
1180
1181void __stdcall glDeleteShader(GLuint shader)
1182{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001183 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001184
1185 try
1186 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001187 if (shader == 0)
1188 {
1189 return;
1190 }
1191
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001192 gl::Context *context = gl::getContext();
1193
1194 if (context)
1195 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001196 if (!context->getShader(shader))
1197 {
1198 if(context->getProgram(shader))
1199 {
1200 return error(GL_INVALID_OPERATION);
1201 }
1202 else
1203 {
1204 return error(GL_INVALID_VALUE);
1205 }
1206 }
1207
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001208 context->deleteShader(shader);
1209 }
1210 }
1211 catch(std::bad_alloc&)
1212 {
1213 return error(GL_OUT_OF_MEMORY);
1214 }
1215}
1216
1217void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1218{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001219 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001220
1221 try
1222 {
1223 if (n < 0)
1224 {
1225 return error(GL_INVALID_VALUE);
1226 }
1227
1228 gl::Context *context = gl::getContext();
1229
1230 if (context)
1231 {
1232 for (int i = 0; i < n; i++)
1233 {
1234 if (textures[i] != 0)
1235 {
1236 context->deleteTexture(textures[i]);
1237 }
1238 }
1239 }
1240 }
1241 catch(std::bad_alloc&)
1242 {
1243 return error(GL_OUT_OF_MEMORY);
1244 }
1245}
1246
1247void __stdcall glDepthFunc(GLenum func)
1248{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001249 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001250
1251 try
1252 {
1253 switch (func)
1254 {
1255 case GL_NEVER:
1256 case GL_ALWAYS:
1257 case GL_LESS:
1258 case GL_LEQUAL:
1259 case GL_EQUAL:
1260 case GL_GREATER:
1261 case GL_GEQUAL:
1262 case GL_NOTEQUAL:
1263 break;
1264 default:
1265 return error(GL_INVALID_ENUM);
1266 }
1267
1268 gl::Context *context = gl::getContext();
1269
1270 if (context)
1271 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001272 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001273 }
1274 }
1275 catch(std::bad_alloc&)
1276 {
1277 return error(GL_OUT_OF_MEMORY);
1278 }
1279}
1280
1281void __stdcall glDepthMask(GLboolean flag)
1282{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001283 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001284
1285 try
1286 {
1287 gl::Context *context = gl::getContext();
1288
1289 if (context)
1290 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001291 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001292 }
1293 }
1294 catch(std::bad_alloc&)
1295 {
1296 return error(GL_OUT_OF_MEMORY);
1297 }
1298}
1299
1300void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1301{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001302 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001303
1304 try
1305 {
1306 gl::Context *context = gl::getContext();
1307
1308 if (context)
1309 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001310 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001311 }
1312 }
1313 catch(std::bad_alloc&)
1314 {
1315 return error(GL_OUT_OF_MEMORY);
1316 }
1317}
1318
1319void __stdcall glDetachShader(GLuint program, GLuint shader)
1320{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001321 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001322
1323 try
1324 {
1325 gl::Context *context = gl::getContext();
1326
1327 if (context)
1328 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001329
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001330 gl::Program *programObject = context->getProgram(program);
1331 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001332
1333 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001334 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001335 gl::Shader *shaderByProgramHandle;
1336 shaderByProgramHandle = context->getShader(program);
1337 if (!shaderByProgramHandle)
1338 {
1339 return error(GL_INVALID_VALUE);
1340 }
1341 else
1342 {
1343 return error(GL_INVALID_OPERATION);
1344 }
1345 }
1346
1347 if (!shaderObject)
1348 {
1349 gl::Program *programByShaderHandle = context->getProgram(shader);
1350 if (!programByShaderHandle)
1351 {
1352 return error(GL_INVALID_VALUE);
1353 }
1354 else
1355 {
1356 return error(GL_INVALID_OPERATION);
1357 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001358 }
1359
1360 if (!programObject->detachShader(shaderObject))
1361 {
1362 return error(GL_INVALID_OPERATION);
1363 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001364 }
1365 }
1366 catch(std::bad_alloc&)
1367 {
1368 return error(GL_OUT_OF_MEMORY);
1369 }
1370}
1371
1372void __stdcall glDisable(GLenum cap)
1373{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001374 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001375
1376 try
1377 {
1378 gl::Context *context = gl::getContext();
1379
1380 if (context)
1381 {
1382 switch (cap)
1383 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001384 case GL_CULL_FACE: context->setCullFace(false); break;
1385 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1386 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1387 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1388 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1389 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1390 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1391 case GL_BLEND: context->setBlend(false); break;
1392 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001393 default:
1394 return error(GL_INVALID_ENUM);
1395 }
1396 }
1397 }
1398 catch(std::bad_alloc&)
1399 {
1400 return error(GL_OUT_OF_MEMORY);
1401 }
1402}
1403
1404void __stdcall glDisableVertexAttribArray(GLuint index)
1405{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001406 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001407
1408 try
1409 {
1410 if (index >= gl::MAX_VERTEX_ATTRIBS)
1411 {
1412 return error(GL_INVALID_VALUE);
1413 }
1414
1415 gl::Context *context = gl::getContext();
1416
1417 if (context)
1418 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001419 context->setVertexAttribEnabled(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001420 }
1421 }
1422 catch(std::bad_alloc&)
1423 {
1424 return error(GL_OUT_OF_MEMORY);
1425 }
1426}
1427
1428void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1429{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001430 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001431
1432 try
1433 {
1434 if (count < 0 || first < 0)
1435 {
1436 return error(GL_INVALID_VALUE);
1437 }
1438
1439 gl::Context *context = gl::getContext();
1440
1441 if (context)
1442 {
1443 context->drawArrays(mode, first, count);
1444 }
1445 }
1446 catch(std::bad_alloc&)
1447 {
1448 return error(GL_OUT_OF_MEMORY);
1449 }
1450}
1451
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001452void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001453{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001454 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 +00001455 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001456
1457 try
1458 {
1459 if (count < 0)
1460 {
1461 return error(GL_INVALID_VALUE);
1462 }
1463
1464 switch (type)
1465 {
1466 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001467 case GL_UNSIGNED_SHORT:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00001468 case GL_UNSIGNED_INT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001469 break;
1470 default:
1471 return error(GL_INVALID_ENUM);
1472 }
1473
1474 gl::Context *context = gl::getContext();
1475
1476 if (context)
1477 {
1478 context->drawElements(mode, count, type, indices);
1479 }
1480 }
1481 catch(std::bad_alloc&)
1482 {
1483 return error(GL_OUT_OF_MEMORY);
1484 }
1485}
1486
1487void __stdcall glEnable(GLenum cap)
1488{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001489 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001490
1491 try
1492 {
1493 gl::Context *context = gl::getContext();
1494
1495 if (context)
1496 {
1497 switch (cap)
1498 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001499 case GL_CULL_FACE: context->setCullFace(true); break;
1500 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1501 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1502 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1503 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1504 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1505 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1506 case GL_BLEND: context->setBlend(true); break;
1507 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001508 default:
1509 return error(GL_INVALID_ENUM);
1510 }
1511 }
1512 }
1513 catch(std::bad_alloc&)
1514 {
1515 return error(GL_OUT_OF_MEMORY);
1516 }
1517}
1518
1519void __stdcall glEnableVertexAttribArray(GLuint index)
1520{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001521 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001522
1523 try
1524 {
1525 if (index >= gl::MAX_VERTEX_ATTRIBS)
1526 {
1527 return error(GL_INVALID_VALUE);
1528 }
1529
1530 gl::Context *context = gl::getContext();
1531
1532 if (context)
1533 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001534 context->setVertexAttribEnabled(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001535 }
1536 }
1537 catch(std::bad_alloc&)
1538 {
1539 return error(GL_OUT_OF_MEMORY);
1540 }
1541}
1542
1543void __stdcall glFinish(void)
1544{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001545 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001546
1547 try
1548 {
1549 gl::Context *context = gl::getContext();
1550
1551 if (context)
1552 {
1553 context->finish();
1554 }
1555 }
1556 catch(std::bad_alloc&)
1557 {
1558 return error(GL_OUT_OF_MEMORY);
1559 }
1560}
1561
1562void __stdcall glFlush(void)
1563{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001564 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001565
1566 try
1567 {
1568 gl::Context *context = gl::getContext();
1569
1570 if (context)
1571 {
1572 context->flush();
1573 }
1574 }
1575 catch(std::bad_alloc&)
1576 {
1577 return error(GL_OUT_OF_MEMORY);
1578 }
1579}
1580
1581void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1582{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001583 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1584 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001585
1586 try
1587 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001588 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1589 || renderbuffertarget != GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001590 {
1591 return error(GL_INVALID_ENUM);
1592 }
1593
1594 gl::Context *context = gl::getContext();
1595
1596 if (context)
1597 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001598 gl::Framebuffer *framebuffer = NULL;
1599 GLuint framebufferHandle = 0;
1600 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1601 {
1602 framebuffer = context->getReadFramebuffer();
1603 framebufferHandle = context->getReadFramebufferHandle();
1604 }
1605 else
1606 {
1607 framebuffer = context->getDrawFramebuffer();
1608 framebufferHandle = context->getDrawFramebufferHandle();
1609 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001610
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001611 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001612 {
1613 return error(GL_INVALID_OPERATION);
1614 }
1615
1616 switch (attachment)
1617 {
1618 case GL_COLOR_ATTACHMENT0:
1619 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1620 break;
1621 case GL_DEPTH_ATTACHMENT:
1622 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1623 break;
1624 case GL_STENCIL_ATTACHMENT:
1625 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1626 break;
1627 default:
1628 return error(GL_INVALID_ENUM);
1629 }
1630 }
1631 }
1632 catch(std::bad_alloc&)
1633 {
1634 return error(GL_OUT_OF_MEMORY);
1635 }
1636}
1637
1638void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1639{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001640 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1641 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001642
1643 try
1644 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001645 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001646 {
1647 return error(GL_INVALID_ENUM);
1648 }
1649
1650 switch (attachment)
1651 {
1652 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001653 case GL_DEPTH_ATTACHMENT:
1654 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001655 break;
1656 default:
1657 return error(GL_INVALID_ENUM);
1658 }
1659
1660 gl::Context *context = gl::getContext();
1661
1662 if (context)
1663 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001664 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001665 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001666 textarget = GL_NONE;
1667 }
1668 else
1669 {
1670 gl::Texture *tex = context->getTexture(texture);
1671
1672 if (tex == NULL)
1673 {
1674 return error(GL_INVALID_OPERATION);
1675 }
1676
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001677 switch (textarget)
1678 {
1679 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001680 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001681 {
1682 return error(GL_INVALID_OPERATION);
1683 }
1684 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001685
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001686 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001687 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001688 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001689 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001690 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001691 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001692 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1693 {
1694 return error(GL_INVALID_OPERATION);
1695 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001696 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001697
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001698 default:
1699 return error(GL_INVALID_ENUM);
1700 }
1701
1702 if (level != 0)
1703 {
1704 return error(GL_INVALID_VALUE);
1705 }
1706 }
1707
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001708 gl::Framebuffer *framebuffer = NULL;
1709 GLuint framebufferHandle = 0;
1710 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1711 {
1712 framebuffer = context->getReadFramebuffer();
1713 framebufferHandle = context->getReadFramebufferHandle();
1714 }
1715 else
1716 {
1717 framebuffer = context->getDrawFramebuffer();
1718 framebufferHandle = context->getDrawFramebufferHandle();
1719 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001720
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001721 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001722 {
1723 return error(GL_INVALID_OPERATION);
1724 }
1725
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001726 switch (attachment)
1727 {
1728 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
1729 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
1730 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
1731 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001732 }
1733 }
1734 catch(std::bad_alloc&)
1735 {
1736 return error(GL_OUT_OF_MEMORY);
1737 }
1738}
1739
1740void __stdcall glFrontFace(GLenum mode)
1741{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001742 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001743
1744 try
1745 {
1746 switch (mode)
1747 {
1748 case GL_CW:
1749 case GL_CCW:
1750 {
1751 gl::Context *context = gl::getContext();
1752
1753 if (context)
1754 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001755 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001756 }
1757 }
1758 break;
1759 default:
1760 return error(GL_INVALID_ENUM);
1761 }
1762 }
1763 catch(std::bad_alloc&)
1764 {
1765 return error(GL_OUT_OF_MEMORY);
1766 }
1767}
1768
1769void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1770{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001771 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001772
1773 try
1774 {
1775 if (n < 0)
1776 {
1777 return error(GL_INVALID_VALUE);
1778 }
1779
1780 gl::Context *context = gl::getContext();
1781
1782 if (context)
1783 {
1784 for (int i = 0; i < n; i++)
1785 {
1786 buffers[i] = context->createBuffer();
1787 }
1788 }
1789 }
1790 catch(std::bad_alloc&)
1791 {
1792 return error(GL_OUT_OF_MEMORY);
1793 }
1794}
1795
1796void __stdcall glGenerateMipmap(GLenum target)
1797{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001798 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001799
1800 try
1801 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00001802 gl::Context *context = gl::getContext();
1803
1804 if (context)
1805 {
1806 gl::Texture *texture;
1807
1808 switch (target)
1809 {
1810 case GL_TEXTURE_2D:
1811 texture = context->getTexture2D();
1812 break;
1813
1814 case GL_TEXTURE_CUBE_MAP:
1815 texture = context->getTextureCubeMap();
1816 break;
1817
1818 default:
1819 return error(GL_INVALID_ENUM);
1820 }
1821
1822 texture->generateMipmaps();
1823 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001824 }
1825 catch(std::bad_alloc&)
1826 {
1827 return error(GL_OUT_OF_MEMORY);
1828 }
1829}
1830
1831void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1832{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001833 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001834
1835 try
1836 {
1837 if (n < 0)
1838 {
1839 return error(GL_INVALID_VALUE);
1840 }
1841
1842 gl::Context *context = gl::getContext();
1843
1844 if (context)
1845 {
1846 for (int i = 0; i < n; i++)
1847 {
1848 framebuffers[i] = context->createFramebuffer();
1849 }
1850 }
1851 }
1852 catch(std::bad_alloc&)
1853 {
1854 return error(GL_OUT_OF_MEMORY);
1855 }
1856}
1857
1858void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1859{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001860 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001861
1862 try
1863 {
1864 if (n < 0)
1865 {
1866 return error(GL_INVALID_VALUE);
1867 }
1868
1869 gl::Context *context = gl::getContext();
1870
1871 if (context)
1872 {
1873 for (int i = 0; i < n; i++)
1874 {
1875 renderbuffers[i] = context->createRenderbuffer();
1876 }
1877 }
1878 }
1879 catch(std::bad_alloc&)
1880 {
1881 return error(GL_OUT_OF_MEMORY);
1882 }
1883}
1884
1885void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1886{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001887 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001888
1889 try
1890 {
1891 if (n < 0)
1892 {
1893 return error(GL_INVALID_VALUE);
1894 }
1895
1896 gl::Context *context = gl::getContext();
1897
1898 if (context)
1899 {
1900 for (int i = 0; i < n; i++)
1901 {
1902 textures[i] = context->createTexture();
1903 }
1904 }
1905 }
1906 catch(std::bad_alloc&)
1907 {
1908 return error(GL_OUT_OF_MEMORY);
1909 }
1910}
1911
daniel@transgaming.com85423182010-04-22 13:35:27 +00001912void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001913{
daniel@transgaming.com85423182010-04-22 13:35:27 +00001914 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
1915 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001916 program, index, bufsize, length, size, type, name);
1917
1918 try
1919 {
1920 if (bufsize < 0)
1921 {
1922 return error(GL_INVALID_VALUE);
1923 }
1924
daniel@transgaming.com85423182010-04-22 13:35:27 +00001925 gl::Context *context = gl::getContext();
1926
1927 if (context)
1928 {
1929 gl::Program *programObject = context->getProgram(program);
1930
1931 if (!programObject)
1932 {
1933 if (context->getShader(program))
1934 {
1935 return error(GL_INVALID_OPERATION);
1936 }
1937 else
1938 {
1939 return error(GL_INVALID_VALUE);
1940 }
1941 }
1942
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001943 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00001944 {
1945 return error(GL_INVALID_VALUE);
1946 }
1947
1948 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
1949 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001950 }
1951 catch(std::bad_alloc&)
1952 {
1953 return error(GL_OUT_OF_MEMORY);
1954 }
1955}
1956
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001957void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001958{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001959 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001960 "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 +00001961 program, index, bufsize, length, size, type, name);
1962
1963 try
1964 {
1965 if (bufsize < 0)
1966 {
1967 return error(GL_INVALID_VALUE);
1968 }
1969
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001970 gl::Context *context = gl::getContext();
1971
1972 if (context)
1973 {
1974 gl::Program *programObject = context->getProgram(program);
1975
1976 if (!programObject)
1977 {
1978 if (context->getShader(program))
1979 {
1980 return error(GL_INVALID_OPERATION);
1981 }
1982 else
1983 {
1984 return error(GL_INVALID_VALUE);
1985 }
1986 }
1987
1988 if (index >= (GLuint)programObject->getActiveUniformCount())
1989 {
1990 return error(GL_INVALID_VALUE);
1991 }
1992
1993 programObject->getActiveUniform(index, bufsize, length, size, type, name);
1994 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001995 }
1996 catch(std::bad_alloc&)
1997 {
1998 return error(GL_OUT_OF_MEMORY);
1999 }
2000}
2001
2002void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2003{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002004 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2005 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002006
2007 try
2008 {
2009 if (maxcount < 0)
2010 {
2011 return error(GL_INVALID_VALUE);
2012 }
2013
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002014 gl::Context *context = gl::getContext();
2015
2016 if (context)
2017 {
2018 gl::Program *programObject = context->getProgram(program);
2019
2020 if (!programObject)
2021 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002022 if (context->getShader(program))
2023 {
2024 return error(GL_INVALID_OPERATION);
2025 }
2026 else
2027 {
2028 return error(GL_INVALID_VALUE);
2029 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002030 }
2031
2032 return programObject->getAttachedShaders(maxcount, count, shaders);
2033 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002034 }
2035 catch(std::bad_alloc&)
2036 {
2037 return error(GL_OUT_OF_MEMORY);
2038 }
2039}
2040
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002041int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002042{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002043 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002044
2045 try
2046 {
2047 gl::Context *context = gl::getContext();
2048
2049 if (context)
2050 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002051
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002052 gl::Program *programObject = context->getProgram(program);
2053
2054 if (!programObject)
2055 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002056 if (context->getShader(program))
2057 {
2058 return error(GL_INVALID_OPERATION, -1);
2059 }
2060 else
2061 {
2062 return error(GL_INVALID_VALUE, -1);
2063 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002064 }
2065
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002066 if (!programObject->isLinked())
2067 {
2068 return error(GL_INVALID_OPERATION, -1);
2069 }
2070
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002071 return programObject->getAttributeLocation(name);
2072 }
2073 }
2074 catch(std::bad_alloc&)
2075 {
2076 return error(GL_OUT_OF_MEMORY, -1);
2077 }
2078
2079 return -1;
2080}
2081
2082void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2083{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002084 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002085
2086 try
2087 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002088 gl::Context *context = gl::getContext();
2089
2090 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002091 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002092 if (!(context->getBooleanv(pname, params)))
2093 {
2094 GLenum nativeType;
2095 unsigned int numParams = 0;
2096 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2097 return error(GL_INVALID_ENUM);
2098
2099 if (numParams == 0)
2100 return; // it is known that the pname is valid, but there are no parameters to return
2101
2102 if (nativeType == GL_FLOAT)
2103 {
2104 GLfloat *floatParams = NULL;
2105 floatParams = new GLfloat[numParams];
2106
2107 context->getFloatv(pname, floatParams);
2108
2109 for (unsigned int i = 0; i < numParams; ++i)
2110 {
2111 if (floatParams[i] == 0.0f)
2112 params[i] = GL_FALSE;
2113 else
2114 params[i] = GL_TRUE;
2115 }
2116
2117 delete [] floatParams;
2118 }
2119 else if (nativeType == GL_INT)
2120 {
2121 GLint *intParams = NULL;
2122 intParams = new GLint[numParams];
2123
2124 context->getIntegerv(pname, intParams);
2125
2126 for (unsigned int i = 0; i < numParams; ++i)
2127 {
2128 if (intParams[i] == 0)
2129 params[i] = GL_FALSE;
2130 else
2131 params[i] = GL_TRUE;
2132 }
2133
2134 delete [] intParams;
2135 }
2136 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002137 }
2138 }
2139 catch(std::bad_alloc&)
2140 {
2141 return error(GL_OUT_OF_MEMORY);
2142 }
2143}
2144
2145void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2146{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002147 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 +00002148
2149 try
2150 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002151 gl::Context *context = gl::getContext();
2152
2153 if (context)
2154 {
2155 gl::Buffer *buffer;
2156
2157 switch (target)
2158 {
2159 case GL_ARRAY_BUFFER:
2160 buffer = context->getArrayBuffer();
2161 break;
2162 case GL_ELEMENT_ARRAY_BUFFER:
2163 buffer = context->getElementArrayBuffer();
2164 break;
2165 default: return error(GL_INVALID_ENUM);
2166 }
2167
2168 if (!buffer)
2169 {
2170 // A null buffer means that "0" is bound to the requested buffer target
2171 return error(GL_INVALID_OPERATION);
2172 }
2173
2174 switch (pname)
2175 {
2176 case GL_BUFFER_USAGE:
2177 *params = buffer->usage();
2178 break;
2179 case GL_BUFFER_SIZE:
2180 *params = buffer->size();
2181 break;
2182 default: return error(GL_INVALID_ENUM);
2183 }
2184 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002185 }
2186 catch(std::bad_alloc&)
2187 {
2188 return error(GL_OUT_OF_MEMORY);
2189 }
2190}
2191
2192GLenum __stdcall glGetError(void)
2193{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002194 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002195
2196 gl::Context *context = gl::getContext();
2197
2198 if (context)
2199 {
2200 return context->getError();
2201 }
2202
2203 return GL_NO_ERROR;
2204}
2205
2206void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2207{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002208 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002209
2210 try
2211 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002212 gl::Context *context = gl::getContext();
2213
2214 if (context)
2215 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002216 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002217 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002218 GLenum nativeType;
2219 unsigned int numParams = 0;
2220 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2221 return error(GL_INVALID_ENUM);
2222
2223 if (numParams == 0)
2224 return; // it is known that the pname is valid, but that there are no parameters to return.
2225
2226 if (nativeType == GL_BOOL)
2227 {
2228 GLboolean *boolParams = NULL;
2229 boolParams = new GLboolean[numParams];
2230
2231 context->getBooleanv(pname, boolParams);
2232
2233 for (unsigned int i = 0; i < numParams; ++i)
2234 {
2235 if (boolParams[i] == GL_FALSE)
2236 params[i] = 0.0f;
2237 else
2238 params[i] = 1.0f;
2239 }
2240
2241 delete [] boolParams;
2242 }
2243 else if (nativeType == GL_INT)
2244 {
2245 GLint *intParams = NULL;
2246 intParams = new GLint[numParams];
2247
2248 context->getIntegerv(pname, intParams);
2249
2250 for (unsigned int i = 0; i < numParams; ++i)
2251 {
2252 params[i] = (GLfloat)intParams[i];
2253 }
2254
2255 delete [] intParams;
2256 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002257 }
2258 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002259 }
2260 catch(std::bad_alloc&)
2261 {
2262 return error(GL_OUT_OF_MEMORY);
2263 }
2264}
2265
2266void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2267{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002268 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2269 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002270
2271 try
2272 {
2273 gl::Context *context = gl::getContext();
2274
2275 if (context)
2276 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002277 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002278 {
2279 return error(GL_INVALID_ENUM);
2280 }
2281
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002282 gl::Framebuffer *framebuffer = NULL;
2283 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2284 {
2285 if(context->getReadFramebufferHandle() == 0)
2286 {
2287 return error(GL_INVALID_OPERATION);
2288 }
2289
2290 framebuffer = context->getReadFramebuffer();
2291 }
2292 else
2293 {
2294 if (context->getDrawFramebufferHandle() == 0)
2295 {
2296 return error(GL_INVALID_OPERATION);
2297 }
2298
2299 framebuffer = context->getDrawFramebuffer();
2300 }
2301
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002302 GLenum attachmentType;
2303 GLuint attachmentHandle;
2304 switch (attachment)
2305 {
2306 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002307 attachmentType = framebuffer->getColorbufferType();
2308 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002309 break;
2310 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002311 attachmentType = framebuffer->getDepthbufferType();
2312 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002313 break;
2314 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002315 attachmentType = framebuffer->getStencilbufferType();
2316 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002317 break;
2318 default: return error(GL_INVALID_ENUM);
2319 }
2320
2321 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002322 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002323 {
2324 attachmentObjectType = attachmentType;
2325 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002326 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002327 {
2328 attachmentObjectType = GL_TEXTURE;
2329 }
2330 else UNREACHABLE();
2331
2332 switch (pname)
2333 {
2334 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2335 *params = attachmentObjectType;
2336 break;
2337 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2338 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2339 {
2340 *params = attachmentHandle;
2341 }
2342 else
2343 {
2344 return error(GL_INVALID_ENUM);
2345 }
2346 break;
2347 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2348 if (attachmentObjectType == GL_TEXTURE)
2349 {
2350 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2351 }
2352 else
2353 {
2354 return error(GL_INVALID_ENUM);
2355 }
2356 break;
2357 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2358 if (attachmentObjectType == GL_TEXTURE)
2359 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002360 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002361 {
2362 *params = attachmentType;
2363 }
2364 else
2365 {
2366 *params = 0;
2367 }
2368 }
2369 else
2370 {
2371 return error(GL_INVALID_ENUM);
2372 }
2373 break;
2374 default:
2375 return error(GL_INVALID_ENUM);
2376 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002377 }
2378 }
2379 catch(std::bad_alloc&)
2380 {
2381 return error(GL_OUT_OF_MEMORY);
2382 }
2383}
2384
2385void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2386{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002387 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002388
2389 try
2390 {
2391 gl::Context *context = gl::getContext();
2392
2393 if (context)
2394 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002395 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002396 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002397 GLenum nativeType;
2398 unsigned int numParams = 0;
2399 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2400 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002401
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002402 if (numParams == 0)
2403 return; // it is known that pname is valid, but there are no parameters to return
2404
2405 if (nativeType == GL_BOOL)
2406 {
2407 GLboolean *boolParams = NULL;
2408 boolParams = new GLboolean[numParams];
2409
2410 context->getBooleanv(pname, boolParams);
2411
2412 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002413 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002414 if (boolParams[i] == GL_FALSE)
2415 params[i] = 0;
2416 else
2417 params[i] = 1;
2418 }
2419
2420 delete [] boolParams;
2421 }
2422 else if (nativeType == GL_FLOAT)
2423 {
2424 GLfloat *floatParams = NULL;
2425 floatParams = new GLfloat[numParams];
2426
2427 context->getFloatv(pname, floatParams);
2428
2429 for (unsigned int i = 0; i < numParams; ++i)
2430 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002431 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 +00002432 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002433 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002434 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002435 else
2436 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 +00002437 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002438
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002439 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002440 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002441 }
2442 }
2443 }
2444 catch(std::bad_alloc&)
2445 {
2446 return error(GL_OUT_OF_MEMORY);
2447 }
2448}
2449
2450void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2451{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002452 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002453
2454 try
2455 {
2456 gl::Context *context = gl::getContext();
2457
2458 if (context)
2459 {
2460 gl::Program *programObject = context->getProgram(program);
2461
2462 if (!programObject)
2463 {
2464 return error(GL_INVALID_VALUE);
2465 }
2466
2467 switch (pname)
2468 {
2469 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002470 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002471 return;
2472 case GL_LINK_STATUS:
2473 *params = programObject->isLinked();
2474 return;
2475 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002476 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002477 return;
2478 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002479 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002480 return;
2481 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002482 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002483 return;
2484 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002485 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002486 return;
2487 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002488 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002489 return;
2490 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002491 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002492 return;
2493 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002494 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002495 return;
2496 default:
2497 return error(GL_INVALID_ENUM);
2498 }
2499 }
2500 }
2501 catch(std::bad_alloc&)
2502 {
2503 return error(GL_OUT_OF_MEMORY);
2504 }
2505}
2506
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002507void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002508{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002509 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 +00002510 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002511
2512 try
2513 {
2514 if (bufsize < 0)
2515 {
2516 return error(GL_INVALID_VALUE);
2517 }
2518
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002519 gl::Context *context = gl::getContext();
2520
2521 if (context)
2522 {
2523 gl::Program *programObject = context->getProgram(program);
2524
2525 if (!programObject)
2526 {
2527 return error(GL_INVALID_VALUE);
2528 }
2529
2530 programObject->getInfoLog(bufsize, length, infolog);
2531 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002532 }
2533 catch(std::bad_alloc&)
2534 {
2535 return error(GL_OUT_OF_MEMORY);
2536 }
2537}
2538
2539void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2540{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002541 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 +00002542
2543 try
2544 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002545 gl::Context *context = gl::getContext();
2546
2547 if (context)
2548 {
2549 if (target != GL_RENDERBUFFER)
2550 {
2551 return error(GL_INVALID_ENUM);
2552 }
2553
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002554 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002555 {
2556 return error(GL_INVALID_OPERATION);
2557 }
2558
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002559 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002560
2561 switch (pname)
2562 {
2563 case GL_RENDERBUFFER_WIDTH:
2564 *params = renderbuffer->getWidth();
2565 break;
2566 case GL_RENDERBUFFER_HEIGHT:
2567 *params = renderbuffer->getHeight();
2568 break;
2569 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2570 *params = renderbuffer->getFormat();
2571 break;
2572 case GL_RENDERBUFFER_RED_SIZE:
2573 if (renderbuffer->isColorbuffer())
2574 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002575 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002576 }
2577 else
2578 {
2579 *params = 0;
2580 }
2581 break;
2582 case GL_RENDERBUFFER_GREEN_SIZE:
2583 if (renderbuffer->isColorbuffer())
2584 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002585 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002586 }
2587 else
2588 {
2589 *params = 0;
2590 }
2591 break;
2592 case GL_RENDERBUFFER_BLUE_SIZE:
2593 if (renderbuffer->isColorbuffer())
2594 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002595 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002596 }
2597 else
2598 {
2599 *params = 0;
2600 }
2601 break;
2602 case GL_RENDERBUFFER_ALPHA_SIZE:
2603 if (renderbuffer->isColorbuffer())
2604 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002605 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002606 }
2607 else
2608 {
2609 *params = 0;
2610 }
2611 break;
2612 case GL_RENDERBUFFER_DEPTH_SIZE:
2613 if (renderbuffer->isDepthbuffer())
2614 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002615 *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002616 }
2617 else
2618 {
2619 *params = 0;
2620 }
2621 break;
2622 case GL_RENDERBUFFER_STENCIL_SIZE:
2623 if (renderbuffer->isStencilbuffer())
2624 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002625 *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002626 }
2627 else
2628 {
2629 *params = 0;
2630 }
2631 break;
2632 default:
2633 return error(GL_INVALID_ENUM);
2634 }
2635 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002636 }
2637 catch(std::bad_alloc&)
2638 {
2639 return error(GL_OUT_OF_MEMORY);
2640 }
2641}
2642
2643void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2644{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002645 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002646
2647 try
2648 {
2649 gl::Context *context = gl::getContext();
2650
2651 if (context)
2652 {
2653 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002654
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002655 if (!shaderObject)
2656 {
2657 return error(GL_INVALID_VALUE);
2658 }
2659
2660 switch (pname)
2661 {
2662 case GL_SHADER_TYPE:
2663 *params = shaderObject->getType();
2664 return;
2665 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002666 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002667 return;
2668 case GL_COMPILE_STATUS:
2669 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2670 return;
2671 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002672 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002673 return;
2674 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002675 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002676 return;
2677 default:
2678 return error(GL_INVALID_ENUM);
2679 }
2680 }
2681 }
2682 catch(std::bad_alloc&)
2683 {
2684 return error(GL_OUT_OF_MEMORY);
2685 }
2686}
2687
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002688void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002689{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002690 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 +00002691 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002692
2693 try
2694 {
2695 if (bufsize < 0)
2696 {
2697 return error(GL_INVALID_VALUE);
2698 }
2699
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002700 gl::Context *context = gl::getContext();
2701
2702 if (context)
2703 {
2704 gl::Shader *shaderObject = context->getShader(shader);
2705
2706 if (!shaderObject)
2707 {
2708 return error(GL_INVALID_VALUE);
2709 }
2710
2711 shaderObject->getInfoLog(bufsize, length, infolog);
2712 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002713 }
2714 catch(std::bad_alloc&)
2715 {
2716 return error(GL_OUT_OF_MEMORY);
2717 }
2718}
2719
2720void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2721{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002722 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2723 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002724
2725 try
2726 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002727 switch (shadertype)
2728 {
2729 case GL_VERTEX_SHADER:
2730 case GL_FRAGMENT_SHADER:
2731 break;
2732 default:
2733 return error(GL_INVALID_ENUM);
2734 }
2735
2736 switch (precisiontype)
2737 {
2738 case GL_LOW_FLOAT:
2739 case GL_MEDIUM_FLOAT:
2740 case GL_HIGH_FLOAT:
2741 // Assume IEEE 754 precision
2742 range[0] = 127;
2743 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002744 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002745 break;
2746 case GL_LOW_INT:
2747 case GL_MEDIUM_INT:
2748 case GL_HIGH_INT:
2749 // Some (most) hardware only supports single-precision floating-point numbers,
2750 // which can accurately represent integers up to +/-16777216
2751 range[0] = 24;
2752 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002753 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002754 break;
2755 default:
2756 return error(GL_INVALID_ENUM);
2757 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002758 }
2759 catch(std::bad_alloc&)
2760 {
2761 return error(GL_OUT_OF_MEMORY);
2762 }
2763}
2764
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002765void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002766{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002767 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 +00002768 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002769
2770 try
2771 {
2772 if (bufsize < 0)
2773 {
2774 return error(GL_INVALID_VALUE);
2775 }
2776
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002777 gl::Context *context = gl::getContext();
2778
2779 if (context)
2780 {
2781 gl::Shader *shaderObject = context->getShader(shader);
2782
2783 if (!shaderObject)
2784 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002785 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002786 }
2787
2788 shaderObject->getSource(bufsize, length, source);
2789 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002790 }
2791 catch(std::bad_alloc&)
2792 {
2793 return error(GL_OUT_OF_MEMORY);
2794 }
2795}
2796
2797const GLubyte* __stdcall glGetString(GLenum name)
2798{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002799 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002800
2801 try
2802 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002803 gl::Context *context = gl::getContext();
2804
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002805 switch (name)
2806 {
2807 case GL_VENDOR:
2808 return (GLubyte*)"TransGaming Inc.";
2809 case GL_RENDERER:
2810 return (GLubyte*)"ANGLE";
2811 case GL_VERSION:
2812 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2813 case GL_SHADING_LANGUAGE_VERSION:
2814 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2815 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002816 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002817 default:
2818 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2819 }
2820 }
2821 catch(std::bad_alloc&)
2822 {
2823 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2824 }
2825
2826 return NULL;
2827}
2828
2829void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2830{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002831 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 +00002832
2833 try
2834 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002835 gl::Context *context = gl::getContext();
2836
2837 if (context)
2838 {
2839 gl::Texture *texture;
2840
2841 switch (target)
2842 {
2843 case GL_TEXTURE_2D:
2844 texture = context->getTexture2D();
2845 break;
2846 case GL_TEXTURE_CUBE_MAP:
2847 texture = context->getTextureCubeMap();
2848 break;
2849 default:
2850 return error(GL_INVALID_ENUM);
2851 }
2852
2853 switch (pname)
2854 {
2855 case GL_TEXTURE_MAG_FILTER:
2856 *params = (GLfloat)texture->getMagFilter();
2857 break;
2858 case GL_TEXTURE_MIN_FILTER:
2859 *params = (GLfloat)texture->getMinFilter();
2860 break;
2861 case GL_TEXTURE_WRAP_S:
2862 *params = (GLfloat)texture->getWrapS();
2863 break;
2864 case GL_TEXTURE_WRAP_T:
2865 *params = (GLfloat)texture->getWrapT();
2866 break;
2867 default:
2868 return error(GL_INVALID_ENUM);
2869 }
2870 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002871 }
2872 catch(std::bad_alloc&)
2873 {
2874 return error(GL_OUT_OF_MEMORY);
2875 }
2876}
2877
2878void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2879{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002880 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 +00002881
2882 try
2883 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002884 gl::Context *context = gl::getContext();
2885
2886 if (context)
2887 {
2888 gl::Texture *texture;
2889
2890 switch (target)
2891 {
2892 case GL_TEXTURE_2D:
2893 texture = context->getTexture2D();
2894 break;
2895 case GL_TEXTURE_CUBE_MAP:
2896 texture = context->getTextureCubeMap();
2897 break;
2898 default:
2899 return error(GL_INVALID_ENUM);
2900 }
2901
2902 switch (pname)
2903 {
2904 case GL_TEXTURE_MAG_FILTER:
2905 *params = texture->getMagFilter();
2906 break;
2907 case GL_TEXTURE_MIN_FILTER:
2908 *params = texture->getMinFilter();
2909 break;
2910 case GL_TEXTURE_WRAP_S:
2911 *params = texture->getWrapS();
2912 break;
2913 case GL_TEXTURE_WRAP_T:
2914 *params = texture->getWrapT();
2915 break;
2916 default:
2917 return error(GL_INVALID_ENUM);
2918 }
2919 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002920 }
2921 catch(std::bad_alloc&)
2922 {
2923 return error(GL_OUT_OF_MEMORY);
2924 }
2925}
2926
2927void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2928{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002929 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002930
2931 try
2932 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002933 gl::Context *context = gl::getContext();
2934
2935 if (context)
2936 {
2937 if (program == 0)
2938 {
2939 return error(GL_INVALID_VALUE);
2940 }
2941
2942 gl::Program *programObject = context->getProgram(program);
2943
2944 if (!programObject || !programObject->isLinked())
2945 {
2946 return error(GL_INVALID_OPERATION);
2947 }
2948
2949 if (!programObject->getUniformfv(location, params))
2950 {
2951 return error(GL_INVALID_OPERATION);
2952 }
2953 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002954 }
2955 catch(std::bad_alloc&)
2956 {
2957 return error(GL_OUT_OF_MEMORY);
2958 }
2959}
2960
2961void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2962{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002963 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002964
2965 try
2966 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002967 gl::Context *context = gl::getContext();
2968
2969 if (context)
2970 {
2971 if (program == 0)
2972 {
2973 return error(GL_INVALID_VALUE);
2974 }
2975
2976 gl::Program *programObject = context->getProgram(program);
2977
2978 if (!programObject || !programObject->isLinked())
2979 {
2980 return error(GL_INVALID_OPERATION);
2981 }
2982
2983 if (!programObject)
2984 {
2985 return error(GL_INVALID_OPERATION);
2986 }
2987
2988 if (!programObject->getUniformiv(location, params))
2989 {
2990 return error(GL_INVALID_OPERATION);
2991 }
2992 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002993 }
2994 catch(std::bad_alloc&)
2995 {
2996 return error(GL_OUT_OF_MEMORY);
2997 }
2998}
2999
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003000int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003001{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003002 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003003
3004 try
3005 {
3006 gl::Context *context = gl::getContext();
3007
3008 if (strstr(name, "gl_") == name)
3009 {
3010 return -1;
3011 }
3012
3013 if (context)
3014 {
3015 gl::Program *programObject = context->getProgram(program);
3016
3017 if (!programObject)
3018 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003019 if (context->getShader(program))
3020 {
3021 return error(GL_INVALID_OPERATION, -1);
3022 }
3023 else
3024 {
3025 return error(GL_INVALID_VALUE, -1);
3026 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003027 }
3028
3029 if (!programObject->isLinked())
3030 {
3031 return error(GL_INVALID_OPERATION, -1);
3032 }
3033
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003034 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003035 }
3036 }
3037 catch(std::bad_alloc&)
3038 {
3039 return error(GL_OUT_OF_MEMORY, -1);
3040 }
3041
3042 return -1;
3043}
3044
3045void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3046{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003047 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003048
3049 try
3050 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003051 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003052
daniel@transgaming.come0078962010-04-15 20:45:08 +00003053 if (context)
3054 {
3055 if (index >= gl::MAX_VERTEX_ATTRIBS)
3056 {
3057 return error(GL_INVALID_VALUE);
3058 }
3059
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003060 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003061
daniel@transgaming.come0078962010-04-15 20:45:08 +00003062 switch (pname)
3063 {
3064 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003065 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003066 break;
3067 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003068 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003069 break;
3070 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003071 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003072 break;
3073 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003074 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003075 break;
3076 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003077 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003078 break;
3079 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003080 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003081 break;
3082 case GL_CURRENT_VERTEX_ATTRIB:
3083 for (int i = 0; i < 4; ++i)
3084 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003085 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003086 }
3087 break;
3088 default: return error(GL_INVALID_ENUM);
3089 }
3090 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003091 }
3092 catch(std::bad_alloc&)
3093 {
3094 return error(GL_OUT_OF_MEMORY);
3095 }
3096}
3097
3098void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3099{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003100 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003101
3102 try
3103 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003104 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003105
daniel@transgaming.come0078962010-04-15 20:45:08 +00003106 if (context)
3107 {
3108 if (index >= gl::MAX_VERTEX_ATTRIBS)
3109 {
3110 return error(GL_INVALID_VALUE);
3111 }
3112
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003113 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003114
daniel@transgaming.come0078962010-04-15 20:45:08 +00003115 switch (pname)
3116 {
3117 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003118 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003119 break;
3120 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003121 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003122 break;
3123 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003124 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003125 break;
3126 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003127 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003128 break;
3129 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003130 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003131 break;
3132 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003133 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003134 break;
3135 case GL_CURRENT_VERTEX_ATTRIB:
3136 for (int i = 0; i < 4; ++i)
3137 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003138 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003139 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3140 }
3141 break;
3142 default: return error(GL_INVALID_ENUM);
3143 }
3144 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003145 }
3146 catch(std::bad_alloc&)
3147 {
3148 return error(GL_OUT_OF_MEMORY);
3149 }
3150}
3151
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003152void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003153{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003154 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003155
3156 try
3157 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003158 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003159
daniel@transgaming.come0078962010-04-15 20:45:08 +00003160 if (context)
3161 {
3162 if (index >= gl::MAX_VERTEX_ATTRIBS)
3163 {
3164 return error(GL_INVALID_VALUE);
3165 }
3166
3167 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3168 {
3169 return error(GL_INVALID_ENUM);
3170 }
3171
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003172 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003173 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003174 }
3175 catch(std::bad_alloc&)
3176 {
3177 return error(GL_OUT_OF_MEMORY);
3178 }
3179}
3180
3181void __stdcall glHint(GLenum target, GLenum mode)
3182{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003183 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003184
3185 try
3186 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003187 switch (target)
3188 {
3189 case GL_GENERATE_MIPMAP_HINT:
3190 switch (mode)
3191 {
3192 case GL_FASTEST:
3193 case GL_NICEST:
3194 case GL_DONT_CARE:
3195 break;
3196 default:
3197 return error(GL_INVALID_ENUM);
3198 }
3199 break;
3200 default:
3201 return error(GL_INVALID_ENUM);
3202 }
3203
3204 gl::Context *context = gl::getContext();
3205 if (context)
3206 {
3207 if (target == GL_GENERATE_MIPMAP_HINT)
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003208 context->setGenerateMipmapHint(mode);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003209 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003210 }
3211 catch(std::bad_alloc&)
3212 {
3213 return error(GL_OUT_OF_MEMORY);
3214 }
3215}
3216
3217GLboolean __stdcall glIsBuffer(GLuint buffer)
3218{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003219 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003220
3221 try
3222 {
3223 gl::Context *context = gl::getContext();
3224
3225 if (context && buffer)
3226 {
3227 gl::Buffer *bufferObject = context->getBuffer(buffer);
3228
3229 if (bufferObject)
3230 {
3231 return GL_TRUE;
3232 }
3233 }
3234 }
3235 catch(std::bad_alloc&)
3236 {
3237 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3238 }
3239
3240 return GL_FALSE;
3241}
3242
3243GLboolean __stdcall glIsEnabled(GLenum cap)
3244{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003245 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003246
3247 try
3248 {
3249 gl::Context *context = gl::getContext();
3250
3251 if (context)
3252 {
3253 switch (cap)
3254 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003255 case GL_CULL_FACE: return context->isCullFaceEnabled();
3256 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3257 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3258 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3259 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3260 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3261 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3262 case GL_BLEND: return context->isBlendEnabled();
3263 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003264 default:
3265 return error(GL_INVALID_ENUM, false);
3266 }
3267 }
3268 }
3269 catch(std::bad_alloc&)
3270 {
3271 return error(GL_OUT_OF_MEMORY, false);
3272 }
3273
3274 return false;
3275}
3276
3277GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3278{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003279 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003280
3281 try
3282 {
3283 gl::Context *context = gl::getContext();
3284
3285 if (context && framebuffer)
3286 {
3287 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3288
3289 if (framebufferObject)
3290 {
3291 return GL_TRUE;
3292 }
3293 }
3294 }
3295 catch(std::bad_alloc&)
3296 {
3297 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3298 }
3299
3300 return GL_FALSE;
3301}
3302
3303GLboolean __stdcall glIsProgram(GLuint program)
3304{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003305 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003306
3307 try
3308 {
3309 gl::Context *context = gl::getContext();
3310
3311 if (context && program)
3312 {
3313 gl::Program *programObject = context->getProgram(program);
3314
3315 if (programObject)
3316 {
3317 return GL_TRUE;
3318 }
3319 }
3320 }
3321 catch(std::bad_alloc&)
3322 {
3323 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3324 }
3325
3326 return GL_FALSE;
3327}
3328
3329GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3330{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003331 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003332
3333 try
3334 {
3335 gl::Context *context = gl::getContext();
3336
3337 if (context && renderbuffer)
3338 {
3339 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3340
3341 if (renderbufferObject)
3342 {
3343 return GL_TRUE;
3344 }
3345 }
3346 }
3347 catch(std::bad_alloc&)
3348 {
3349 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3350 }
3351
3352 return GL_FALSE;
3353}
3354
3355GLboolean __stdcall glIsShader(GLuint shader)
3356{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003357 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003358
3359 try
3360 {
3361 gl::Context *context = gl::getContext();
3362
3363 if (context && shader)
3364 {
3365 gl::Shader *shaderObject = context->getShader(shader);
3366
3367 if (shaderObject)
3368 {
3369 return GL_TRUE;
3370 }
3371 }
3372 }
3373 catch(std::bad_alloc&)
3374 {
3375 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3376 }
3377
3378 return GL_FALSE;
3379}
3380
3381GLboolean __stdcall glIsTexture(GLuint texture)
3382{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003383 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003384
3385 try
3386 {
3387 gl::Context *context = gl::getContext();
3388
3389 if (context && texture)
3390 {
3391 gl::Texture *textureObject = context->getTexture(texture);
3392
3393 if (textureObject)
3394 {
3395 return GL_TRUE;
3396 }
3397 }
3398 }
3399 catch(std::bad_alloc&)
3400 {
3401 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3402 }
3403
3404 return GL_FALSE;
3405}
3406
3407void __stdcall glLineWidth(GLfloat width)
3408{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003409 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003410
3411 try
3412 {
3413 if (width <= 0.0f)
3414 {
3415 return error(GL_INVALID_VALUE);
3416 }
3417
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003418 gl::Context *context = gl::getContext();
3419
3420 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003421 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003422 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003423 }
3424 }
3425 catch(std::bad_alloc&)
3426 {
3427 return error(GL_OUT_OF_MEMORY);
3428 }
3429}
3430
3431void __stdcall glLinkProgram(GLuint program)
3432{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003433 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003434
3435 try
3436 {
3437 gl::Context *context = gl::getContext();
3438
3439 if (context)
3440 {
3441 gl::Program *programObject = context->getProgram(program);
3442
3443 if (!programObject)
3444 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003445 if (context->getShader(program))
3446 {
3447 return error(GL_INVALID_OPERATION);
3448 }
3449 else
3450 {
3451 return error(GL_INVALID_VALUE);
3452 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003453 }
3454
3455 programObject->link();
3456 }
3457 }
3458 catch(std::bad_alloc&)
3459 {
3460 return error(GL_OUT_OF_MEMORY);
3461 }
3462}
3463
3464void __stdcall glPixelStorei(GLenum pname, GLint param)
3465{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003466 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003467
3468 try
3469 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003470 gl::Context *context = gl::getContext();
3471
3472 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003473 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003474 switch (pname)
3475 {
3476 case GL_UNPACK_ALIGNMENT:
3477 if (param != 1 && param != 2 && param != 4 && param != 8)
3478 {
3479 return error(GL_INVALID_VALUE);
3480 }
3481
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003482 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003483 break;
3484
3485 case GL_PACK_ALIGNMENT:
3486 if (param != 1 && param != 2 && param != 4 && param != 8)
3487 {
3488 return error(GL_INVALID_VALUE);
3489 }
3490
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003491 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003492 break;
3493
3494 default:
3495 return error(GL_INVALID_ENUM);
3496 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003497 }
3498 }
3499 catch(std::bad_alloc&)
3500 {
3501 return error(GL_OUT_OF_MEMORY);
3502 }
3503}
3504
3505void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3506{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003507 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003508
3509 try
3510 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003511 gl::Context *context = gl::getContext();
3512
3513 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003514 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003515 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003516 }
3517 }
3518 catch(std::bad_alloc&)
3519 {
3520 return error(GL_OUT_OF_MEMORY);
3521 }
3522}
3523
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003524void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003525{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003526 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003527 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003528 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003529
3530 try
3531 {
3532 if (width < 0 || height < 0)
3533 {
3534 return error(GL_INVALID_VALUE);
3535 }
3536
3537 switch (format)
3538 {
3539 case GL_RGBA:
3540 switch (type)
3541 {
3542 case GL_UNSIGNED_BYTE:
3543 break;
3544 default:
3545 return error(GL_INVALID_OPERATION);
3546 }
3547 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003548 case GL_BGRA_EXT:
3549 switch (type)
3550 {
3551 case GL_UNSIGNED_BYTE:
3552 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3553 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3554 break;
3555 default:
3556 return error(GL_INVALID_OPERATION);
3557 }
3558 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003559 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3560 switch (type)
3561 {
3562 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3563 break;
3564 default:
3565 return error(GL_INVALID_OPERATION);
3566 }
3567 break;
3568 default:
3569 return error(GL_INVALID_OPERATION);
3570 }
3571
3572 gl::Context *context = gl::getContext();
3573
3574 if (context)
3575 {
3576 context->readPixels(x, y, width, height, format, type, pixels);
3577 }
3578 }
3579 catch(std::bad_alloc&)
3580 {
3581 return error(GL_OUT_OF_MEMORY);
3582 }
3583}
3584
3585void __stdcall glReleaseShaderCompiler(void)
3586{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003587 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003588
3589 try
3590 {
3591 gl::Shader::releaseCompiler();
3592 }
3593 catch(std::bad_alloc&)
3594 {
3595 return error(GL_OUT_OF_MEMORY);
3596 }
3597}
3598
3599void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3600{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003601 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3602 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003603
3604 try
3605 {
3606 switch (target)
3607 {
3608 case GL_RENDERBUFFER:
3609 break;
3610 default:
3611 return error(GL_INVALID_ENUM);
3612 }
3613
3614 switch (internalformat)
3615 {
3616 case GL_DEPTH_COMPONENT16:
3617 case GL_RGBA4:
3618 case GL_RGB5_A1:
3619 case GL_RGB565:
3620 case GL_STENCIL_INDEX8:
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003621 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003622 break;
3623 default:
3624 return error(GL_INVALID_ENUM);
3625 }
3626
3627 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
3628 {
3629 return error(GL_INVALID_VALUE);
3630 }
3631
3632 gl::Context *context = gl::getContext();
3633
3634 if (context)
3635 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003636 GLuint handle = context->getRenderbufferHandle();
3637 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003638 {
3639 return error(GL_INVALID_OPERATION);
3640 }
3641
3642 switch (internalformat)
3643 {
3644 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003645 context->setRenderbufferStorage(new gl::Depthbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003646 break;
3647 case GL_RGBA4:
3648 case GL_RGB5_A1:
3649 case GL_RGB565:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003650 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003651 break;
3652 case GL_STENCIL_INDEX8:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003653 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003654 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003655 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003656 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003657 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003658 default:
3659 return error(GL_INVALID_ENUM);
3660 }
3661 }
3662 }
3663 catch(std::bad_alloc&)
3664 {
3665 return error(GL_OUT_OF_MEMORY);
3666 }
3667}
3668
3669void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3670{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003671 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003672
3673 try
3674 {
3675 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003676
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003677 if (context)
3678 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00003679 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003680 }
3681 }
3682 catch(std::bad_alloc&)
3683 {
3684 return error(GL_OUT_OF_MEMORY);
3685 }
3686}
3687
3688void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3689{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003690 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 +00003691
3692 try
3693 {
3694 if (width < 0 || height < 0)
3695 {
3696 return error(GL_INVALID_VALUE);
3697 }
3698
3699 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003700
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003701 if (context)
3702 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003703 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003704 }
3705 }
3706 catch(std::bad_alloc&)
3707 {
3708 return error(GL_OUT_OF_MEMORY);
3709 }
3710}
3711
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003712void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003713{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003714 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003715 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003716 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003717
3718 try
3719 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00003720 // No binary shader formats are supported.
3721 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003722 }
3723 catch(std::bad_alloc&)
3724 {
3725 return error(GL_OUT_OF_MEMORY);
3726 }
3727}
3728
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003729void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003730{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003731 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 +00003732 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003733
3734 try
3735 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003736 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003737 {
3738 return error(GL_INVALID_VALUE);
3739 }
3740
3741 gl::Context *context = gl::getContext();
3742
3743 if (context)
3744 {
3745 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003746
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003747 if (!shaderObject)
3748 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003749 if (context->getProgram(shader))
3750 {
3751 return error(GL_INVALID_OPERATION);
3752 }
3753 else
3754 {
3755 return error(GL_INVALID_VALUE);
3756 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003757 }
3758
3759 shaderObject->setSource(count, string, length);
3760 }
3761 }
3762 catch(std::bad_alloc&)
3763 {
3764 return error(GL_OUT_OF_MEMORY);
3765 }
3766}
3767
3768void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3769{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003770 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003771}
3772
3773void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3774{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003775 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 +00003776
3777 try
3778 {
3779 switch (face)
3780 {
3781 case GL_FRONT:
3782 case GL_BACK:
3783 case GL_FRONT_AND_BACK:
3784 break;
3785 default:
3786 return error(GL_INVALID_ENUM);
3787 }
3788
3789 switch (func)
3790 {
3791 case GL_NEVER:
3792 case GL_ALWAYS:
3793 case GL_LESS:
3794 case GL_LEQUAL:
3795 case GL_EQUAL:
3796 case GL_GEQUAL:
3797 case GL_GREATER:
3798 case GL_NOTEQUAL:
3799 break;
3800 default:
3801 return error(GL_INVALID_ENUM);
3802 }
3803
3804 gl::Context *context = gl::getContext();
3805
3806 if (context)
3807 {
3808 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3809 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003810 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003811 }
3812
3813 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3814 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003815 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003816 }
3817 }
3818 }
3819 catch(std::bad_alloc&)
3820 {
3821 return error(GL_OUT_OF_MEMORY);
3822 }
3823}
3824
3825void __stdcall glStencilMask(GLuint mask)
3826{
3827 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3828}
3829
3830void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3831{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003832 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003833
3834 try
3835 {
3836 switch (face)
3837 {
3838 case GL_FRONT:
3839 case GL_BACK:
3840 case GL_FRONT_AND_BACK:
3841 break;
3842 default:
3843 return error(GL_INVALID_ENUM);
3844 }
3845
3846 gl::Context *context = gl::getContext();
3847
3848 if (context)
3849 {
3850 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3851 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003852 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003853 }
3854
3855 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3856 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003857 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003858 }
3859 }
3860 }
3861 catch(std::bad_alloc&)
3862 {
3863 return error(GL_OUT_OF_MEMORY);
3864 }
3865}
3866
3867void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3868{
3869 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3870}
3871
3872void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3873{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003874 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3875 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003876
3877 try
3878 {
3879 switch (face)
3880 {
3881 case GL_FRONT:
3882 case GL_BACK:
3883 case GL_FRONT_AND_BACK:
3884 break;
3885 default:
3886 return error(GL_INVALID_ENUM);
3887 }
3888
3889 switch (fail)
3890 {
3891 case GL_ZERO:
3892 case GL_KEEP:
3893 case GL_REPLACE:
3894 case GL_INCR:
3895 case GL_DECR:
3896 case GL_INVERT:
3897 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003898 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003899 break;
3900 default:
3901 return error(GL_INVALID_ENUM);
3902 }
3903
3904 switch (zfail)
3905 {
3906 case GL_ZERO:
3907 case GL_KEEP:
3908 case GL_REPLACE:
3909 case GL_INCR:
3910 case GL_DECR:
3911 case GL_INVERT:
3912 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003913 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003914 break;
3915 default:
3916 return error(GL_INVALID_ENUM);
3917 }
3918
3919 switch (zpass)
3920 {
3921 case GL_ZERO:
3922 case GL_KEEP:
3923 case GL_REPLACE:
3924 case GL_INCR:
3925 case GL_DECR:
3926 case GL_INVERT:
3927 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003928 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003929 break;
3930 default:
3931 return error(GL_INVALID_ENUM);
3932 }
3933
3934 gl::Context *context = gl::getContext();
3935
3936 if (context)
3937 {
3938 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3939 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003940 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003941 }
3942
3943 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3944 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003945 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003946 }
3947 }
3948 }
3949 catch(std::bad_alloc&)
3950 {
3951 return error(GL_OUT_OF_MEMORY);
3952 }
3953}
3954
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003955void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3956 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003957{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003958 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 +00003959 "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 +00003960 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003961
3962 try
3963 {
3964 if (level < 0 || width < 0 || height < 0)
3965 {
3966 return error(GL_INVALID_VALUE);
3967 }
3968
3969 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3970 {
3971 return error(GL_INVALID_VALUE);
3972 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003973
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003974 switch (target)
3975 {
3976 case GL_TEXTURE_2D:
3977 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3978 {
3979 return error(GL_INVALID_VALUE);
3980 }
3981 break;
3982 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3983 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3984 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3985 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3986 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3987 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00003988 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003989 {
3990 return error(GL_INVALID_VALUE);
3991 }
3992
3993 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3994 {
3995 return error(GL_INVALID_VALUE);
3996 }
3997 break;
3998 default:
3999 return error(GL_INVALID_ENUM);
4000 }
4001
4002 if (internalformat != format)
4003 {
4004 return error(GL_INVALID_OPERATION);
4005 }
4006
4007 switch (internalformat)
4008 {
4009 case GL_ALPHA:
4010 case GL_LUMINANCE:
4011 case GL_LUMINANCE_ALPHA:
4012 switch (type)
4013 {
4014 case GL_UNSIGNED_BYTE:
4015 break;
4016 default:
4017 return error(GL_INVALID_ENUM);
4018 }
4019 break;
4020 case GL_RGB:
4021 switch (type)
4022 {
4023 case GL_UNSIGNED_BYTE:
4024 case GL_UNSIGNED_SHORT_5_6_5:
4025 break;
4026 default:
4027 return error(GL_INVALID_ENUM);
4028 }
4029 break;
4030 case GL_RGBA:
4031 switch (type)
4032 {
4033 case GL_UNSIGNED_BYTE:
4034 case GL_UNSIGNED_SHORT_4_4_4_4:
4035 case GL_UNSIGNED_SHORT_5_5_5_1:
4036 break;
4037 default:
4038 return error(GL_INVALID_ENUM);
4039 }
4040 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004041 case GL_BGRA_EXT:
4042 switch (type)
4043 {
4044 case GL_UNSIGNED_BYTE:
4045 break;
4046 default:
4047 return error(GL_INVALID_ENUM);
4048 }
4049 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004050 default:
4051 return error(GL_INVALID_VALUE);
4052 }
4053
4054 if (border != 0)
4055 {
4056 return error(GL_INVALID_VALUE);
4057 }
4058
4059 gl::Context *context = gl::getContext();
4060
4061 if (context)
4062 {
4063 if (target == GL_TEXTURE_2D)
4064 {
4065 gl::Texture2D *texture = context->getTexture2D();
4066
4067 if (!texture)
4068 {
4069 return error(GL_INVALID_OPERATION);
4070 }
4071
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004072 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004073 }
4074 else
4075 {
4076 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4077
4078 if (!texture)
4079 {
4080 return error(GL_INVALID_OPERATION);
4081 }
4082
4083 switch (target)
4084 {
4085 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004086 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004087 break;
4088 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004089 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004090 break;
4091 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004092 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004093 break;
4094 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004095 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004096 break;
4097 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004098 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004099 break;
4100 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004101 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004102 break;
4103 default: UNREACHABLE();
4104 }
4105 }
4106 }
4107 }
4108 catch(std::bad_alloc&)
4109 {
4110 return error(GL_OUT_OF_MEMORY);
4111 }
4112}
4113
4114void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4115{
4116 glTexParameteri(target, pname, (GLint)param);
4117}
4118
4119void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4120{
4121 glTexParameteri(target, pname, (GLint)*params);
4122}
4123
4124void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4125{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004126 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004127
4128 try
4129 {
4130 gl::Context *context = gl::getContext();
4131
4132 if (context)
4133 {
4134 gl::Texture *texture;
4135
4136 switch (target)
4137 {
4138 case GL_TEXTURE_2D:
4139 texture = context->getTexture2D();
4140 break;
4141 case GL_TEXTURE_CUBE_MAP:
4142 texture = context->getTextureCubeMap();
4143 break;
4144 default:
4145 return error(GL_INVALID_ENUM);
4146 }
4147
4148 switch (pname)
4149 {
4150 case GL_TEXTURE_WRAP_S:
4151 if (!texture->setWrapS((GLenum)param))
4152 {
4153 return error(GL_INVALID_ENUM);
4154 }
4155 break;
4156 case GL_TEXTURE_WRAP_T:
4157 if (!texture->setWrapT((GLenum)param))
4158 {
4159 return error(GL_INVALID_ENUM);
4160 }
4161 break;
4162 case GL_TEXTURE_MIN_FILTER:
4163 if (!texture->setMinFilter((GLenum)param))
4164 {
4165 return error(GL_INVALID_ENUM);
4166 }
4167 break;
4168 case GL_TEXTURE_MAG_FILTER:
4169 if (!texture->setMagFilter((GLenum)param))
4170 {
4171 return error(GL_INVALID_ENUM);
4172 }
4173 break;
4174 default:
4175 return error(GL_INVALID_ENUM);
4176 }
4177 }
4178 }
4179 catch(std::bad_alloc&)
4180 {
4181 return error(GL_OUT_OF_MEMORY);
4182 }
4183}
4184
4185void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4186{
4187 glTexParameteri(target, pname, *params);
4188}
4189
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004190void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4191 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004192{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004193 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4194 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004195 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004196 target, level, xoffset, yoffset, width, height, format, type, pixels);
4197
4198 try
4199 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004200 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004201 {
4202 return error(GL_INVALID_ENUM);
4203 }
4204
4205 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004206 {
4207 return error(GL_INVALID_VALUE);
4208 }
4209
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004210 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4211 {
4212 return error(GL_INVALID_VALUE);
4213 }
4214
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004215 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004216 {
4217 return error(GL_INVALID_ENUM);
4218 }
4219
4220 if (width == 0 || height == 0 || pixels == NULL)
4221 {
4222 return;
4223 }
4224
4225 gl::Context *context = gl::getContext();
4226
4227 if (context)
4228 {
4229 if (target == GL_TEXTURE_2D)
4230 {
4231 gl::Texture2D *texture = context->getTexture2D();
4232
4233 if (!texture)
4234 {
4235 return error(GL_INVALID_OPERATION);
4236 }
4237
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004238 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004239 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004240 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004241 {
4242 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4243
4244 if (!texture)
4245 {
4246 return error(GL_INVALID_OPERATION);
4247 }
4248
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004249 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004250 }
4251 else
4252 {
4253 UNREACHABLE();
4254 }
4255 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004256 }
4257 catch(std::bad_alloc&)
4258 {
4259 return error(GL_OUT_OF_MEMORY);
4260 }
4261}
4262
4263void __stdcall glUniform1f(GLint location, GLfloat x)
4264{
4265 glUniform1fv(location, 1, &x);
4266}
4267
4268void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4269{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004270 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004271
4272 try
4273 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004274 if (count < 0)
4275 {
4276 return error(GL_INVALID_VALUE);
4277 }
4278
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004279 if (location == -1)
4280 {
4281 return;
4282 }
4283
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004284 gl::Context *context = gl::getContext();
4285
4286 if (context)
4287 {
4288 gl::Program *program = context->getCurrentProgram();
4289
4290 if (!program)
4291 {
4292 return error(GL_INVALID_OPERATION);
4293 }
4294
4295 if (!program->setUniform1fv(location, count, v))
4296 {
4297 return error(GL_INVALID_OPERATION);
4298 }
4299 }
4300 }
4301 catch(std::bad_alloc&)
4302 {
4303 return error(GL_OUT_OF_MEMORY);
4304 }
4305}
4306
4307void __stdcall glUniform1i(GLint location, GLint x)
4308{
4309 glUniform1iv(location, 1, &x);
4310}
4311
4312void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4313{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004314 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004315
4316 try
4317 {
4318 if (count < 0)
4319 {
4320 return error(GL_INVALID_VALUE);
4321 }
4322
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004323 if (location == -1)
4324 {
4325 return;
4326 }
4327
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004328 gl::Context *context = gl::getContext();
4329
4330 if (context)
4331 {
4332 gl::Program *program = context->getCurrentProgram();
4333
4334 if (!program)
4335 {
4336 return error(GL_INVALID_OPERATION);
4337 }
4338
4339 if (!program->setUniform1iv(location, count, v))
4340 {
4341 return error(GL_INVALID_OPERATION);
4342 }
4343 }
4344 }
4345 catch(std::bad_alloc&)
4346 {
4347 return error(GL_OUT_OF_MEMORY);
4348 }
4349}
4350
4351void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4352{
4353 GLfloat xy[2] = {x, y};
4354
4355 glUniform2fv(location, 1, (GLfloat*)&xy);
4356}
4357
4358void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4359{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004360 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004361
4362 try
4363 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004364 if (count < 0)
4365 {
4366 return error(GL_INVALID_VALUE);
4367 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004368
4369 if (location == -1)
4370 {
4371 return;
4372 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004373
4374 gl::Context *context = gl::getContext();
4375
4376 if (context)
4377 {
4378 gl::Program *program = context->getCurrentProgram();
4379
4380 if (!program)
4381 {
4382 return error(GL_INVALID_OPERATION);
4383 }
4384
4385 if (!program->setUniform2fv(location, count, v))
4386 {
4387 return error(GL_INVALID_OPERATION);
4388 }
4389 }
4390 }
4391 catch(std::bad_alloc&)
4392 {
4393 return error(GL_OUT_OF_MEMORY);
4394 }
4395}
4396
4397void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4398{
4399 GLint xy[4] = {x, y};
4400
4401 glUniform2iv(location, 1, (GLint*)&xy);
4402}
4403
4404void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4405{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004406 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004407
4408 try
4409 {
4410 if (count < 0)
4411 {
4412 return error(GL_INVALID_VALUE);
4413 }
4414
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004415 if (location == -1)
4416 {
4417 return;
4418 }
4419
4420 gl::Context *context = gl::getContext();
4421
4422 if (context)
4423 {
4424 gl::Program *program = context->getCurrentProgram();
4425
4426 if (!program)
4427 {
4428 return error(GL_INVALID_OPERATION);
4429 }
4430
4431 if (!program->setUniform2iv(location, count, v))
4432 {
4433 return error(GL_INVALID_OPERATION);
4434 }
4435 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004436 }
4437 catch(std::bad_alloc&)
4438 {
4439 return error(GL_OUT_OF_MEMORY);
4440 }
4441}
4442
4443void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4444{
4445 GLfloat xyz[3] = {x, y, z};
4446
4447 glUniform3fv(location, 1, (GLfloat*)&xyz);
4448}
4449
4450void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4451{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004452 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004453
4454 try
4455 {
4456 if (count < 0)
4457 {
4458 return error(GL_INVALID_VALUE);
4459 }
4460
4461 if (location == -1)
4462 {
4463 return;
4464 }
4465
4466 gl::Context *context = gl::getContext();
4467
4468 if (context)
4469 {
4470 gl::Program *program = context->getCurrentProgram();
4471
4472 if (!program)
4473 {
4474 return error(GL_INVALID_OPERATION);
4475 }
4476
4477 if (!program->setUniform3fv(location, count, v))
4478 {
4479 return error(GL_INVALID_OPERATION);
4480 }
4481 }
4482 }
4483 catch(std::bad_alloc&)
4484 {
4485 return error(GL_OUT_OF_MEMORY);
4486 }
4487}
4488
4489void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4490{
4491 GLint xyz[3] = {x, y, z};
4492
4493 glUniform3iv(location, 1, (GLint*)&xyz);
4494}
4495
4496void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4497{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004498 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004499
4500 try
4501 {
4502 if (count < 0)
4503 {
4504 return error(GL_INVALID_VALUE);
4505 }
4506
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004507 if (location == -1)
4508 {
4509 return;
4510 }
4511
4512 gl::Context *context = gl::getContext();
4513
4514 if (context)
4515 {
4516 gl::Program *program = context->getCurrentProgram();
4517
4518 if (!program)
4519 {
4520 return error(GL_INVALID_OPERATION);
4521 }
4522
4523 if (!program->setUniform3iv(location, count, v))
4524 {
4525 return error(GL_INVALID_OPERATION);
4526 }
4527 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004528 }
4529 catch(std::bad_alloc&)
4530 {
4531 return error(GL_OUT_OF_MEMORY);
4532 }
4533}
4534
4535void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4536{
4537 GLfloat xyzw[4] = {x, y, z, w};
4538
4539 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4540}
4541
4542void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4543{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004544 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004545
4546 try
4547 {
4548 if (count < 0)
4549 {
4550 return error(GL_INVALID_VALUE);
4551 }
4552
4553 if (location == -1)
4554 {
4555 return;
4556 }
4557
4558 gl::Context *context = gl::getContext();
4559
4560 if (context)
4561 {
4562 gl::Program *program = context->getCurrentProgram();
4563
4564 if (!program)
4565 {
4566 return error(GL_INVALID_OPERATION);
4567 }
4568
4569 if (!program->setUniform4fv(location, count, v))
4570 {
4571 return error(GL_INVALID_OPERATION);
4572 }
4573 }
4574 }
4575 catch(std::bad_alloc&)
4576 {
4577 return error(GL_OUT_OF_MEMORY);
4578 }
4579}
4580
4581void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4582{
4583 GLint xyzw[4] = {x, y, z, w};
4584
4585 glUniform4iv(location, 1, (GLint*)&xyzw);
4586}
4587
4588void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4589{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004590 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004591
4592 try
4593 {
4594 if (count < 0)
4595 {
4596 return error(GL_INVALID_VALUE);
4597 }
4598
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004599 if (location == -1)
4600 {
4601 return;
4602 }
4603
4604 gl::Context *context = gl::getContext();
4605
4606 if (context)
4607 {
4608 gl::Program *program = context->getCurrentProgram();
4609
4610 if (!program)
4611 {
4612 return error(GL_INVALID_OPERATION);
4613 }
4614
4615 if (!program->setUniform4iv(location, count, v))
4616 {
4617 return error(GL_INVALID_OPERATION);
4618 }
4619 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004620 }
4621 catch(std::bad_alloc&)
4622 {
4623 return error(GL_OUT_OF_MEMORY);
4624 }
4625}
4626
4627void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4628{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004629 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4630 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004631
4632 try
4633 {
4634 if (count < 0 || transpose != GL_FALSE)
4635 {
4636 return error(GL_INVALID_VALUE);
4637 }
4638
4639 if (location == -1)
4640 {
4641 return;
4642 }
4643
4644 gl::Context *context = gl::getContext();
4645
4646 if (context)
4647 {
4648 gl::Program *program = context->getCurrentProgram();
4649
4650 if (!program)
4651 {
4652 return error(GL_INVALID_OPERATION);
4653 }
4654
4655 if (!program->setUniformMatrix2fv(location, count, value))
4656 {
4657 return error(GL_INVALID_OPERATION);
4658 }
4659 }
4660 }
4661 catch(std::bad_alloc&)
4662 {
4663 return error(GL_OUT_OF_MEMORY);
4664 }
4665}
4666
4667void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4668{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004669 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4670 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004671
4672 try
4673 {
4674 if (count < 0 || transpose != GL_FALSE)
4675 {
4676 return error(GL_INVALID_VALUE);
4677 }
4678
4679 if (location == -1)
4680 {
4681 return;
4682 }
4683
4684 gl::Context *context = gl::getContext();
4685
4686 if (context)
4687 {
4688 gl::Program *program = context->getCurrentProgram();
4689
4690 if (!program)
4691 {
4692 return error(GL_INVALID_OPERATION);
4693 }
4694
4695 if (!program->setUniformMatrix3fv(location, count, value))
4696 {
4697 return error(GL_INVALID_OPERATION);
4698 }
4699 }
4700 }
4701 catch(std::bad_alloc&)
4702 {
4703 return error(GL_OUT_OF_MEMORY);
4704 }
4705}
4706
4707void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4708{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004709 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4710 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004711
4712 try
4713 {
4714 if (count < 0 || transpose != GL_FALSE)
4715 {
4716 return error(GL_INVALID_VALUE);
4717 }
4718
4719 if (location == -1)
4720 {
4721 return;
4722 }
4723
4724 gl::Context *context = gl::getContext();
4725
4726 if (context)
4727 {
4728 gl::Program *program = context->getCurrentProgram();
4729
4730 if (!program)
4731 {
4732 return error(GL_INVALID_OPERATION);
4733 }
4734
4735 if (!program->setUniformMatrix4fv(location, count, value))
4736 {
4737 return error(GL_INVALID_OPERATION);
4738 }
4739 }
4740 }
4741 catch(std::bad_alloc&)
4742 {
4743 return error(GL_OUT_OF_MEMORY);
4744 }
4745}
4746
4747void __stdcall glUseProgram(GLuint program)
4748{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004749 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004750
4751 try
4752 {
4753 gl::Context *context = gl::getContext();
4754
4755 if (context)
4756 {
4757 gl::Program *programObject = context->getProgram(program);
4758
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004759 if (!programObject && program != 0)
4760 {
4761 if (context->getShader(program))
4762 {
4763 return error(GL_INVALID_OPERATION);
4764 }
4765 else
4766 {
4767 return error(GL_INVALID_VALUE);
4768 }
4769 }
4770
4771 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004772 {
4773 return error(GL_INVALID_OPERATION);
4774 }
4775
4776 context->useProgram(program);
4777 }
4778 }
4779 catch(std::bad_alloc&)
4780 {
4781 return error(GL_OUT_OF_MEMORY);
4782 }
4783}
4784
4785void __stdcall glValidateProgram(GLuint program)
4786{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004787 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004788
4789 try
4790 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00004791 gl::Context *context = gl::getContext();
4792
4793 if (context)
4794 {
4795 gl::Program *programObject = context->getProgram(program);
4796
4797 if (!programObject)
4798 {
4799 if (context->getShader(program))
4800 {
4801 return error(GL_INVALID_OPERATION);
4802 }
4803 else
4804 {
4805 return error(GL_INVALID_VALUE);
4806 }
4807 }
4808
4809 programObject->validate();
4810 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004811 }
4812 catch(std::bad_alloc&)
4813 {
4814 return error(GL_OUT_OF_MEMORY);
4815 }
4816}
4817
4818void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4819{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004820 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004821
4822 try
4823 {
4824 if (index >= gl::MAX_VERTEX_ATTRIBS)
4825 {
4826 return error(GL_INVALID_VALUE);
4827 }
4828
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004829 gl::Context *context = gl::getContext();
4830
4831 if (context)
4832 {
4833 GLfloat vals[4] = { x, 0, 0, 1 };
4834 context->setVertexAttrib(index, vals);
4835 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004836 }
4837 catch(std::bad_alloc&)
4838 {
4839 return error(GL_OUT_OF_MEMORY);
4840 }
4841}
4842
4843void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4844{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004845 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004846
4847 try
4848 {
4849 if (index >= gl::MAX_VERTEX_ATTRIBS)
4850 {
4851 return error(GL_INVALID_VALUE);
4852 }
4853
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004854 gl::Context *context = gl::getContext();
4855
4856 if (context)
4857 {
4858 GLfloat vals[4] = { values[0], 0, 0, 1 };
4859 context->setVertexAttrib(index, vals);
4860 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004861 }
4862 catch(std::bad_alloc&)
4863 {
4864 return error(GL_OUT_OF_MEMORY);
4865 }
4866}
4867
4868void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4869{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004870 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004871
4872 try
4873 {
4874 if (index >= gl::MAX_VERTEX_ATTRIBS)
4875 {
4876 return error(GL_INVALID_VALUE);
4877 }
4878
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004879 gl::Context *context = gl::getContext();
4880
4881 if (context)
4882 {
4883 GLfloat vals[4] = { x, y, 0, 1 };
4884 context->setVertexAttrib(index, vals);
4885 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004886 }
4887 catch(std::bad_alloc&)
4888 {
4889 return error(GL_OUT_OF_MEMORY);
4890 }
4891}
4892
4893void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4894{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004895 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004896
4897 try
4898 {
4899 if (index >= gl::MAX_VERTEX_ATTRIBS)
4900 {
4901 return error(GL_INVALID_VALUE);
4902 }
4903
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004904 gl::Context *context = gl::getContext();
4905
4906 if (context)
4907 {
4908 GLfloat vals[4] = { values[0], values[1], 0, 1 };
4909 context->setVertexAttrib(index, vals);
4910 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004911 }
4912 catch(std::bad_alloc&)
4913 {
4914 return error(GL_OUT_OF_MEMORY);
4915 }
4916}
4917
4918void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4919{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004920 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 +00004921
4922 try
4923 {
4924 if (index >= gl::MAX_VERTEX_ATTRIBS)
4925 {
4926 return error(GL_INVALID_VALUE);
4927 }
4928
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004929 gl::Context *context = gl::getContext();
4930
4931 if (context)
4932 {
4933 GLfloat vals[4] = { x, y, z, 1 };
4934 context->setVertexAttrib(index, vals);
4935 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004936 }
4937 catch(std::bad_alloc&)
4938 {
4939 return error(GL_OUT_OF_MEMORY);
4940 }
4941}
4942
4943void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4944{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004945 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004946
4947 try
4948 {
4949 if (index >= gl::MAX_VERTEX_ATTRIBS)
4950 {
4951 return error(GL_INVALID_VALUE);
4952 }
4953
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004954 gl::Context *context = gl::getContext();
4955
4956 if (context)
4957 {
4958 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
4959 context->setVertexAttrib(index, vals);
4960 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004961 }
4962 catch(std::bad_alloc&)
4963 {
4964 return error(GL_OUT_OF_MEMORY);
4965 }
4966}
4967
4968void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4969{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004970 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 +00004971
4972 try
4973 {
4974 if (index >= gl::MAX_VERTEX_ATTRIBS)
4975 {
4976 return error(GL_INVALID_VALUE);
4977 }
4978
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004979 gl::Context *context = gl::getContext();
4980
4981 if (context)
4982 {
4983 GLfloat vals[4] = { x, y, z, w };
4984 context->setVertexAttrib(index, vals);
4985 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004986 }
4987 catch(std::bad_alloc&)
4988 {
4989 return error(GL_OUT_OF_MEMORY);
4990 }
4991}
4992
4993void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4994{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004995 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004996
4997 try
4998 {
4999 if (index >= gl::MAX_VERTEX_ATTRIBS)
5000 {
5001 return error(GL_INVALID_VALUE);
5002 }
5003
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005004 gl::Context *context = gl::getContext();
5005
5006 if (context)
5007 {
5008 context->setVertexAttrib(index, values);
5009 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005010 }
5011 catch(std::bad_alloc&)
5012 {
5013 return error(GL_OUT_OF_MEMORY);
5014 }
5015}
5016
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005017void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005018{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005019 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005020 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005021 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005022
5023 try
5024 {
5025 if (index >= gl::MAX_VERTEX_ATTRIBS)
5026 {
5027 return error(GL_INVALID_VALUE);
5028 }
5029
5030 if (size < 1 || size > 4)
5031 {
5032 return error(GL_INVALID_VALUE);
5033 }
5034
5035 switch (type)
5036 {
5037 case GL_BYTE:
5038 case GL_UNSIGNED_BYTE:
5039 case GL_SHORT:
5040 case GL_UNSIGNED_SHORT:
5041 case GL_FIXED:
5042 case GL_FLOAT:
5043 break;
5044 default:
5045 return error(GL_INVALID_ENUM);
5046 }
5047
5048 if (stride < 0)
5049 {
5050 return error(GL_INVALID_VALUE);
5051 }
5052
5053 gl::Context *context = gl::getContext();
5054
5055 if (context)
5056 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005057 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005058 }
5059 }
5060 catch(std::bad_alloc&)
5061 {
5062 return error(GL_OUT_OF_MEMORY);
5063 }
5064}
5065
5066void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5067{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005068 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 +00005069
5070 try
5071 {
5072 if (width < 0 || height < 0)
5073 {
5074 return error(GL_INVALID_VALUE);
5075 }
5076
5077 gl::Context *context = gl::getContext();
5078
5079 if (context)
5080 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005081 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005082 }
5083 }
5084 catch(std::bad_alloc&)
5085 {
5086 return error(GL_OUT_OF_MEMORY);
5087 }
5088}
5089
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005090void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5091 GLbitfield mask, GLenum filter)
5092{
5093 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5094 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5095 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5096 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5097
5098 try
5099 {
5100 switch (filter)
5101 {
5102 case GL_NEAREST:
5103 break;
5104 default:
5105 return error(GL_INVALID_ENUM);
5106 }
5107
5108 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5109 {
5110 return error(GL_INVALID_VALUE);
5111 }
5112
5113 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5114 {
5115 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5116 return error(GL_INVALID_OPERATION);
5117 }
5118
5119 gl::Context *context = gl::getContext();
5120
5121 if (context)
5122 {
5123 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5124 {
5125 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5126 return error(GL_INVALID_OPERATION);
5127 }
5128
5129 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5130 }
5131 }
5132 catch(std::bad_alloc&)
5133 {
5134 return error(GL_OUT_OF_MEMORY);
5135 }
5136}
5137
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005138void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5139 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005140{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005141 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5142 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005143 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005144 target, level, internalformat, width, height, depth, border, format, type, pixels);
5145
5146 try
5147 {
5148 UNIMPLEMENTED(); // FIXME
5149 }
5150 catch(std::bad_alloc&)
5151 {
5152 return error(GL_OUT_OF_MEMORY);
5153 }
5154}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005155
5156__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5157{
5158 struct Extension
5159 {
5160 const char *name;
5161 __eglMustCastToProperFunctionPointerType address;
5162 };
5163
5164 static const Extension glExtensions[] =
5165 {
5166 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005167 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005168 };
5169
5170 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5171 {
5172 if (strcmp(procname, glExtensions[ext].name) == 0)
5173 {
5174 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5175 }
5176 }
5177
5178 return NULL;
5179}
5180
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005181}