blob: 2c231cb18b7fa4fc6d322be2921e29acf2960a8b [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8
9#define GL_APICALL
10#include <GLES2/gl2.h>
11#include <GLES2/gl2ext.h>
12
daniel@transgaming.com00c75962010-03-11 20:36:15 +000013#include <exception>
14#include <limits>
15
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000016#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000017
18#include "libGLESv2/main.h"
19#include "libGLESv2/mathutil.h"
20#include "libGLESv2/utilities.h"
21#include "libGLESv2/Buffer.h"
22#include "libGLESv2/Context.h"
23#include "libGLESv2/Framebuffer.h"
24#include "libGLESv2/Program.h"
25#include "libGLESv2/Renderbuffer.h"
26#include "libGLESv2/Shader.h"
27#include "libGLESv2/Texture.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000028
29extern "C"
30{
31
32void __stdcall glActiveTexture(GLenum texture)
33{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000034 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035
36 try
37 {
38 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
39 {
40 return error(GL_INVALID_ENUM);
41 }
42
43 gl::Context *context = gl::getContext();
44
45 if (context)
46 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +000047 context->setActiveSampler(texture - GL_TEXTURE0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000048 }
49 }
50 catch(std::bad_alloc&)
51 {
52 return error(GL_OUT_OF_MEMORY);
53 }
54}
55
56void __stdcall glAttachShader(GLuint program, GLuint shader)
57{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000058 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000059
60 try
61 {
62 gl::Context *context = gl::getContext();
63
64 if (context)
65 {
66 gl::Program *programObject = context->getProgram(program);
67 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000068
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000069 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000071 if (context->getShader(program))
72 {
73 return error(GL_INVALID_OPERATION);
74 }
75 else
76 {
77 return error(GL_INVALID_VALUE);
78 }
79 }
80
81 if (!shaderObject)
82 {
83 if (context->getProgram(shader))
84 {
85 return error(GL_INVALID_OPERATION);
86 }
87 else
88 {
89 return error(GL_INVALID_VALUE);
90 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000091 }
92
93 if (!programObject->attachShader(shaderObject))
94 {
95 return error(GL_INVALID_OPERATION);
96 }
97 }
98 }
99 catch(std::bad_alloc&)
100 {
101 return error(GL_OUT_OF_MEMORY);
102 }
103}
104
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000105void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000106{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000107 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108
109 try
110 {
111 if (index >= gl::MAX_VERTEX_ATTRIBS)
112 {
113 return error(GL_INVALID_VALUE);
114 }
115
116 gl::Context *context = gl::getContext();
117
118 if (context)
119 {
120 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000121
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000122 if (!programObject)
123 {
daniel@transgaming.com98079832010-04-13 03:26:29 +0000124 if (context->getShader(program))
125 {
126 return error(GL_INVALID_OPERATION);
127 }
128 else
129 {
130 return error(GL_INVALID_VALUE);
131 }
132 }
133
134 if (strncmp(name, "gl_", 3) == 0)
135 {
136 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137 }
138
139 programObject->bindAttributeLocation(index, name);
140 }
141 }
142 catch(std::bad_alloc&)
143 {
144 return error(GL_OUT_OF_MEMORY);
145 }
146}
147
148void __stdcall glBindBuffer(GLenum target, GLuint buffer)
149{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000150 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000151
152 try
153 {
154 gl::Context *context = gl::getContext();
155
156 if (context)
157 {
158 switch (target)
159 {
160 case GL_ARRAY_BUFFER:
161 context->bindArrayBuffer(buffer);
162 return;
163 case GL_ELEMENT_ARRAY_BUFFER:
164 context->bindElementArrayBuffer(buffer);
165 return;
166 default:
167 return error(GL_INVALID_ENUM);
168 }
169 }
170 }
171 catch(std::bad_alloc&)
172 {
173 return error(GL_OUT_OF_MEMORY);
174 }
175}
176
177void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
178{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000179 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000180
181 try
182 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000183 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000184 {
185 return error(GL_INVALID_ENUM);
186 }
187
188 gl::Context *context = gl::getContext();
189
190 if (context)
191 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000192 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
193 {
194 context->bindReadFramebuffer(framebuffer);
195 }
196
197 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
198 {
199 context->bindDrawFramebuffer(framebuffer);
200 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000201 }
202 }
203 catch(std::bad_alloc&)
204 {
205 return error(GL_OUT_OF_MEMORY);
206 }
207}
208
209void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
210{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000211 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000212
213 try
214 {
215 if (target != GL_RENDERBUFFER)
216 {
217 return error(GL_INVALID_ENUM);
218 }
219
220 gl::Context *context = gl::getContext();
221
222 if (context)
223 {
224 context->bindRenderbuffer(renderbuffer);
225 }
226 }
227 catch(std::bad_alloc&)
228 {
229 return error(GL_OUT_OF_MEMORY);
230 }
231}
232
233void __stdcall glBindTexture(GLenum target, GLuint texture)
234{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000235 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000236
237 try
238 {
239 gl::Context *context = gl::getContext();
240
241 if (context)
242 {
243 gl::Texture *textureObject = context->getTexture(texture);
244
245 if (textureObject && textureObject->getTarget() != target && texture != 0)
246 {
247 return error(GL_INVALID_OPERATION);
248 }
249
250 switch (target)
251 {
252 case GL_TEXTURE_2D:
253 context->bindTexture2D(texture);
254 return;
255 case GL_TEXTURE_CUBE_MAP:
256 context->bindTextureCubeMap(texture);
257 return;
258 default:
259 return error(GL_INVALID_ENUM);
260 }
261 }
262 }
263 catch(std::bad_alloc&)
264 {
265 return error(GL_OUT_OF_MEMORY);
266 }
267}
268
269void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
270{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000271 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
272 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000273
274 try
275 {
276 gl::Context* context = gl::getContext();
277
278 if (context)
279 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000280 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000281 }
282 }
283 catch(std::bad_alloc&)
284 {
285 return error(GL_OUT_OF_MEMORY);
286 }
287}
288
289void __stdcall glBlendEquation(GLenum mode)
290{
291 glBlendEquationSeparate(mode, mode);
292}
293
294void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
295{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000296 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000297
298 try
299 {
300 switch (modeRGB)
301 {
302 case GL_FUNC_ADD:
303 case GL_FUNC_SUBTRACT:
304 case GL_FUNC_REVERSE_SUBTRACT:
305 break;
306 default:
307 return error(GL_INVALID_ENUM);
308 }
309
310 switch (modeAlpha)
311 {
312 case GL_FUNC_ADD:
313 case GL_FUNC_SUBTRACT:
314 case GL_FUNC_REVERSE_SUBTRACT:
315 break;
316 default:
317 return error(GL_INVALID_ENUM);
318 }
319
320 gl::Context *context = gl::getContext();
321
322 if (context)
323 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000324 context->setBlendEquation(modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000325 }
326 }
327 catch(std::bad_alloc&)
328 {
329 return error(GL_OUT_OF_MEMORY);
330 }
331}
332
333void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
334{
335 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
336}
337
338void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
339{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000340 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
341 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000342
343 try
344 {
345 switch (srcRGB)
346 {
347 case GL_ZERO:
348 case GL_ONE:
349 case GL_SRC_COLOR:
350 case GL_ONE_MINUS_SRC_COLOR:
351 case GL_DST_COLOR:
352 case GL_ONE_MINUS_DST_COLOR:
353 case GL_SRC_ALPHA:
354 case GL_ONE_MINUS_SRC_ALPHA:
355 case GL_DST_ALPHA:
356 case GL_ONE_MINUS_DST_ALPHA:
357 case GL_CONSTANT_COLOR:
358 case GL_ONE_MINUS_CONSTANT_COLOR:
359 case GL_CONSTANT_ALPHA:
360 case GL_ONE_MINUS_CONSTANT_ALPHA:
361 case GL_SRC_ALPHA_SATURATE:
362 break;
363 default:
364 return error(GL_INVALID_ENUM);
365 }
366
367 switch (dstRGB)
368 {
369 case GL_ZERO:
370 case GL_ONE:
371 case GL_SRC_COLOR:
372 case GL_ONE_MINUS_SRC_COLOR:
373 case GL_DST_COLOR:
374 case GL_ONE_MINUS_DST_COLOR:
375 case GL_SRC_ALPHA:
376 case GL_ONE_MINUS_SRC_ALPHA:
377 case GL_DST_ALPHA:
378 case GL_ONE_MINUS_DST_ALPHA:
379 case GL_CONSTANT_COLOR:
380 case GL_ONE_MINUS_CONSTANT_COLOR:
381 case GL_CONSTANT_ALPHA:
382 case GL_ONE_MINUS_CONSTANT_ALPHA:
383 break;
384 default:
385 return error(GL_INVALID_ENUM);
386 }
387
388 switch (srcAlpha)
389 {
390 case GL_ZERO:
391 case GL_ONE:
392 case GL_SRC_COLOR:
393 case GL_ONE_MINUS_SRC_COLOR:
394 case GL_DST_COLOR:
395 case GL_ONE_MINUS_DST_COLOR:
396 case GL_SRC_ALPHA:
397 case GL_ONE_MINUS_SRC_ALPHA:
398 case GL_DST_ALPHA:
399 case GL_ONE_MINUS_DST_ALPHA:
400 case GL_CONSTANT_COLOR:
401 case GL_ONE_MINUS_CONSTANT_COLOR:
402 case GL_CONSTANT_ALPHA:
403 case GL_ONE_MINUS_CONSTANT_ALPHA:
404 case GL_SRC_ALPHA_SATURATE:
405 break;
406 default:
407 return error(GL_INVALID_ENUM);
408 }
409
410 switch (dstAlpha)
411 {
412 case GL_ZERO:
413 case GL_ONE:
414 case GL_SRC_COLOR:
415 case GL_ONE_MINUS_SRC_COLOR:
416 case GL_DST_COLOR:
417 case GL_ONE_MINUS_DST_COLOR:
418 case GL_SRC_ALPHA:
419 case GL_ONE_MINUS_SRC_ALPHA:
420 case GL_DST_ALPHA:
421 case GL_ONE_MINUS_DST_ALPHA:
422 case GL_CONSTANT_COLOR:
423 case GL_ONE_MINUS_CONSTANT_COLOR:
424 case GL_CONSTANT_ALPHA:
425 case GL_ONE_MINUS_CONSTANT_ALPHA:
426 break;
427 default:
428 return error(GL_INVALID_ENUM);
429 }
430
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000431 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
432 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
433
434 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
435 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
436
437 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000438 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000439 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
440 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000441 }
442
443 gl::Context *context = gl::getContext();
444
445 if (context)
446 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +0000447 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000448 }
449 }
450 catch(std::bad_alloc&)
451 {
452 return error(GL_OUT_OF_MEMORY);
453 }
454}
455
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000456void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000457{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000458 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000459 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000460
461 try
462 {
463 if (size < 0)
464 {
465 return error(GL_INVALID_VALUE);
466 }
467
468 switch (usage)
469 {
470 case GL_STREAM_DRAW:
471 case GL_STATIC_DRAW:
472 case GL_DYNAMIC_DRAW:
473 break;
474 default:
475 return error(GL_INVALID_ENUM);
476 }
477
478 gl::Context *context = gl::getContext();
479
480 if (context)
481 {
482 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000483
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000484 switch (target)
485 {
486 case GL_ARRAY_BUFFER:
487 buffer = context->getArrayBuffer();
488 break;
489 case GL_ELEMENT_ARRAY_BUFFER:
490 buffer = context->getElementArrayBuffer();
491 break;
492 default:
493 return error(GL_INVALID_ENUM);
494 }
495
496 if (!buffer)
497 {
498 return error(GL_INVALID_OPERATION);
499 }
500
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000501 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000502 }
503 }
504 catch(std::bad_alloc&)
505 {
506 return error(GL_OUT_OF_MEMORY);
507 }
508}
509
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000510void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000511{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000512 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000513 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000514
515 try
516 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000517 if (size < 0 || offset < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000518 {
519 return error(GL_INVALID_VALUE);
520 }
521
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000522 if (data == NULL)
523 {
524 return;
525 }
526
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000527 gl::Context *context = gl::getContext();
528
529 if (context)
530 {
531 gl::Buffer *buffer;
532
533 switch (target)
534 {
535 case GL_ARRAY_BUFFER:
536 buffer = context->getArrayBuffer();
537 break;
538 case GL_ELEMENT_ARRAY_BUFFER:
539 buffer = context->getElementArrayBuffer();
540 break;
541 default:
542 return error(GL_INVALID_ENUM);
543 }
544
545 if (!buffer)
546 {
547 return error(GL_INVALID_OPERATION);
548 }
549
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000550 if ((size_t)size + offset > buffer->size())
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000551 {
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000552 return error(GL_INVALID_VALUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000553 }
daniel@transgaming.comdefa1c32010-05-18 18:51:45 +0000554
555 buffer->bufferSubData(data, size, offset);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000556 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000557 }
558 catch(std::bad_alloc&)
559 {
560 return error(GL_OUT_OF_MEMORY);
561 }
562}
563
564GLenum __stdcall glCheckFramebufferStatus(GLenum target)
565{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000566 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000567
568 try
569 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000570 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000571 {
572 return error(GL_INVALID_ENUM, 0);
573 }
574
575 gl::Context *context = gl::getContext();
576
577 if (context)
578 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000579 gl::Framebuffer *framebuffer = NULL;
580 if (target == GL_READ_FRAMEBUFFER_ANGLE)
581 {
582 framebuffer = context->getReadFramebuffer();
583 }
584 else
585 {
586 framebuffer = context->getDrawFramebuffer();
587 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000588
589 return framebuffer->completeness();
590 }
591 }
592 catch(std::bad_alloc&)
593 {
594 return error(GL_OUT_OF_MEMORY, 0);
595 }
596
597 return 0;
598}
599
600void __stdcall glClear(GLbitfield mask)
601{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000602 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000603
604 try
605 {
606 gl::Context *context = gl::getContext();
607
608 if (context)
609 {
610 context->clear(mask);
611 }
612 }
613 catch(std::bad_alloc&)
614 {
615 return error(GL_OUT_OF_MEMORY);
616 }
617}
618
619void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
620{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000621 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
622 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000623
624 try
625 {
626 gl::Context *context = gl::getContext();
627
628 if (context)
629 {
630 context->setClearColor(red, green, blue, alpha);
631 }
632 }
633 catch(std::bad_alloc&)
634 {
635 return error(GL_OUT_OF_MEMORY);
636 }
637}
638
639void __stdcall glClearDepthf(GLclampf depth)
640{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000641 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000642
643 try
644 {
645 gl::Context *context = gl::getContext();
646
647 if (context)
648 {
649 context->setClearDepth(depth);
650 }
651 }
652 catch(std::bad_alloc&)
653 {
654 return error(GL_OUT_OF_MEMORY);
655 }
656}
657
658void __stdcall glClearStencil(GLint s)
659{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000660 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000661
662 try
663 {
664 gl::Context *context = gl::getContext();
665
666 if (context)
667 {
668 context->setClearStencil(s);
669 }
670 }
671 catch(std::bad_alloc&)
672 {
673 return error(GL_OUT_OF_MEMORY);
674 }
675}
676
677void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
678{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000679 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
680 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000681
682 try
683 {
684 gl::Context *context = gl::getContext();
685
686 if (context)
687 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +0000688 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000689 }
690 }
691 catch(std::bad_alloc&)
692 {
693 return error(GL_OUT_OF_MEMORY);
694 }
695}
696
697void __stdcall glCompileShader(GLuint shader)
698{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000699 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000700
701 try
702 {
703 gl::Context *context = gl::getContext();
704
705 if (context)
706 {
707 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000708
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000709 if (!shaderObject)
710 {
daniel@transgaming.com0cefaf42010-04-13 03:26:36 +0000711 if (context->getProgram(shader))
712 {
713 return error(GL_INVALID_OPERATION);
714 }
715 else
716 {
717 return error(GL_INVALID_VALUE);
718 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000719 }
720
721 shaderObject->compile();
722 }
723 }
724 catch(std::bad_alloc&)
725 {
726 return error(GL_OUT_OF_MEMORY);
727 }
728}
729
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000730void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
731 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000732{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000733 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000734 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000735 target, level, internalformat, width, height, border, imageSize, data);
736
737 try
738 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000739 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000740 {
741 return error(GL_INVALID_ENUM);
742 }
743
744 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000745 {
746 return error(GL_INVALID_VALUE);
747 }
748
daniel@transgaming.com41430492010-03-11 20:36:18 +0000749 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
750 {
751 return error(GL_INVALID_VALUE);
752 }
753
754 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000755 }
756 catch(std::bad_alloc&)
757 {
758 return error(GL_OUT_OF_MEMORY);
759 }
760}
761
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000762void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
763 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000764{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000765 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
766 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000767 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000768 target, level, xoffset, yoffset, width, height, format, imageSize, data);
769
770 try
771 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000772 if (!gl::IsTextureTarget(target))
daniel@transgaming.com41430492010-03-11 20:36:18 +0000773 {
774 return error(GL_INVALID_ENUM);
775 }
776
777 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000778 {
779 return error(GL_INVALID_VALUE);
780 }
781
daniel@transgaming.com41430492010-03-11 20:36:18 +0000782 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
783 {
784 return error(GL_INVALID_VALUE);
785 }
786
787 if (xoffset != 0 || yoffset != 0)
788 {
789 return error(GL_INVALID_OPERATION);
790 }
791
792 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000793 }
794 catch(std::bad_alloc&)
795 {
796 return error(GL_OUT_OF_MEMORY);
797 }
798}
799
800void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
801{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000802 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
803 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000804 target, level, internalformat, x, y, width, height, border);
805
806 try
807 {
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000808 if (level < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000809 {
810 return error(GL_INVALID_VALUE);
811 }
812
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000813 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
814 {
815 return error(GL_INVALID_VALUE);
816 }
817
818 switch (target)
819 {
820 case GL_TEXTURE_2D:
821 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
822 {
823 return error(GL_INVALID_VALUE);
824 }
825 break;
826 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
827 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
828 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
829 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
830 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
831 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +0000832 if (width != height)
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000833 {
834 return error(GL_INVALID_VALUE);
835 }
836
837 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
838 {
839 return error(GL_INVALID_VALUE);
840 }
841 break;
842 default:
843 return error(GL_INVALID_ENUM);
844 }
845
846 switch (internalformat)
847 {
848 case GL_ALPHA:
849 case GL_LUMINANCE:
850 case GL_LUMINANCE_ALPHA:
851 case GL_RGB:
852 case GL_RGBA:
853 break;
854 default:
855 return error(GL_INVALID_VALUE);
856 }
857
858 if (border != 0)
859 {
860 return error(GL_INVALID_VALUE);
861 }
862
863 gl::Context *context = gl::getContext();
864
865 if (context)
866 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000867 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +0000868 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
869 {
870 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
871 }
872
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000873 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
874 {
875 return error(GL_INVALID_OPERATION);
876 }
877
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000878 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000879 if (target == GL_TEXTURE_2D)
880 {
881 gl::Texture2D *texture = context->getTexture2D();
882
883 if (!texture)
884 {
885 return error(GL_INVALID_OPERATION);
886 }
887
888 texture->copyImage(level, internalformat, x, y, width, height, source);
889 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000890 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000891 {
892 gl::TextureCubeMap *texture = context->getTextureCubeMap();
893
894 if (!texture)
895 {
896 return error(GL_INVALID_OPERATION);
897 }
898
899 texture->copyImage(target, level, internalformat, x, y, width, height, source);
900 }
901 else
902 {
903 UNREACHABLE();
904 }
905 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000906 }
907 catch(std::bad_alloc&)
908 {
909 return error(GL_OUT_OF_MEMORY);
910 }
911}
912
913void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
914{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000915 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
916 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000917 target, level, xoffset, yoffset, x, y, width, height);
918
919 try
920 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000921 if (!gl::IsTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000922 {
923 return error(GL_INVALID_ENUM);
924 }
925
926 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000927 {
928 return error(GL_INVALID_VALUE);
929 }
930
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000931 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
932 {
933 return error(GL_INVALID_VALUE);
934 }
935
936 if (width == 0 || height == 0)
937 {
938 return;
939 }
940
941 gl::Context *context = gl::getContext();
942
943 if (context)
944 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +0000945 gl::Framebuffer *framebuffer = context->getReadFramebuffer();
daniel@transgaming.combbc57792010-07-28 19:21:05 +0000946 if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
947 {
948 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
949 }
950
daniel@transgaming.com1f135d82010-08-24 19:20:36 +0000951 if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
952 {
953 return error(GL_INVALID_OPERATION);
954 }
955
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +0000956 gl::Colorbuffer *source = framebuffer->getColorbuffer();
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000957 if (target == GL_TEXTURE_2D)
958 {
959 gl::Texture2D *texture = context->getTexture2D();
960
961 if (!texture)
962 {
963 return error(GL_INVALID_OPERATION);
964 }
965
966 texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
967 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +0000968 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000969 {
970 gl::TextureCubeMap *texture = context->getTextureCubeMap();
971
972 if (!texture)
973 {
974 return error(GL_INVALID_OPERATION);
975 }
976
977 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
978 }
979 else
980 {
981 UNREACHABLE();
982 }
983 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000984 }
daniel@transgaming.comb8c28ed2010-04-13 03:26:32 +0000985
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000986 catch(std::bad_alloc&)
987 {
988 return error(GL_OUT_OF_MEMORY);
989 }
990}
991
992GLuint __stdcall glCreateProgram(void)
993{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000994 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000995
996 try
997 {
998 gl::Context *context = gl::getContext();
999
1000 if (context)
1001 {
1002 return context->createProgram();
1003 }
1004 }
1005 catch(std::bad_alloc&)
1006 {
1007 return error(GL_OUT_OF_MEMORY, 0);
1008 }
1009
1010 return 0;
1011}
1012
1013GLuint __stdcall glCreateShader(GLenum type)
1014{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001015 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001016
1017 try
1018 {
1019 gl::Context *context = gl::getContext();
1020
1021 if (context)
1022 {
1023 switch (type)
1024 {
1025 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001026 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001027 return context->createShader(type);
1028 default:
1029 return error(GL_INVALID_ENUM, 0);
1030 }
1031 }
1032 }
1033 catch(std::bad_alloc&)
1034 {
1035 return error(GL_OUT_OF_MEMORY, 0);
1036 }
1037
1038 return 0;
1039}
1040
1041void __stdcall glCullFace(GLenum mode)
1042{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001043 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001044
1045 try
1046 {
1047 switch (mode)
1048 {
1049 case GL_FRONT:
1050 case GL_BACK:
1051 case GL_FRONT_AND_BACK:
1052 {
1053 gl::Context *context = gl::getContext();
1054
1055 if (context)
1056 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001057 context->setCullMode(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001058 }
1059 }
1060 break;
1061 default:
1062 return error(GL_INVALID_ENUM);
1063 }
1064 }
1065 catch(std::bad_alloc&)
1066 {
1067 return error(GL_OUT_OF_MEMORY);
1068 }
1069}
1070
1071void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1072{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001073 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001074
1075 try
1076 {
1077 if (n < 0)
1078 {
1079 return error(GL_INVALID_VALUE);
1080 }
1081
1082 gl::Context *context = gl::getContext();
1083
1084 if (context)
1085 {
1086 for (int i = 0; i < n; i++)
1087 {
1088 context->deleteBuffer(buffers[i]);
1089 }
1090 }
1091 }
1092 catch(std::bad_alloc&)
1093 {
1094 return error(GL_OUT_OF_MEMORY);
1095 }
1096}
1097
1098void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1099{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001100 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001101
1102 try
1103 {
1104 if (n < 0)
1105 {
1106 return error(GL_INVALID_VALUE);
1107 }
1108
1109 gl::Context *context = gl::getContext();
1110
1111 if (context)
1112 {
1113 for (int i = 0; i < n; i++)
1114 {
1115 if (framebuffers[i] != 0)
1116 {
1117 context->deleteFramebuffer(framebuffers[i]);
1118 }
1119 }
1120 }
1121 }
1122 catch(std::bad_alloc&)
1123 {
1124 return error(GL_OUT_OF_MEMORY);
1125 }
1126}
1127
1128void __stdcall glDeleteProgram(GLuint program)
1129{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001130 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001131
1132 try
1133 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001134 if (program == 0)
1135 {
1136 return;
1137 }
1138
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001139 gl::Context *context = gl::getContext();
1140
1141 if (context)
1142 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001143 if (!context->getProgram(program))
1144 {
1145 if(context->getShader(program))
1146 {
1147 return error(GL_INVALID_OPERATION);
1148 }
1149 else
1150 {
1151 return error(GL_INVALID_VALUE);
1152 }
1153 }
1154
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001155 context->deleteProgram(program);
1156 }
1157 }
1158 catch(std::bad_alloc&)
1159 {
1160 return error(GL_OUT_OF_MEMORY);
1161 }
1162}
1163
1164void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1165{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001166 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001167
1168 try
1169 {
1170 if (n < 0)
1171 {
1172 return error(GL_INVALID_VALUE);
1173 }
1174
1175 gl::Context *context = gl::getContext();
1176
1177 if (context)
1178 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +00001179 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001180 {
1181 context->deleteRenderbuffer(renderbuffers[i]);
1182 }
1183 }
1184 }
1185 catch(std::bad_alloc&)
1186 {
1187 return error(GL_OUT_OF_MEMORY);
1188 }
1189}
1190
1191void __stdcall glDeleteShader(GLuint shader)
1192{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001193 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001194
1195 try
1196 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001197 if (shader == 0)
1198 {
1199 return;
1200 }
1201
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001202 gl::Context *context = gl::getContext();
1203
1204 if (context)
1205 {
daniel@transgaming.com75401e62010-04-13 03:26:39 +00001206 if (!context->getShader(shader))
1207 {
1208 if(context->getProgram(shader))
1209 {
1210 return error(GL_INVALID_OPERATION);
1211 }
1212 else
1213 {
1214 return error(GL_INVALID_VALUE);
1215 }
1216 }
1217
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001218 context->deleteShader(shader);
1219 }
1220 }
1221 catch(std::bad_alloc&)
1222 {
1223 return error(GL_OUT_OF_MEMORY);
1224 }
1225}
1226
1227void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1228{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001229 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001230
1231 try
1232 {
1233 if (n < 0)
1234 {
1235 return error(GL_INVALID_VALUE);
1236 }
1237
1238 gl::Context *context = gl::getContext();
1239
1240 if (context)
1241 {
1242 for (int i = 0; i < n; i++)
1243 {
1244 if (textures[i] != 0)
1245 {
1246 context->deleteTexture(textures[i]);
1247 }
1248 }
1249 }
1250 }
1251 catch(std::bad_alloc&)
1252 {
1253 return error(GL_OUT_OF_MEMORY);
1254 }
1255}
1256
1257void __stdcall glDepthFunc(GLenum func)
1258{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001259 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001260
1261 try
1262 {
1263 switch (func)
1264 {
1265 case GL_NEVER:
1266 case GL_ALWAYS:
1267 case GL_LESS:
1268 case GL_LEQUAL:
1269 case GL_EQUAL:
1270 case GL_GREATER:
1271 case GL_GEQUAL:
1272 case GL_NOTEQUAL:
1273 break;
1274 default:
1275 return error(GL_INVALID_ENUM);
1276 }
1277
1278 gl::Context *context = gl::getContext();
1279
1280 if (context)
1281 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001282 context->setDepthFunc(func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001283 }
1284 }
1285 catch(std::bad_alloc&)
1286 {
1287 return error(GL_OUT_OF_MEMORY);
1288 }
1289}
1290
1291void __stdcall glDepthMask(GLboolean flag)
1292{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001293 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001294
1295 try
1296 {
1297 gl::Context *context = gl::getContext();
1298
1299 if (context)
1300 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001301 context->setDepthMask(flag != GL_FALSE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001302 }
1303 }
1304 catch(std::bad_alloc&)
1305 {
1306 return error(GL_OUT_OF_MEMORY);
1307 }
1308}
1309
1310void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1311{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001312 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001313
1314 try
1315 {
1316 gl::Context *context = gl::getContext();
1317
1318 if (context)
1319 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001320 context->setDepthRange(zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001321 }
1322 }
1323 catch(std::bad_alloc&)
1324 {
1325 return error(GL_OUT_OF_MEMORY);
1326 }
1327}
1328
1329void __stdcall glDetachShader(GLuint program, GLuint shader)
1330{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001331 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001332
1333 try
1334 {
1335 gl::Context *context = gl::getContext();
1336
1337 if (context)
1338 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001339
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001340 gl::Program *programObject = context->getProgram(program);
1341 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001342
1343 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001344 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001345 gl::Shader *shaderByProgramHandle;
1346 shaderByProgramHandle = context->getShader(program);
1347 if (!shaderByProgramHandle)
1348 {
1349 return error(GL_INVALID_VALUE);
1350 }
1351 else
1352 {
1353 return error(GL_INVALID_OPERATION);
1354 }
1355 }
1356
1357 if (!shaderObject)
1358 {
1359 gl::Program *programByShaderHandle = context->getProgram(shader);
1360 if (!programByShaderHandle)
1361 {
1362 return error(GL_INVALID_VALUE);
1363 }
1364 else
1365 {
1366 return error(GL_INVALID_OPERATION);
1367 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001368 }
1369
1370 if (!programObject->detachShader(shaderObject))
1371 {
1372 return error(GL_INVALID_OPERATION);
1373 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001374 }
1375 }
1376 catch(std::bad_alloc&)
1377 {
1378 return error(GL_OUT_OF_MEMORY);
1379 }
1380}
1381
1382void __stdcall glDisable(GLenum cap)
1383{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001384 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001385
1386 try
1387 {
1388 gl::Context *context = gl::getContext();
1389
1390 if (context)
1391 {
1392 switch (cap)
1393 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001394 case GL_CULL_FACE: context->setCullFace(false); break;
1395 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break;
1396 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1397 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break;
1398 case GL_SCISSOR_TEST: context->setScissorTest(false); break;
1399 case GL_STENCIL_TEST: context->setStencilTest(false); break;
1400 case GL_DEPTH_TEST: context->setDepthTest(false); break;
1401 case GL_BLEND: context->setBlend(false); break;
1402 case GL_DITHER: context->setDither(false); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001403 default:
1404 return error(GL_INVALID_ENUM);
1405 }
1406 }
1407 }
1408 catch(std::bad_alloc&)
1409 {
1410 return error(GL_OUT_OF_MEMORY);
1411 }
1412}
1413
1414void __stdcall glDisableVertexAttribArray(GLuint index)
1415{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001416 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001417
1418 try
1419 {
1420 if (index >= gl::MAX_VERTEX_ATTRIBS)
1421 {
1422 return error(GL_INVALID_VALUE);
1423 }
1424
1425 gl::Context *context = gl::getContext();
1426
1427 if (context)
1428 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001429 context->setVertexAttribEnabled(index, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001430 }
1431 }
1432 catch(std::bad_alloc&)
1433 {
1434 return error(GL_OUT_OF_MEMORY);
1435 }
1436}
1437
1438void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1439{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001440 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001441
1442 try
1443 {
1444 if (count < 0 || first < 0)
1445 {
1446 return error(GL_INVALID_VALUE);
1447 }
1448
1449 gl::Context *context = gl::getContext();
1450
1451 if (context)
1452 {
1453 context->drawArrays(mode, first, count);
1454 }
1455 }
1456 catch(std::bad_alloc&)
1457 {
1458 return error(GL_OUT_OF_MEMORY);
1459 }
1460}
1461
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001462void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001463{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001464 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001465 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001466
1467 try
1468 {
1469 if (count < 0)
1470 {
1471 return error(GL_INVALID_VALUE);
1472 }
1473
1474 switch (type)
1475 {
1476 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001477 case GL_UNSIGNED_SHORT:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00001478 case GL_UNSIGNED_INT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001479 break;
1480 default:
1481 return error(GL_INVALID_ENUM);
1482 }
1483
1484 gl::Context *context = gl::getContext();
1485
1486 if (context)
1487 {
1488 context->drawElements(mode, count, type, indices);
1489 }
1490 }
1491 catch(std::bad_alloc&)
1492 {
1493 return error(GL_OUT_OF_MEMORY);
1494 }
1495}
1496
1497void __stdcall glEnable(GLenum cap)
1498{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001499 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001500
1501 try
1502 {
1503 gl::Context *context = gl::getContext();
1504
1505 if (context)
1506 {
1507 switch (cap)
1508 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001509 case GL_CULL_FACE: context->setCullFace(true); break;
1510 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break;
1511 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1512 case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break;
1513 case GL_SCISSOR_TEST: context->setScissorTest(true); break;
1514 case GL_STENCIL_TEST: context->setStencilTest(true); break;
1515 case GL_DEPTH_TEST: context->setDepthTest(true); break;
1516 case GL_BLEND: context->setBlend(true); break;
1517 case GL_DITHER: context->setDither(true); break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001518 default:
1519 return error(GL_INVALID_ENUM);
1520 }
1521 }
1522 }
1523 catch(std::bad_alloc&)
1524 {
1525 return error(GL_OUT_OF_MEMORY);
1526 }
1527}
1528
1529void __stdcall glEnableVertexAttribArray(GLuint index)
1530{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001531 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001532
1533 try
1534 {
1535 if (index >= gl::MAX_VERTEX_ATTRIBS)
1536 {
1537 return error(GL_INVALID_VALUE);
1538 }
1539
1540 gl::Context *context = gl::getContext();
1541
1542 if (context)
1543 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001544 context->setVertexAttribEnabled(index, true);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001545 }
1546 }
1547 catch(std::bad_alloc&)
1548 {
1549 return error(GL_OUT_OF_MEMORY);
1550 }
1551}
1552
1553void __stdcall glFinish(void)
1554{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001555 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001556
1557 try
1558 {
1559 gl::Context *context = gl::getContext();
1560
1561 if (context)
1562 {
1563 context->finish();
1564 }
1565 }
1566 catch(std::bad_alloc&)
1567 {
1568 return error(GL_OUT_OF_MEMORY);
1569 }
1570}
1571
1572void __stdcall glFlush(void)
1573{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001574 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001575
1576 try
1577 {
1578 gl::Context *context = gl::getContext();
1579
1580 if (context)
1581 {
1582 context->flush();
1583 }
1584 }
1585 catch(std::bad_alloc&)
1586 {
1587 return error(GL_OUT_OF_MEMORY);
1588 }
1589}
1590
1591void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1592{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001593 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1594 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001595
1596 try
1597 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001598 if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1599 || renderbuffertarget != GL_RENDERBUFFER)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001600 {
1601 return error(GL_INVALID_ENUM);
1602 }
1603
1604 gl::Context *context = gl::getContext();
1605
1606 if (context)
1607 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001608 gl::Framebuffer *framebuffer = NULL;
1609 GLuint framebufferHandle = 0;
1610 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1611 {
1612 framebuffer = context->getReadFramebuffer();
1613 framebufferHandle = context->getReadFramebufferHandle();
1614 }
1615 else
1616 {
1617 framebuffer = context->getDrawFramebuffer();
1618 framebufferHandle = context->getDrawFramebufferHandle();
1619 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001620
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001621 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001622 {
1623 return error(GL_INVALID_OPERATION);
1624 }
1625
1626 switch (attachment)
1627 {
1628 case GL_COLOR_ATTACHMENT0:
1629 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1630 break;
1631 case GL_DEPTH_ATTACHMENT:
1632 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1633 break;
1634 case GL_STENCIL_ATTACHMENT:
1635 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1636 break;
1637 default:
1638 return error(GL_INVALID_ENUM);
1639 }
1640 }
1641 }
1642 catch(std::bad_alloc&)
1643 {
1644 return error(GL_OUT_OF_MEMORY);
1645 }
1646}
1647
1648void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1649{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001650 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1651 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001652
1653 try
1654 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001655 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001656 {
1657 return error(GL_INVALID_ENUM);
1658 }
1659
1660 switch (attachment)
1661 {
1662 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001663 case GL_DEPTH_ATTACHMENT:
1664 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001665 break;
1666 default:
1667 return error(GL_INVALID_ENUM);
1668 }
1669
1670 gl::Context *context = gl::getContext();
1671
1672 if (context)
1673 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001674 if (texture == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001675 {
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001676 textarget = GL_NONE;
1677 }
1678 else
1679 {
1680 gl::Texture *tex = context->getTexture(texture);
1681
1682 if (tex == NULL)
1683 {
1684 return error(GL_INVALID_OPERATION);
1685 }
1686
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001687 switch (textarget)
1688 {
1689 case GL_TEXTURE_2D:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001690 if (tex->getTarget() != GL_TEXTURE_2D)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001691 {
1692 return error(GL_INVALID_OPERATION);
1693 }
1694 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001695
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001696 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001697 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001698 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001699 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001700 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001701 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001702 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
1703 {
1704 return error(GL_INVALID_OPERATION);
1705 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001706 break;
daniel@transgaming.com93a81472010-04-20 18:52:58 +00001707
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001708 default:
1709 return error(GL_INVALID_ENUM);
1710 }
1711
1712 if (level != 0)
1713 {
1714 return error(GL_INVALID_VALUE);
1715 }
1716 }
1717
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001718 gl::Framebuffer *framebuffer = NULL;
1719 GLuint framebufferHandle = 0;
1720 if (target == GL_READ_FRAMEBUFFER_ANGLE)
1721 {
1722 framebuffer = context->getReadFramebuffer();
1723 framebufferHandle = context->getReadFramebufferHandle();
1724 }
1725 else
1726 {
1727 framebuffer = context->getDrawFramebuffer();
1728 framebufferHandle = context->getDrawFramebufferHandle();
1729 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001730
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00001731 if (framebufferHandle == 0 || !framebuffer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001732 {
1733 return error(GL_INVALID_OPERATION);
1734 }
1735
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00001736 switch (attachment)
1737 {
1738 case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
1739 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
1740 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
1741 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001742 }
1743 }
1744 catch(std::bad_alloc&)
1745 {
1746 return error(GL_OUT_OF_MEMORY);
1747 }
1748}
1749
1750void __stdcall glFrontFace(GLenum mode)
1751{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001752 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001753
1754 try
1755 {
1756 switch (mode)
1757 {
1758 case GL_CW:
1759 case GL_CCW:
1760 {
1761 gl::Context *context = gl::getContext();
1762
1763 if (context)
1764 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00001765 context->setFrontFace(mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001766 }
1767 }
1768 break;
1769 default:
1770 return error(GL_INVALID_ENUM);
1771 }
1772 }
1773 catch(std::bad_alloc&)
1774 {
1775 return error(GL_OUT_OF_MEMORY);
1776 }
1777}
1778
1779void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1780{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001781 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001782
1783 try
1784 {
1785 if (n < 0)
1786 {
1787 return error(GL_INVALID_VALUE);
1788 }
1789
1790 gl::Context *context = gl::getContext();
1791
1792 if (context)
1793 {
1794 for (int i = 0; i < n; i++)
1795 {
1796 buffers[i] = context->createBuffer();
1797 }
1798 }
1799 }
1800 catch(std::bad_alloc&)
1801 {
1802 return error(GL_OUT_OF_MEMORY);
1803 }
1804}
1805
1806void __stdcall glGenerateMipmap(GLenum target)
1807{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001808 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001809
1810 try
1811 {
daniel@transgaming.com8fd99e22010-04-20 18:52:00 +00001812 gl::Context *context = gl::getContext();
1813
1814 if (context)
1815 {
1816 gl::Texture *texture;
1817
1818 switch (target)
1819 {
1820 case GL_TEXTURE_2D:
1821 texture = context->getTexture2D();
1822 break;
1823
1824 case GL_TEXTURE_CUBE_MAP:
1825 texture = context->getTextureCubeMap();
1826 break;
1827
1828 default:
1829 return error(GL_INVALID_ENUM);
1830 }
1831
1832 texture->generateMipmaps();
1833 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001834 }
1835 catch(std::bad_alloc&)
1836 {
1837 return error(GL_OUT_OF_MEMORY);
1838 }
1839}
1840
1841void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1842{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001843 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001844
1845 try
1846 {
1847 if (n < 0)
1848 {
1849 return error(GL_INVALID_VALUE);
1850 }
1851
1852 gl::Context *context = gl::getContext();
1853
1854 if (context)
1855 {
1856 for (int i = 0; i < n; i++)
1857 {
1858 framebuffers[i] = context->createFramebuffer();
1859 }
1860 }
1861 }
1862 catch(std::bad_alloc&)
1863 {
1864 return error(GL_OUT_OF_MEMORY);
1865 }
1866}
1867
1868void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1869{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001870 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001871
1872 try
1873 {
1874 if (n < 0)
1875 {
1876 return error(GL_INVALID_VALUE);
1877 }
1878
1879 gl::Context *context = gl::getContext();
1880
1881 if (context)
1882 {
1883 for (int i = 0; i < n; i++)
1884 {
1885 renderbuffers[i] = context->createRenderbuffer();
1886 }
1887 }
1888 }
1889 catch(std::bad_alloc&)
1890 {
1891 return error(GL_OUT_OF_MEMORY);
1892 }
1893}
1894
1895void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1896{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001897 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001898
1899 try
1900 {
1901 if (n < 0)
1902 {
1903 return error(GL_INVALID_VALUE);
1904 }
1905
1906 gl::Context *context = gl::getContext();
1907
1908 if (context)
1909 {
1910 for (int i = 0; i < n; i++)
1911 {
1912 textures[i] = context->createTexture();
1913 }
1914 }
1915 }
1916 catch(std::bad_alloc&)
1917 {
1918 return error(GL_OUT_OF_MEMORY);
1919 }
1920}
1921
daniel@transgaming.com85423182010-04-22 13:35:27 +00001922void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001923{
daniel@transgaming.com85423182010-04-22 13:35:27 +00001924 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
1925 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001926 program, index, bufsize, length, size, type, name);
1927
1928 try
1929 {
1930 if (bufsize < 0)
1931 {
1932 return error(GL_INVALID_VALUE);
1933 }
1934
daniel@transgaming.com85423182010-04-22 13:35:27 +00001935 gl::Context *context = gl::getContext();
1936
1937 if (context)
1938 {
1939 gl::Program *programObject = context->getProgram(program);
1940
1941 if (!programObject)
1942 {
1943 if (context->getShader(program))
1944 {
1945 return error(GL_INVALID_OPERATION);
1946 }
1947 else
1948 {
1949 return error(GL_INVALID_VALUE);
1950 }
1951 }
1952
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001953 if (index >= (GLuint)programObject->getActiveAttributeCount())
daniel@transgaming.com85423182010-04-22 13:35:27 +00001954 {
1955 return error(GL_INVALID_VALUE);
1956 }
1957
1958 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
1959 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001960 }
1961 catch(std::bad_alloc&)
1962 {
1963 return error(GL_OUT_OF_MEMORY);
1964 }
1965}
1966
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001967void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001968{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001969 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001970 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001971 program, index, bufsize, length, size, type, name);
1972
1973 try
1974 {
1975 if (bufsize < 0)
1976 {
1977 return error(GL_INVALID_VALUE);
1978 }
1979
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00001980 gl::Context *context = gl::getContext();
1981
1982 if (context)
1983 {
1984 gl::Program *programObject = context->getProgram(program);
1985
1986 if (!programObject)
1987 {
1988 if (context->getShader(program))
1989 {
1990 return error(GL_INVALID_OPERATION);
1991 }
1992 else
1993 {
1994 return error(GL_INVALID_VALUE);
1995 }
1996 }
1997
1998 if (index >= (GLuint)programObject->getActiveUniformCount())
1999 {
2000 return error(GL_INVALID_VALUE);
2001 }
2002
2003 programObject->getActiveUniform(index, bufsize, length, size, type, name);
2004 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002005 }
2006 catch(std::bad_alloc&)
2007 {
2008 return error(GL_OUT_OF_MEMORY);
2009 }
2010}
2011
2012void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2013{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002014 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2015 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002016
2017 try
2018 {
2019 if (maxcount < 0)
2020 {
2021 return error(GL_INVALID_VALUE);
2022 }
2023
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002024 gl::Context *context = gl::getContext();
2025
2026 if (context)
2027 {
2028 gl::Program *programObject = context->getProgram(program);
2029
2030 if (!programObject)
2031 {
daniel@transgaming.com23953e32010-04-13 19:53:31 +00002032 if (context->getShader(program))
2033 {
2034 return error(GL_INVALID_OPERATION);
2035 }
2036 else
2037 {
2038 return error(GL_INVALID_VALUE);
2039 }
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002040 }
2041
2042 return programObject->getAttachedShaders(maxcount, count, shaders);
2043 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002044 }
2045 catch(std::bad_alloc&)
2046 {
2047 return error(GL_OUT_OF_MEMORY);
2048 }
2049}
2050
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002051int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002052{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002053 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002054
2055 try
2056 {
2057 gl::Context *context = gl::getContext();
2058
2059 if (context)
2060 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002061
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002062 gl::Program *programObject = context->getProgram(program);
2063
2064 if (!programObject)
2065 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00002066 if (context->getShader(program))
2067 {
2068 return error(GL_INVALID_OPERATION, -1);
2069 }
2070 else
2071 {
2072 return error(GL_INVALID_VALUE, -1);
2073 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002074 }
2075
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00002076 if (!programObject->isLinked())
2077 {
2078 return error(GL_INVALID_OPERATION, -1);
2079 }
2080
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002081 return programObject->getAttributeLocation(name);
2082 }
2083 }
2084 catch(std::bad_alloc&)
2085 {
2086 return error(GL_OUT_OF_MEMORY, -1);
2087 }
2088
2089 return -1;
2090}
2091
2092void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2093{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002094 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002095
2096 try
2097 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002098 gl::Context *context = gl::getContext();
2099
2100 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002101 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002102 if (!(context->getBooleanv(pname, params)))
2103 {
2104 GLenum nativeType;
2105 unsigned int numParams = 0;
2106 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2107 return error(GL_INVALID_ENUM);
2108
2109 if (numParams == 0)
2110 return; // it is known that the pname is valid, but there are no parameters to return
2111
2112 if (nativeType == GL_FLOAT)
2113 {
2114 GLfloat *floatParams = NULL;
2115 floatParams = new GLfloat[numParams];
2116
2117 context->getFloatv(pname, floatParams);
2118
2119 for (unsigned int i = 0; i < numParams; ++i)
2120 {
2121 if (floatParams[i] == 0.0f)
2122 params[i] = GL_FALSE;
2123 else
2124 params[i] = GL_TRUE;
2125 }
2126
2127 delete [] floatParams;
2128 }
2129 else if (nativeType == GL_INT)
2130 {
2131 GLint *intParams = NULL;
2132 intParams = new GLint[numParams];
2133
2134 context->getIntegerv(pname, intParams);
2135
2136 for (unsigned int i = 0; i < numParams; ++i)
2137 {
2138 if (intParams[i] == 0)
2139 params[i] = GL_FALSE;
2140 else
2141 params[i] = GL_TRUE;
2142 }
2143
2144 delete [] intParams;
2145 }
2146 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002147 }
2148 }
2149 catch(std::bad_alloc&)
2150 {
2151 return error(GL_OUT_OF_MEMORY);
2152 }
2153}
2154
2155void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2156{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002157 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002158
2159 try
2160 {
daniel@transgaming.comaa0ccbd2010-04-15 20:45:05 +00002161 gl::Context *context = gl::getContext();
2162
2163 if (context)
2164 {
2165 gl::Buffer *buffer;
2166
2167 switch (target)
2168 {
2169 case GL_ARRAY_BUFFER:
2170 buffer = context->getArrayBuffer();
2171 break;
2172 case GL_ELEMENT_ARRAY_BUFFER:
2173 buffer = context->getElementArrayBuffer();
2174 break;
2175 default: return error(GL_INVALID_ENUM);
2176 }
2177
2178 if (!buffer)
2179 {
2180 // A null buffer means that "0" is bound to the requested buffer target
2181 return error(GL_INVALID_OPERATION);
2182 }
2183
2184 switch (pname)
2185 {
2186 case GL_BUFFER_USAGE:
2187 *params = buffer->usage();
2188 break;
2189 case GL_BUFFER_SIZE:
2190 *params = buffer->size();
2191 break;
2192 default: return error(GL_INVALID_ENUM);
2193 }
2194 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002195 }
2196 catch(std::bad_alloc&)
2197 {
2198 return error(GL_OUT_OF_MEMORY);
2199 }
2200}
2201
2202GLenum __stdcall glGetError(void)
2203{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002204 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002205
2206 gl::Context *context = gl::getContext();
2207
2208 if (context)
2209 {
2210 return context->getError();
2211 }
2212
2213 return GL_NO_ERROR;
2214}
2215
2216void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2217{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002218 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002219
2220 try
2221 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002222 gl::Context *context = gl::getContext();
2223
2224 if (context)
2225 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002226 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002227 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002228 GLenum nativeType;
2229 unsigned int numParams = 0;
2230 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2231 return error(GL_INVALID_ENUM);
2232
2233 if (numParams == 0)
2234 return; // it is known that the pname is valid, but that there are no parameters to return.
2235
2236 if (nativeType == GL_BOOL)
2237 {
2238 GLboolean *boolParams = NULL;
2239 boolParams = new GLboolean[numParams];
2240
2241 context->getBooleanv(pname, boolParams);
2242
2243 for (unsigned int i = 0; i < numParams; ++i)
2244 {
2245 if (boolParams[i] == GL_FALSE)
2246 params[i] = 0.0f;
2247 else
2248 params[i] = 1.0f;
2249 }
2250
2251 delete [] boolParams;
2252 }
2253 else if (nativeType == GL_INT)
2254 {
2255 GLint *intParams = NULL;
2256 intParams = new GLint[numParams];
2257
2258 context->getIntegerv(pname, intParams);
2259
2260 for (unsigned int i = 0; i < numParams; ++i)
2261 {
2262 params[i] = (GLfloat)intParams[i];
2263 }
2264
2265 delete [] intParams;
2266 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002267 }
2268 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002269 }
2270 catch(std::bad_alloc&)
2271 {
2272 return error(GL_OUT_OF_MEMORY);
2273 }
2274}
2275
2276void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2277{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002278 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2279 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002280
2281 try
2282 {
2283 gl::Context *context = gl::getContext();
2284
2285 if (context)
2286 {
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002287 if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002288 {
2289 return error(GL_INVALID_ENUM);
2290 }
2291
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002292 gl::Framebuffer *framebuffer = NULL;
2293 if (target == GL_READ_FRAMEBUFFER_ANGLE)
2294 {
2295 if(context->getReadFramebufferHandle() == 0)
2296 {
2297 return error(GL_INVALID_OPERATION);
2298 }
2299
2300 framebuffer = context->getReadFramebuffer();
2301 }
2302 else
2303 {
2304 if (context->getDrawFramebufferHandle() == 0)
2305 {
2306 return error(GL_INVALID_OPERATION);
2307 }
2308
2309 framebuffer = context->getDrawFramebuffer();
2310 }
2311
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002312 GLenum attachmentType;
2313 GLuint attachmentHandle;
2314 switch (attachment)
2315 {
2316 case GL_COLOR_ATTACHMENT0:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002317 attachmentType = framebuffer->getColorbufferType();
2318 attachmentHandle = framebuffer->getColorbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002319 break;
2320 case GL_DEPTH_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002321 attachmentType = framebuffer->getDepthbufferType();
2322 attachmentHandle = framebuffer->getDepthbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002323 break;
2324 case GL_STENCIL_ATTACHMENT:
daniel@transgaming.coma27ff1e2010-08-24 19:20:11 +00002325 attachmentType = framebuffer->getStencilbufferType();
2326 attachmentHandle = framebuffer->getStencilbufferHandle();
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002327 break;
2328 default: return error(GL_INVALID_ENUM);
2329 }
2330
2331 GLenum attachmentObjectType; // Type category
daniel@transgaming.comfbc09532010-04-26 15:33:41 +00002332 if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002333 {
2334 attachmentObjectType = attachmentType;
2335 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002336 else if (gl::IsTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002337 {
2338 attachmentObjectType = GL_TEXTURE;
2339 }
2340 else UNREACHABLE();
2341
2342 switch (pname)
2343 {
2344 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2345 *params = attachmentObjectType;
2346 break;
2347 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2348 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2349 {
2350 *params = attachmentHandle;
2351 }
2352 else
2353 {
2354 return error(GL_INVALID_ENUM);
2355 }
2356 break;
2357 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2358 if (attachmentObjectType == GL_TEXTURE)
2359 {
2360 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2361 }
2362 else
2363 {
2364 return error(GL_INVALID_ENUM);
2365 }
2366 break;
2367 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2368 if (attachmentObjectType == GL_TEXTURE)
2369 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00002370 if (gl::IsCubemapTextureTarget(attachmentType))
daniel@transgaming.comc46c9c02010-04-23 18:34:55 +00002371 {
2372 *params = attachmentType;
2373 }
2374 else
2375 {
2376 *params = 0;
2377 }
2378 }
2379 else
2380 {
2381 return error(GL_INVALID_ENUM);
2382 }
2383 break;
2384 default:
2385 return error(GL_INVALID_ENUM);
2386 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002387 }
2388 }
2389 catch(std::bad_alloc&)
2390 {
2391 return error(GL_OUT_OF_MEMORY);
2392 }
2393}
2394
2395void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2396{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002397 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002398
2399 try
2400 {
2401 gl::Context *context = gl::getContext();
2402
2403 if (context)
2404 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002405 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002406 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002407 GLenum nativeType;
2408 unsigned int numParams = 0;
2409 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2410 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002411
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002412 if (numParams == 0)
2413 return; // it is known that pname is valid, but there are no parameters to return
2414
2415 if (nativeType == GL_BOOL)
2416 {
2417 GLboolean *boolParams = NULL;
2418 boolParams = new GLboolean[numParams];
2419
2420 context->getBooleanv(pname, boolParams);
2421
2422 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002423 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002424 if (boolParams[i] == GL_FALSE)
2425 params[i] = 0;
2426 else
2427 params[i] = 1;
2428 }
2429
2430 delete [] boolParams;
2431 }
2432 else if (nativeType == GL_FLOAT)
2433 {
2434 GLfloat *floatParams = NULL;
2435 floatParams = new GLfloat[numParams];
2436
2437 context->getFloatv(pname, floatParams);
2438
2439 for (unsigned int i = 0; i < numParams; ++i)
2440 {
daniel@transgaming.comc1641352010-04-26 15:33:36 +00002441 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002442 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002443 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002444 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002445 else
2446 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002447 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002448
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002449 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002450 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002451 }
2452 }
2453 }
2454 catch(std::bad_alloc&)
2455 {
2456 return error(GL_OUT_OF_MEMORY);
2457 }
2458}
2459
2460void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2461{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002462 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002463
2464 try
2465 {
2466 gl::Context *context = gl::getContext();
2467
2468 if (context)
2469 {
2470 gl::Program *programObject = context->getProgram(program);
2471
2472 if (!programObject)
2473 {
2474 return error(GL_INVALID_VALUE);
2475 }
2476
2477 switch (pname)
2478 {
2479 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002480 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002481 return;
2482 case GL_LINK_STATUS:
2483 *params = programObject->isLinked();
2484 return;
2485 case GL_VALIDATE_STATUS:
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00002486 *params = programObject->isValidated();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002487 return;
2488 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002489 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002490 return;
2491 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002492 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002493 return;
2494 case GL_ACTIVE_ATTRIBUTES:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002495 *params = programObject->getActiveAttributeCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002496 return;
2497 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
daniel@transgaming.com85423182010-04-22 13:35:27 +00002498 *params = programObject->getActiveAttributeMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002499 return;
2500 case GL_ACTIVE_UNIFORMS:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002501 *params = programObject->getActiveUniformCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002502 return;
2503 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
daniel@transgaming.com09fbfef2010-04-22 13:35:31 +00002504 *params = programObject->getActiveUniformMaxLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002505 return;
2506 default:
2507 return error(GL_INVALID_ENUM);
2508 }
2509 }
2510 }
2511 catch(std::bad_alloc&)
2512 {
2513 return error(GL_OUT_OF_MEMORY);
2514 }
2515}
2516
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002517void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002518{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002519 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002520 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002521
2522 try
2523 {
2524 if (bufsize < 0)
2525 {
2526 return error(GL_INVALID_VALUE);
2527 }
2528
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002529 gl::Context *context = gl::getContext();
2530
2531 if (context)
2532 {
2533 gl::Program *programObject = context->getProgram(program);
2534
2535 if (!programObject)
2536 {
2537 return error(GL_INVALID_VALUE);
2538 }
2539
2540 programObject->getInfoLog(bufsize, length, infolog);
2541 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002542 }
2543 catch(std::bad_alloc&)
2544 {
2545 return error(GL_OUT_OF_MEMORY);
2546 }
2547}
2548
2549void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2550{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002551 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002552
2553 try
2554 {
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002555 gl::Context *context = gl::getContext();
2556
2557 if (context)
2558 {
2559 if (target != GL_RENDERBUFFER)
2560 {
2561 return error(GL_INVALID_ENUM);
2562 }
2563
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002564 if (context->getRenderbufferHandle() == 0)
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002565 {
2566 return error(GL_INVALID_OPERATION);
2567 }
2568
daniel@transgaming.com428d1582010-05-04 03:35:25 +00002569 gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002570
2571 switch (pname)
2572 {
2573 case GL_RENDERBUFFER_WIDTH:
2574 *params = renderbuffer->getWidth();
2575 break;
2576 case GL_RENDERBUFFER_HEIGHT:
2577 *params = renderbuffer->getHeight();
2578 break;
2579 case GL_RENDERBUFFER_INTERNAL_FORMAT:
2580 *params = renderbuffer->getFormat();
2581 break;
2582 case GL_RENDERBUFFER_RED_SIZE:
2583 if (renderbuffer->isColorbuffer())
2584 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002585 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002586 }
2587 else
2588 {
2589 *params = 0;
2590 }
2591 break;
2592 case GL_RENDERBUFFER_GREEN_SIZE:
2593 if (renderbuffer->isColorbuffer())
2594 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002595 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002596 }
2597 else
2598 {
2599 *params = 0;
2600 }
2601 break;
2602 case GL_RENDERBUFFER_BLUE_SIZE:
2603 if (renderbuffer->isColorbuffer())
2604 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002605 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002606 }
2607 else
2608 {
2609 *params = 0;
2610 }
2611 break;
2612 case GL_RENDERBUFFER_ALPHA_SIZE:
2613 if (renderbuffer->isColorbuffer())
2614 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002615 *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002616 }
2617 else
2618 {
2619 *params = 0;
2620 }
2621 break;
2622 case GL_RENDERBUFFER_DEPTH_SIZE:
2623 if (renderbuffer->isDepthbuffer())
2624 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002625 *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002626 }
2627 else
2628 {
2629 *params = 0;
2630 }
2631 break;
2632 case GL_RENDERBUFFER_STENCIL_SIZE:
2633 if (renderbuffer->isStencilbuffer())
2634 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00002635 *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002636 }
2637 else
2638 {
2639 *params = 0;
2640 }
2641 break;
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00002642 case GL_RENDERBUFFER_SAMPLES_ANGLE:
2643 {
2644 if (context->getMaxSupportedSamples() != 0)
2645 {
2646 *params = renderbuffer->getStorage()->getSamples();
2647 }
2648 else
2649 {
2650 return error(GL_INVALID_ENUM);
2651 }
2652 }
2653 break;
daniel@transgaming.com4901fca2010-04-20 18:52:41 +00002654 default:
2655 return error(GL_INVALID_ENUM);
2656 }
2657 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002658 }
2659 catch(std::bad_alloc&)
2660 {
2661 return error(GL_OUT_OF_MEMORY);
2662 }
2663}
2664
2665void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2666{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002667 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002668
2669 try
2670 {
2671 gl::Context *context = gl::getContext();
2672
2673 if (context)
2674 {
2675 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002676
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002677 if (!shaderObject)
2678 {
2679 return error(GL_INVALID_VALUE);
2680 }
2681
2682 switch (pname)
2683 {
2684 case GL_SHADER_TYPE:
2685 *params = shaderObject->getType();
2686 return;
2687 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002688 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002689 return;
2690 case GL_COMPILE_STATUS:
2691 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2692 return;
2693 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002694 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002695 return;
2696 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002697 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002698 return;
2699 default:
2700 return error(GL_INVALID_ENUM);
2701 }
2702 }
2703 }
2704 catch(std::bad_alloc&)
2705 {
2706 return error(GL_OUT_OF_MEMORY);
2707 }
2708}
2709
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002710void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002711{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002712 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002713 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002714
2715 try
2716 {
2717 if (bufsize < 0)
2718 {
2719 return error(GL_INVALID_VALUE);
2720 }
2721
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002722 gl::Context *context = gl::getContext();
2723
2724 if (context)
2725 {
2726 gl::Shader *shaderObject = context->getShader(shader);
2727
2728 if (!shaderObject)
2729 {
2730 return error(GL_INVALID_VALUE);
2731 }
2732
2733 shaderObject->getInfoLog(bufsize, length, infolog);
2734 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002735 }
2736 catch(std::bad_alloc&)
2737 {
2738 return error(GL_OUT_OF_MEMORY);
2739 }
2740}
2741
2742void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2743{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002744 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2745 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002746
2747 try
2748 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002749 switch (shadertype)
2750 {
2751 case GL_VERTEX_SHADER:
2752 case GL_FRAGMENT_SHADER:
2753 break;
2754 default:
2755 return error(GL_INVALID_ENUM);
2756 }
2757
2758 switch (precisiontype)
2759 {
2760 case GL_LOW_FLOAT:
2761 case GL_MEDIUM_FLOAT:
2762 case GL_HIGH_FLOAT:
2763 // Assume IEEE 754 precision
2764 range[0] = 127;
2765 range[1] = 127;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002766 *precision = 23;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002767 break;
2768 case GL_LOW_INT:
2769 case GL_MEDIUM_INT:
2770 case GL_HIGH_INT:
2771 // Some (most) hardware only supports single-precision floating-point numbers,
2772 // which can accurately represent integers up to +/-16777216
2773 range[0] = 24;
2774 range[1] = 24;
daniel@transgaming.comc5c15382010-04-23 18:34:49 +00002775 *precision = 0;
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002776 break;
2777 default:
2778 return error(GL_INVALID_ENUM);
2779 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002780 }
2781 catch(std::bad_alloc&)
2782 {
2783 return error(GL_OUT_OF_MEMORY);
2784 }
2785}
2786
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002787void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002788{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002789 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002790 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002791
2792 try
2793 {
2794 if (bufsize < 0)
2795 {
2796 return error(GL_INVALID_VALUE);
2797 }
2798
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002799 gl::Context *context = gl::getContext();
2800
2801 if (context)
2802 {
2803 gl::Shader *shaderObject = context->getShader(shader);
2804
2805 if (!shaderObject)
2806 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002807 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002808 }
2809
2810 shaderObject->getSource(bufsize, length, source);
2811 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002812 }
2813 catch(std::bad_alloc&)
2814 {
2815 return error(GL_OUT_OF_MEMORY);
2816 }
2817}
2818
2819const GLubyte* __stdcall glGetString(GLenum name)
2820{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002821 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002822
2823 try
2824 {
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002825 gl::Context *context = gl::getContext();
2826
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002827 switch (name)
2828 {
2829 case GL_VENDOR:
2830 return (GLubyte*)"TransGaming Inc.";
2831 case GL_RENDERER:
2832 return (GLubyte*)"ANGLE";
2833 case GL_VERSION:
2834 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2835 case GL_SHADING_LANGUAGE_VERSION:
2836 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2837 case GL_EXTENSIONS:
daniel@transgaming.com3e4c6002010-05-05 18:50:13 +00002838 return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002839 default:
2840 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2841 }
2842 }
2843 catch(std::bad_alloc&)
2844 {
2845 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2846 }
2847
2848 return NULL;
2849}
2850
2851void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2852{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002853 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002854
2855 try
2856 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002857 gl::Context *context = gl::getContext();
2858
2859 if (context)
2860 {
2861 gl::Texture *texture;
2862
2863 switch (target)
2864 {
2865 case GL_TEXTURE_2D:
2866 texture = context->getTexture2D();
2867 break;
2868 case GL_TEXTURE_CUBE_MAP:
2869 texture = context->getTextureCubeMap();
2870 break;
2871 default:
2872 return error(GL_INVALID_ENUM);
2873 }
2874
2875 switch (pname)
2876 {
2877 case GL_TEXTURE_MAG_FILTER:
2878 *params = (GLfloat)texture->getMagFilter();
2879 break;
2880 case GL_TEXTURE_MIN_FILTER:
2881 *params = (GLfloat)texture->getMinFilter();
2882 break;
2883 case GL_TEXTURE_WRAP_S:
2884 *params = (GLfloat)texture->getWrapS();
2885 break;
2886 case GL_TEXTURE_WRAP_T:
2887 *params = (GLfloat)texture->getWrapT();
2888 break;
2889 default:
2890 return error(GL_INVALID_ENUM);
2891 }
2892 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002893 }
2894 catch(std::bad_alloc&)
2895 {
2896 return error(GL_OUT_OF_MEMORY);
2897 }
2898}
2899
2900void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2901{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002902 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002903
2904 try
2905 {
daniel@transgaming.com5d2bee92010-04-20 18:51:56 +00002906 gl::Context *context = gl::getContext();
2907
2908 if (context)
2909 {
2910 gl::Texture *texture;
2911
2912 switch (target)
2913 {
2914 case GL_TEXTURE_2D:
2915 texture = context->getTexture2D();
2916 break;
2917 case GL_TEXTURE_CUBE_MAP:
2918 texture = context->getTextureCubeMap();
2919 break;
2920 default:
2921 return error(GL_INVALID_ENUM);
2922 }
2923
2924 switch (pname)
2925 {
2926 case GL_TEXTURE_MAG_FILTER:
2927 *params = texture->getMagFilter();
2928 break;
2929 case GL_TEXTURE_MIN_FILTER:
2930 *params = texture->getMinFilter();
2931 break;
2932 case GL_TEXTURE_WRAP_S:
2933 *params = texture->getWrapS();
2934 break;
2935 case GL_TEXTURE_WRAP_T:
2936 *params = texture->getWrapT();
2937 break;
2938 default:
2939 return error(GL_INVALID_ENUM);
2940 }
2941 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002942 }
2943 catch(std::bad_alloc&)
2944 {
2945 return error(GL_OUT_OF_MEMORY);
2946 }
2947}
2948
2949void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2950{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002951 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002952
2953 try
2954 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002955 gl::Context *context = gl::getContext();
2956
2957 if (context)
2958 {
2959 if (program == 0)
2960 {
2961 return error(GL_INVALID_VALUE);
2962 }
2963
2964 gl::Program *programObject = context->getProgram(program);
2965
2966 if (!programObject || !programObject->isLinked())
2967 {
2968 return error(GL_INVALID_OPERATION);
2969 }
2970
2971 if (!programObject->getUniformfv(location, params))
2972 {
2973 return error(GL_INVALID_OPERATION);
2974 }
2975 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002976 }
2977 catch(std::bad_alloc&)
2978 {
2979 return error(GL_OUT_OF_MEMORY);
2980 }
2981}
2982
2983void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2984{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002985 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002986
2987 try
2988 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002989 gl::Context *context = gl::getContext();
2990
2991 if (context)
2992 {
2993 if (program == 0)
2994 {
2995 return error(GL_INVALID_VALUE);
2996 }
2997
2998 gl::Program *programObject = context->getProgram(program);
2999
3000 if (!programObject || !programObject->isLinked())
3001 {
3002 return error(GL_INVALID_OPERATION);
3003 }
3004
3005 if (!programObject)
3006 {
3007 return error(GL_INVALID_OPERATION);
3008 }
3009
3010 if (!programObject->getUniformiv(location, params))
3011 {
3012 return error(GL_INVALID_OPERATION);
3013 }
3014 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003015 }
3016 catch(std::bad_alloc&)
3017 {
3018 return error(GL_OUT_OF_MEMORY);
3019 }
3020}
3021
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003022int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003023{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003024 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003025
3026 try
3027 {
3028 gl::Context *context = gl::getContext();
3029
3030 if (strstr(name, "gl_") == name)
3031 {
3032 return -1;
3033 }
3034
3035 if (context)
3036 {
3037 gl::Program *programObject = context->getProgram(program);
3038
3039 if (!programObject)
3040 {
daniel@transgaming.comd1abe5b2010-04-13 19:53:33 +00003041 if (context->getShader(program))
3042 {
3043 return error(GL_INVALID_OPERATION, -1);
3044 }
3045 else
3046 {
3047 return error(GL_INVALID_VALUE, -1);
3048 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003049 }
3050
3051 if (!programObject->isLinked())
3052 {
3053 return error(GL_INVALID_OPERATION, -1);
3054 }
3055
daniel@transgaming.coma3bbfd42010-06-07 02:06:09 +00003056 return programObject->getUniformLocation(name, false);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003057 }
3058 }
3059 catch(std::bad_alloc&)
3060 {
3061 return error(GL_OUT_OF_MEMORY, -1);
3062 }
3063
3064 return -1;
3065}
3066
3067void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3068{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003069 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003070
3071 try
3072 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003073 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003074
daniel@transgaming.come0078962010-04-15 20:45:08 +00003075 if (context)
3076 {
3077 if (index >= gl::MAX_VERTEX_ATTRIBS)
3078 {
3079 return error(GL_INVALID_VALUE);
3080 }
3081
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003082 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003083
daniel@transgaming.come0078962010-04-15 20:45:08 +00003084 switch (pname)
3085 {
3086 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003087 *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003088 break;
3089 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003090 *params = (GLfloat)attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003091 break;
3092 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003093 *params = (GLfloat)attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003094 break;
3095 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003096 *params = (GLfloat)attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003097 break;
3098 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003099 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003100 break;
3101 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003102 *params = (GLfloat)attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003103 break;
3104 case GL_CURRENT_VERTEX_ATTRIB:
3105 for (int i = 0; i < 4; ++i)
3106 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003107 params[i] = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003108 }
3109 break;
3110 default: return error(GL_INVALID_ENUM);
3111 }
3112 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003113 }
3114 catch(std::bad_alloc&)
3115 {
3116 return error(GL_OUT_OF_MEMORY);
3117 }
3118}
3119
3120void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3121{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003122 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003123
3124 try
3125 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003126 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003127
daniel@transgaming.come0078962010-04-15 20:45:08 +00003128 if (context)
3129 {
3130 if (index >= gl::MAX_VERTEX_ATTRIBS)
3131 {
3132 return error(GL_INVALID_VALUE);
3133 }
3134
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003135 const gl::AttributeState &attribState = context->getVertexAttribState(index);
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003136
daniel@transgaming.come0078962010-04-15 20:45:08 +00003137 switch (pname)
3138 {
3139 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003140 *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003141 break;
3142 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003143 *params = attribState.mSize;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003144 break;
3145 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003146 *params = attribState.mStride;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003147 break;
3148 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003149 *params = attribState.mType;
daniel@transgaming.come0078962010-04-15 20:45:08 +00003150 break;
3151 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003152 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
daniel@transgaming.come0078962010-04-15 20:45:08 +00003153 break;
3154 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003155 *params = attribState.mBoundBuffer.id();
daniel@transgaming.come0078962010-04-15 20:45:08 +00003156 break;
3157 case GL_CURRENT_VERTEX_ATTRIB:
3158 for (int i = 0; i < 4; ++i)
3159 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003160 float currentValue = attribState.mCurrentValue[i];
daniel@transgaming.come0078962010-04-15 20:45:08 +00003161 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3162 }
3163 break;
3164 default: return error(GL_INVALID_ENUM);
3165 }
3166 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003167 }
3168 catch(std::bad_alloc&)
3169 {
3170 return error(GL_OUT_OF_MEMORY);
3171 }
3172}
3173
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003174void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003175{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003176 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003177
3178 try
3179 {
daniel@transgaming.come0078962010-04-15 20:45:08 +00003180 gl::Context *context = gl::getContext();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003181
daniel@transgaming.come0078962010-04-15 20:45:08 +00003182 if (context)
3183 {
3184 if (index >= gl::MAX_VERTEX_ATTRIBS)
3185 {
3186 return error(GL_INVALID_VALUE);
3187 }
3188
3189 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3190 {
3191 return error(GL_INVALID_ENUM);
3192 }
3193
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003194 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
daniel@transgaming.come0078962010-04-15 20:45:08 +00003195 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003196 }
3197 catch(std::bad_alloc&)
3198 {
3199 return error(GL_OUT_OF_MEMORY);
3200 }
3201}
3202
3203void __stdcall glHint(GLenum target, GLenum mode)
3204{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003205 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003206
3207 try
3208 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003209 switch (target)
3210 {
3211 case GL_GENERATE_MIPMAP_HINT:
3212 switch (mode)
3213 {
3214 case GL_FASTEST:
3215 case GL_NICEST:
3216 case GL_DONT_CARE:
3217 break;
3218 default:
3219 return error(GL_INVALID_ENUM);
3220 }
3221 break;
3222 default:
3223 return error(GL_INVALID_ENUM);
3224 }
3225
3226 gl::Context *context = gl::getContext();
3227 if (context)
3228 {
3229 if (target == GL_GENERATE_MIPMAP_HINT)
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003230 context->setGenerateMipmapHint(mode);
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00003231 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003232 }
3233 catch(std::bad_alloc&)
3234 {
3235 return error(GL_OUT_OF_MEMORY);
3236 }
3237}
3238
3239GLboolean __stdcall glIsBuffer(GLuint buffer)
3240{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003241 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003242
3243 try
3244 {
3245 gl::Context *context = gl::getContext();
3246
3247 if (context && buffer)
3248 {
3249 gl::Buffer *bufferObject = context->getBuffer(buffer);
3250
3251 if (bufferObject)
3252 {
3253 return GL_TRUE;
3254 }
3255 }
3256 }
3257 catch(std::bad_alloc&)
3258 {
3259 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3260 }
3261
3262 return GL_FALSE;
3263}
3264
3265GLboolean __stdcall glIsEnabled(GLenum cap)
3266{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003267 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003268
3269 try
3270 {
3271 gl::Context *context = gl::getContext();
3272
3273 if (context)
3274 {
3275 switch (cap)
3276 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003277 case GL_CULL_FACE: return context->isCullFaceEnabled();
3278 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled();
3279 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3280 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled();
3281 case GL_SCISSOR_TEST: return context->isScissorTestEnabled();
3282 case GL_STENCIL_TEST: return context->isStencilTestEnabled();
3283 case GL_DEPTH_TEST: return context->isDepthTestEnabled();
3284 case GL_BLEND: return context->isBlendEnabled();
3285 case GL_DITHER: return context->isDitherEnabled();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003286 default:
3287 return error(GL_INVALID_ENUM, false);
3288 }
3289 }
3290 }
3291 catch(std::bad_alloc&)
3292 {
3293 return error(GL_OUT_OF_MEMORY, false);
3294 }
3295
3296 return false;
3297}
3298
3299GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3300{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003301 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003302
3303 try
3304 {
3305 gl::Context *context = gl::getContext();
3306
3307 if (context && framebuffer)
3308 {
3309 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3310
3311 if (framebufferObject)
3312 {
3313 return GL_TRUE;
3314 }
3315 }
3316 }
3317 catch(std::bad_alloc&)
3318 {
3319 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3320 }
3321
3322 return GL_FALSE;
3323}
3324
3325GLboolean __stdcall glIsProgram(GLuint program)
3326{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003327 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003328
3329 try
3330 {
3331 gl::Context *context = gl::getContext();
3332
3333 if (context && program)
3334 {
3335 gl::Program *programObject = context->getProgram(program);
3336
3337 if (programObject)
3338 {
3339 return GL_TRUE;
3340 }
3341 }
3342 }
3343 catch(std::bad_alloc&)
3344 {
3345 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3346 }
3347
3348 return GL_FALSE;
3349}
3350
3351GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3352{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003353 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003354
3355 try
3356 {
3357 gl::Context *context = gl::getContext();
3358
3359 if (context && renderbuffer)
3360 {
3361 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3362
3363 if (renderbufferObject)
3364 {
3365 return GL_TRUE;
3366 }
3367 }
3368 }
3369 catch(std::bad_alloc&)
3370 {
3371 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3372 }
3373
3374 return GL_FALSE;
3375}
3376
3377GLboolean __stdcall glIsShader(GLuint shader)
3378{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003379 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003380
3381 try
3382 {
3383 gl::Context *context = gl::getContext();
3384
3385 if (context && shader)
3386 {
3387 gl::Shader *shaderObject = context->getShader(shader);
3388
3389 if (shaderObject)
3390 {
3391 return GL_TRUE;
3392 }
3393 }
3394 }
3395 catch(std::bad_alloc&)
3396 {
3397 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3398 }
3399
3400 return GL_FALSE;
3401}
3402
3403GLboolean __stdcall glIsTexture(GLuint texture)
3404{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003405 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003406
3407 try
3408 {
3409 gl::Context *context = gl::getContext();
3410
3411 if (context && texture)
3412 {
3413 gl::Texture *textureObject = context->getTexture(texture);
3414
3415 if (textureObject)
3416 {
3417 return GL_TRUE;
3418 }
3419 }
3420 }
3421 catch(std::bad_alloc&)
3422 {
3423 return error(GL_OUT_OF_MEMORY, GL_FALSE);
3424 }
3425
3426 return GL_FALSE;
3427}
3428
3429void __stdcall glLineWidth(GLfloat width)
3430{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003431 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003432
3433 try
3434 {
3435 if (width <= 0.0f)
3436 {
3437 return error(GL_INVALID_VALUE);
3438 }
3439
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00003440 gl::Context *context = gl::getContext();
3441
3442 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003443 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003444 context->setLineWidth(width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003445 }
3446 }
3447 catch(std::bad_alloc&)
3448 {
3449 return error(GL_OUT_OF_MEMORY);
3450 }
3451}
3452
3453void __stdcall glLinkProgram(GLuint program)
3454{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003455 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003456
3457 try
3458 {
3459 gl::Context *context = gl::getContext();
3460
3461 if (context)
3462 {
3463 gl::Program *programObject = context->getProgram(program);
3464
3465 if (!programObject)
3466 {
daniel@transgaming.com277b7142010-04-13 03:26:44 +00003467 if (context->getShader(program))
3468 {
3469 return error(GL_INVALID_OPERATION);
3470 }
3471 else
3472 {
3473 return error(GL_INVALID_VALUE);
3474 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003475 }
3476
3477 programObject->link();
3478 }
3479 }
3480 catch(std::bad_alloc&)
3481 {
3482 return error(GL_OUT_OF_MEMORY);
3483 }
3484}
3485
3486void __stdcall glPixelStorei(GLenum pname, GLint param)
3487{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003488 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003489
3490 try
3491 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003492 gl::Context *context = gl::getContext();
3493
3494 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003495 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003496 switch (pname)
3497 {
3498 case GL_UNPACK_ALIGNMENT:
3499 if (param != 1 && param != 2 && param != 4 && param != 8)
3500 {
3501 return error(GL_INVALID_VALUE);
3502 }
3503
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003504 context->setUnpackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003505 break;
3506
3507 case GL_PACK_ALIGNMENT:
3508 if (param != 1 && param != 2 && param != 4 && param != 8)
3509 {
3510 return error(GL_INVALID_VALUE);
3511 }
3512
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003513 context->setPackAlignment(param);
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003514 break;
3515
3516 default:
3517 return error(GL_INVALID_ENUM);
3518 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003519 }
3520 }
3521 catch(std::bad_alloc&)
3522 {
3523 return error(GL_OUT_OF_MEMORY);
3524 }
3525}
3526
3527void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3528{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003529 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003530
3531 try
3532 {
daniel@transgaming.comaede6302010-04-29 03:35:48 +00003533 gl::Context *context = gl::getContext();
3534
3535 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003536 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003537 context->setPolygonOffsetParams(factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003538 }
3539 }
3540 catch(std::bad_alloc&)
3541 {
3542 return error(GL_OUT_OF_MEMORY);
3543 }
3544}
3545
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003546void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003547{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003548 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003549 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003550 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003551
3552 try
3553 {
3554 if (width < 0 || height < 0)
3555 {
3556 return error(GL_INVALID_VALUE);
3557 }
3558
3559 switch (format)
3560 {
3561 case GL_RGBA:
3562 switch (type)
3563 {
3564 case GL_UNSIGNED_BYTE:
3565 break;
3566 default:
3567 return error(GL_INVALID_OPERATION);
3568 }
3569 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00003570 case GL_BGRA_EXT:
3571 switch (type)
3572 {
3573 case GL_UNSIGNED_BYTE:
3574 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3575 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3576 break;
3577 default:
3578 return error(GL_INVALID_OPERATION);
3579 }
3580 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003581 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3582 switch (type)
3583 {
3584 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3585 break;
3586 default:
3587 return error(GL_INVALID_OPERATION);
3588 }
3589 break;
3590 default:
3591 return error(GL_INVALID_OPERATION);
3592 }
3593
3594 gl::Context *context = gl::getContext();
3595
3596 if (context)
3597 {
3598 context->readPixels(x, y, width, height, format, type, pixels);
3599 }
3600 }
3601 catch(std::bad_alloc&)
3602 {
3603 return error(GL_OUT_OF_MEMORY);
3604 }
3605}
3606
3607void __stdcall glReleaseShaderCompiler(void)
3608{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003609 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003610
3611 try
3612 {
3613 gl::Shader::releaseCompiler();
3614 }
3615 catch(std::bad_alloc&)
3616 {
3617 return error(GL_OUT_OF_MEMORY);
3618 }
3619}
3620
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003621void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003622{
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003623 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3624 target, samples, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003625
3626 try
3627 {
3628 switch (target)
3629 {
3630 case GL_RENDERBUFFER:
3631 break;
3632 default:
3633 return error(GL_INVALID_ENUM);
3634 }
3635
3636 switch (internalformat)
3637 {
3638 case GL_DEPTH_COMPONENT16:
3639 case GL_RGBA4:
3640 case GL_RGB5_A1:
3641 case GL_RGB565:
3642 case GL_STENCIL_INDEX8:
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003643 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com63977542010-08-24 19:21:02 +00003644 case GL_RGB8_OES:
3645 case GL_RGBA8_OES:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003646 break;
3647 default:
3648 return error(GL_INVALID_ENUM);
3649 }
3650
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003651 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE || samples < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003652 {
3653 return error(GL_INVALID_VALUE);
3654 }
3655
3656 gl::Context *context = gl::getContext();
3657
3658 if (context)
3659 {
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003660 if (samples > context->getMaxSupportedSamples())
3661 {
3662 return error(GL_INVALID_VALUE);
3663 }
3664
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00003665 GLuint handle = context->getRenderbufferHandle();
3666 if (handle == 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003667 {
3668 return error(GL_INVALID_OPERATION);
3669 }
3670
3671 switch (internalformat)
3672 {
3673 case GL_DEPTH_COMPONENT16:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003674 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003675 break;
3676 case GL_RGBA4:
3677 case GL_RGB5_A1:
3678 case GL_RGB565:
daniel@transgaming.com63977542010-08-24 19:21:02 +00003679 case GL_RGB8_OES:
3680 case GL_RGBA8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003681 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003682 break;
3683 case GL_STENCIL_INDEX8:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003684 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003685 break;
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003686 case GL_DEPTH24_STENCIL8_OES:
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003687 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
daniel@transgaming.comcdacc8e2010-07-28 19:20:50 +00003688 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003689 default:
3690 return error(GL_INVALID_ENUM);
3691 }
3692 }
3693 }
3694 catch(std::bad_alloc&)
3695 {
3696 return error(GL_OUT_OF_MEMORY);
3697 }
3698}
3699
daniel@transgaming.com1f135d82010-08-24 19:20:36 +00003700void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3701{
3702 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
3703}
3704
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003705void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
3706{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003707 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003708
3709 try
3710 {
3711 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003712
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003713 if (context)
3714 {
daniel@transgaming.coma36f98e2010-05-18 18:51:09 +00003715 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003716 }
3717 }
3718 catch(std::bad_alloc&)
3719 {
3720 return error(GL_OUT_OF_MEMORY);
3721 }
3722}
3723
3724void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
3725{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003726 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 +00003727
3728 try
3729 {
3730 if (width < 0 || height < 0)
3731 {
3732 return error(GL_INVALID_VALUE);
3733 }
3734
3735 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003736
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003737 if (context)
3738 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003739 context->setScissorParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003740 }
3741 }
3742 catch(std::bad_alloc&)
3743 {
3744 return error(GL_OUT_OF_MEMORY);
3745 }
3746}
3747
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003748void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003749{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003750 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003751 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003752 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003753
3754 try
3755 {
daniel@transgaming.comd1f667f2010-04-29 03:38:52 +00003756 // No binary shader formats are supported.
3757 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003758 }
3759 catch(std::bad_alloc&)
3760 {
3761 return error(GL_OUT_OF_MEMORY);
3762 }
3763}
3764
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003765void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003766{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003767 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 +00003768 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003769
3770 try
3771 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003772 if (count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003773 {
3774 return error(GL_INVALID_VALUE);
3775 }
3776
3777 gl::Context *context = gl::getContext();
3778
3779 if (context)
3780 {
3781 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003782
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003783 if (!shaderObject)
3784 {
daniel@transgaming.com8e6a6be2010-04-13 03:26:41 +00003785 if (context->getProgram(shader))
3786 {
3787 return error(GL_INVALID_OPERATION);
3788 }
3789 else
3790 {
3791 return error(GL_INVALID_VALUE);
3792 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003793 }
3794
3795 shaderObject->setSource(count, string, length);
3796 }
3797 }
3798 catch(std::bad_alloc&)
3799 {
3800 return error(GL_OUT_OF_MEMORY);
3801 }
3802}
3803
3804void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3805{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003806 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003807}
3808
3809void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3810{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003811 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 +00003812
3813 try
3814 {
3815 switch (face)
3816 {
3817 case GL_FRONT:
3818 case GL_BACK:
3819 case GL_FRONT_AND_BACK:
3820 break;
3821 default:
3822 return error(GL_INVALID_ENUM);
3823 }
3824
3825 switch (func)
3826 {
3827 case GL_NEVER:
3828 case GL_ALWAYS:
3829 case GL_LESS:
3830 case GL_LEQUAL:
3831 case GL_EQUAL:
3832 case GL_GEQUAL:
3833 case GL_GREATER:
3834 case GL_NOTEQUAL:
3835 break;
3836 default:
3837 return error(GL_INVALID_ENUM);
3838 }
3839
3840 gl::Context *context = gl::getContext();
3841
3842 if (context)
3843 {
3844 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3845 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003846 context->setStencilParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003847 }
3848
3849 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3850 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003851 context->setStencilBackParams(func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003852 }
3853 }
3854 }
3855 catch(std::bad_alloc&)
3856 {
3857 return error(GL_OUT_OF_MEMORY);
3858 }
3859}
3860
3861void __stdcall glStencilMask(GLuint mask)
3862{
3863 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3864}
3865
3866void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3867{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003868 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003869
3870 try
3871 {
3872 switch (face)
3873 {
3874 case GL_FRONT:
3875 case GL_BACK:
3876 case GL_FRONT_AND_BACK:
3877 break;
3878 default:
3879 return error(GL_INVALID_ENUM);
3880 }
3881
3882 gl::Context *context = gl::getContext();
3883
3884 if (context)
3885 {
3886 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3887 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003888 context->setStencilWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003889 }
3890
3891 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3892 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003893 context->setStencilBackWritemask(mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003894 }
3895 }
3896 }
3897 catch(std::bad_alloc&)
3898 {
3899 return error(GL_OUT_OF_MEMORY);
3900 }
3901}
3902
3903void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3904{
3905 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3906}
3907
3908void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3909{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003910 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3911 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003912
3913 try
3914 {
3915 switch (face)
3916 {
3917 case GL_FRONT:
3918 case GL_BACK:
3919 case GL_FRONT_AND_BACK:
3920 break;
3921 default:
3922 return error(GL_INVALID_ENUM);
3923 }
3924
3925 switch (fail)
3926 {
3927 case GL_ZERO:
3928 case GL_KEEP:
3929 case GL_REPLACE:
3930 case GL_INCR:
3931 case GL_DECR:
3932 case GL_INVERT:
3933 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003934 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003935 break;
3936 default:
3937 return error(GL_INVALID_ENUM);
3938 }
3939
3940 switch (zfail)
3941 {
3942 case GL_ZERO:
3943 case GL_KEEP:
3944 case GL_REPLACE:
3945 case GL_INCR:
3946 case GL_DECR:
3947 case GL_INVERT:
3948 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003949 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003950 break;
3951 default:
3952 return error(GL_INVALID_ENUM);
3953 }
3954
3955 switch (zpass)
3956 {
3957 case GL_ZERO:
3958 case GL_KEEP:
3959 case GL_REPLACE:
3960 case GL_INCR:
3961 case GL_DECR:
3962 case GL_INVERT:
3963 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003964 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003965 break;
3966 default:
3967 return error(GL_INVALID_ENUM);
3968 }
3969
3970 gl::Context *context = gl::getContext();
3971
3972 if (context)
3973 {
3974 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3975 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003976 context->setStencilOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003977 }
3978
3979 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3980 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00003981 context->setStencilBackOperations(fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003982 }
3983 }
3984 }
3985 catch(std::bad_alloc&)
3986 {
3987 return error(GL_OUT_OF_MEMORY);
3988 }
3989}
3990
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003991void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3992 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003993{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003994 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 +00003995 "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 +00003996 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003997
3998 try
3999 {
4000 if (level < 0 || width < 0 || height < 0)
4001 {
4002 return error(GL_INVALID_VALUE);
4003 }
4004
4005 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
4006 {
4007 return error(GL_INVALID_VALUE);
4008 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00004009
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004010 switch (target)
4011 {
4012 case GL_TEXTURE_2D:
4013 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
4014 {
4015 return error(GL_INVALID_VALUE);
4016 }
4017 break;
4018 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4019 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4020 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4021 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4022 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4023 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com34dc3e82010-04-15 20:45:02 +00004024 if (width != height)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004025 {
4026 return error(GL_INVALID_VALUE);
4027 }
4028
4029 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
4030 {
4031 return error(GL_INVALID_VALUE);
4032 }
4033 break;
4034 default:
4035 return error(GL_INVALID_ENUM);
4036 }
4037
4038 if (internalformat != format)
4039 {
4040 return error(GL_INVALID_OPERATION);
4041 }
4042
4043 switch (internalformat)
4044 {
4045 case GL_ALPHA:
4046 case GL_LUMINANCE:
4047 case GL_LUMINANCE_ALPHA:
4048 switch (type)
4049 {
4050 case GL_UNSIGNED_BYTE:
4051 break;
4052 default:
4053 return error(GL_INVALID_ENUM);
4054 }
4055 break;
4056 case GL_RGB:
4057 switch (type)
4058 {
4059 case GL_UNSIGNED_BYTE:
4060 case GL_UNSIGNED_SHORT_5_6_5:
4061 break;
4062 default:
4063 return error(GL_INVALID_ENUM);
4064 }
4065 break;
4066 case GL_RGBA:
4067 switch (type)
4068 {
4069 case GL_UNSIGNED_BYTE:
4070 case GL_UNSIGNED_SHORT_4_4_4_4:
4071 case GL_UNSIGNED_SHORT_5_5_5_1:
4072 break;
4073 default:
4074 return error(GL_INVALID_ENUM);
4075 }
4076 break;
daniel@transgaming.coma9198d92010-08-08 04:49:56 +00004077 case GL_BGRA_EXT:
4078 switch (type)
4079 {
4080 case GL_UNSIGNED_BYTE:
4081 break;
4082 default:
4083 return error(GL_INVALID_ENUM);
4084 }
4085 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004086 default:
4087 return error(GL_INVALID_VALUE);
4088 }
4089
4090 if (border != 0)
4091 {
4092 return error(GL_INVALID_VALUE);
4093 }
4094
4095 gl::Context *context = gl::getContext();
4096
4097 if (context)
4098 {
4099 if (target == GL_TEXTURE_2D)
4100 {
4101 gl::Texture2D *texture = context->getTexture2D();
4102
4103 if (!texture)
4104 {
4105 return error(GL_INVALID_OPERATION);
4106 }
4107
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004108 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004109 }
4110 else
4111 {
4112 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4113
4114 if (!texture)
4115 {
4116 return error(GL_INVALID_OPERATION);
4117 }
4118
4119 switch (target)
4120 {
4121 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004122 texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004123 break;
4124 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004125 texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004126 break;
4127 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004128 texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004129 break;
4130 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004131 texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004132 break;
4133 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004134 texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004135 break;
4136 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004137 texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004138 break;
4139 default: UNREACHABLE();
4140 }
4141 }
4142 }
4143 }
4144 catch(std::bad_alloc&)
4145 {
4146 return error(GL_OUT_OF_MEMORY);
4147 }
4148}
4149
4150void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4151{
4152 glTexParameteri(target, pname, (GLint)param);
4153}
4154
4155void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4156{
4157 glTexParameteri(target, pname, (GLint)*params);
4158}
4159
4160void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4161{
daniel@transgaming.com00035fe2010-05-05 18:49:03 +00004162 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004163
4164 try
4165 {
4166 gl::Context *context = gl::getContext();
4167
4168 if (context)
4169 {
4170 gl::Texture *texture;
4171
4172 switch (target)
4173 {
4174 case GL_TEXTURE_2D:
4175 texture = context->getTexture2D();
4176 break;
4177 case GL_TEXTURE_CUBE_MAP:
4178 texture = context->getTextureCubeMap();
4179 break;
4180 default:
4181 return error(GL_INVALID_ENUM);
4182 }
4183
4184 switch (pname)
4185 {
4186 case GL_TEXTURE_WRAP_S:
4187 if (!texture->setWrapS((GLenum)param))
4188 {
4189 return error(GL_INVALID_ENUM);
4190 }
4191 break;
4192 case GL_TEXTURE_WRAP_T:
4193 if (!texture->setWrapT((GLenum)param))
4194 {
4195 return error(GL_INVALID_ENUM);
4196 }
4197 break;
4198 case GL_TEXTURE_MIN_FILTER:
4199 if (!texture->setMinFilter((GLenum)param))
4200 {
4201 return error(GL_INVALID_ENUM);
4202 }
4203 break;
4204 case GL_TEXTURE_MAG_FILTER:
4205 if (!texture->setMagFilter((GLenum)param))
4206 {
4207 return error(GL_INVALID_ENUM);
4208 }
4209 break;
4210 default:
4211 return error(GL_INVALID_ENUM);
4212 }
4213 }
4214 }
4215 catch(std::bad_alloc&)
4216 {
4217 return error(GL_OUT_OF_MEMORY);
4218 }
4219}
4220
4221void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4222{
4223 glTexParameteri(target, pname, *params);
4224}
4225
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004226void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4227 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004228{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004229 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4230 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004231 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004232 target, level, xoffset, yoffset, width, height, format, type, pixels);
4233
4234 try
4235 {
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004236 if (!gl::IsTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004237 {
4238 return error(GL_INVALID_ENUM);
4239 }
4240
4241 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004242 {
4243 return error(GL_INVALID_VALUE);
4244 }
4245
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004246 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4247 {
4248 return error(GL_INVALID_VALUE);
4249 }
4250
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004251 if (!gl::CheckTextureFormatType(format, type))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004252 {
4253 return error(GL_INVALID_ENUM);
4254 }
4255
4256 if (width == 0 || height == 0 || pixels == NULL)
4257 {
4258 return;
4259 }
4260
4261 gl::Context *context = gl::getContext();
4262
4263 if (context)
4264 {
4265 if (target == GL_TEXTURE_2D)
4266 {
4267 gl::Texture2D *texture = context->getTexture2D();
4268
4269 if (!texture)
4270 {
4271 return error(GL_INVALID_OPERATION);
4272 }
4273
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004274 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004275 }
daniel@transgaming.com19ffc242010-05-04 03:35:21 +00004276 else if (gl::IsCubemapTextureTarget(target))
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004277 {
4278 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4279
4280 if (!texture)
4281 {
4282 return error(GL_INVALID_OPERATION);
4283 }
4284
daniel@transgaming.com428d1582010-05-04 03:35:25 +00004285 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00004286 }
4287 else
4288 {
4289 UNREACHABLE();
4290 }
4291 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004292 }
4293 catch(std::bad_alloc&)
4294 {
4295 return error(GL_OUT_OF_MEMORY);
4296 }
4297}
4298
4299void __stdcall glUniform1f(GLint location, GLfloat x)
4300{
4301 glUniform1fv(location, 1, &x);
4302}
4303
4304void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4305{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004306 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004307
4308 try
4309 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004310 if (count < 0)
4311 {
4312 return error(GL_INVALID_VALUE);
4313 }
4314
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004315 if (location == -1)
4316 {
4317 return;
4318 }
4319
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004320 gl::Context *context = gl::getContext();
4321
4322 if (context)
4323 {
4324 gl::Program *program = context->getCurrentProgram();
4325
4326 if (!program)
4327 {
4328 return error(GL_INVALID_OPERATION);
4329 }
4330
4331 if (!program->setUniform1fv(location, count, v))
4332 {
4333 return error(GL_INVALID_OPERATION);
4334 }
4335 }
4336 }
4337 catch(std::bad_alloc&)
4338 {
4339 return error(GL_OUT_OF_MEMORY);
4340 }
4341}
4342
4343void __stdcall glUniform1i(GLint location, GLint x)
4344{
4345 glUniform1iv(location, 1, &x);
4346}
4347
4348void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4349{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004350 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004351
4352 try
4353 {
4354 if (count < 0)
4355 {
4356 return error(GL_INVALID_VALUE);
4357 }
4358
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004359 if (location == -1)
4360 {
4361 return;
4362 }
4363
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004364 gl::Context *context = gl::getContext();
4365
4366 if (context)
4367 {
4368 gl::Program *program = context->getCurrentProgram();
4369
4370 if (!program)
4371 {
4372 return error(GL_INVALID_OPERATION);
4373 }
4374
4375 if (!program->setUniform1iv(location, count, v))
4376 {
4377 return error(GL_INVALID_OPERATION);
4378 }
4379 }
4380 }
4381 catch(std::bad_alloc&)
4382 {
4383 return error(GL_OUT_OF_MEMORY);
4384 }
4385}
4386
4387void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4388{
4389 GLfloat xy[2] = {x, y};
4390
4391 glUniform2fv(location, 1, (GLfloat*)&xy);
4392}
4393
4394void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4395{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004396 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004397
4398 try
4399 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004400 if (count < 0)
4401 {
4402 return error(GL_INVALID_VALUE);
4403 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004404
4405 if (location == -1)
4406 {
4407 return;
4408 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004409
4410 gl::Context *context = gl::getContext();
4411
4412 if (context)
4413 {
4414 gl::Program *program = context->getCurrentProgram();
4415
4416 if (!program)
4417 {
4418 return error(GL_INVALID_OPERATION);
4419 }
4420
4421 if (!program->setUniform2fv(location, count, v))
4422 {
4423 return error(GL_INVALID_OPERATION);
4424 }
4425 }
4426 }
4427 catch(std::bad_alloc&)
4428 {
4429 return error(GL_OUT_OF_MEMORY);
4430 }
4431}
4432
4433void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4434{
4435 GLint xy[4] = {x, y};
4436
4437 glUniform2iv(location, 1, (GLint*)&xy);
4438}
4439
4440void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4441{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004442 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004443
4444 try
4445 {
4446 if (count < 0)
4447 {
4448 return error(GL_INVALID_VALUE);
4449 }
4450
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004451 if (location == -1)
4452 {
4453 return;
4454 }
4455
4456 gl::Context *context = gl::getContext();
4457
4458 if (context)
4459 {
4460 gl::Program *program = context->getCurrentProgram();
4461
4462 if (!program)
4463 {
4464 return error(GL_INVALID_OPERATION);
4465 }
4466
4467 if (!program->setUniform2iv(location, count, v))
4468 {
4469 return error(GL_INVALID_OPERATION);
4470 }
4471 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004472 }
4473 catch(std::bad_alloc&)
4474 {
4475 return error(GL_OUT_OF_MEMORY);
4476 }
4477}
4478
4479void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
4480{
4481 GLfloat xyz[3] = {x, y, z};
4482
4483 glUniform3fv(location, 1, (GLfloat*)&xyz);
4484}
4485
4486void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
4487{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004488 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004489
4490 try
4491 {
4492 if (count < 0)
4493 {
4494 return error(GL_INVALID_VALUE);
4495 }
4496
4497 if (location == -1)
4498 {
4499 return;
4500 }
4501
4502 gl::Context *context = gl::getContext();
4503
4504 if (context)
4505 {
4506 gl::Program *program = context->getCurrentProgram();
4507
4508 if (!program)
4509 {
4510 return error(GL_INVALID_OPERATION);
4511 }
4512
4513 if (!program->setUniform3fv(location, count, v))
4514 {
4515 return error(GL_INVALID_OPERATION);
4516 }
4517 }
4518 }
4519 catch(std::bad_alloc&)
4520 {
4521 return error(GL_OUT_OF_MEMORY);
4522 }
4523}
4524
4525void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
4526{
4527 GLint xyz[3] = {x, y, z};
4528
4529 glUniform3iv(location, 1, (GLint*)&xyz);
4530}
4531
4532void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
4533{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004534 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004535
4536 try
4537 {
4538 if (count < 0)
4539 {
4540 return error(GL_INVALID_VALUE);
4541 }
4542
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004543 if (location == -1)
4544 {
4545 return;
4546 }
4547
4548 gl::Context *context = gl::getContext();
4549
4550 if (context)
4551 {
4552 gl::Program *program = context->getCurrentProgram();
4553
4554 if (!program)
4555 {
4556 return error(GL_INVALID_OPERATION);
4557 }
4558
4559 if (!program->setUniform3iv(location, count, v))
4560 {
4561 return error(GL_INVALID_OPERATION);
4562 }
4563 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004564 }
4565 catch(std::bad_alloc&)
4566 {
4567 return error(GL_OUT_OF_MEMORY);
4568 }
4569}
4570
4571void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4572{
4573 GLfloat xyzw[4] = {x, y, z, w};
4574
4575 glUniform4fv(location, 1, (GLfloat*)&xyzw);
4576}
4577
4578void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
4579{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004580 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004581
4582 try
4583 {
4584 if (count < 0)
4585 {
4586 return error(GL_INVALID_VALUE);
4587 }
4588
4589 if (location == -1)
4590 {
4591 return;
4592 }
4593
4594 gl::Context *context = gl::getContext();
4595
4596 if (context)
4597 {
4598 gl::Program *program = context->getCurrentProgram();
4599
4600 if (!program)
4601 {
4602 return error(GL_INVALID_OPERATION);
4603 }
4604
4605 if (!program->setUniform4fv(location, count, v))
4606 {
4607 return error(GL_INVALID_OPERATION);
4608 }
4609 }
4610 }
4611 catch(std::bad_alloc&)
4612 {
4613 return error(GL_OUT_OF_MEMORY);
4614 }
4615}
4616
4617void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
4618{
4619 GLint xyzw[4] = {x, y, z, w};
4620
4621 glUniform4iv(location, 1, (GLint*)&xyzw);
4622}
4623
4624void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
4625{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004626 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004627
4628 try
4629 {
4630 if (count < 0)
4631 {
4632 return error(GL_INVALID_VALUE);
4633 }
4634
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00004635 if (location == -1)
4636 {
4637 return;
4638 }
4639
4640 gl::Context *context = gl::getContext();
4641
4642 if (context)
4643 {
4644 gl::Program *program = context->getCurrentProgram();
4645
4646 if (!program)
4647 {
4648 return error(GL_INVALID_OPERATION);
4649 }
4650
4651 if (!program->setUniform4iv(location, count, v))
4652 {
4653 return error(GL_INVALID_OPERATION);
4654 }
4655 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004656 }
4657 catch(std::bad_alloc&)
4658 {
4659 return error(GL_OUT_OF_MEMORY);
4660 }
4661}
4662
4663void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4664{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004665 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4666 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004667
4668 try
4669 {
4670 if (count < 0 || transpose != GL_FALSE)
4671 {
4672 return error(GL_INVALID_VALUE);
4673 }
4674
4675 if (location == -1)
4676 {
4677 return;
4678 }
4679
4680 gl::Context *context = gl::getContext();
4681
4682 if (context)
4683 {
4684 gl::Program *program = context->getCurrentProgram();
4685
4686 if (!program)
4687 {
4688 return error(GL_INVALID_OPERATION);
4689 }
4690
4691 if (!program->setUniformMatrix2fv(location, count, value))
4692 {
4693 return error(GL_INVALID_OPERATION);
4694 }
4695 }
4696 }
4697 catch(std::bad_alloc&)
4698 {
4699 return error(GL_OUT_OF_MEMORY);
4700 }
4701}
4702
4703void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4704{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004705 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4706 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004707
4708 try
4709 {
4710 if (count < 0 || transpose != GL_FALSE)
4711 {
4712 return error(GL_INVALID_VALUE);
4713 }
4714
4715 if (location == -1)
4716 {
4717 return;
4718 }
4719
4720 gl::Context *context = gl::getContext();
4721
4722 if (context)
4723 {
4724 gl::Program *program = context->getCurrentProgram();
4725
4726 if (!program)
4727 {
4728 return error(GL_INVALID_OPERATION);
4729 }
4730
4731 if (!program->setUniformMatrix3fv(location, count, value))
4732 {
4733 return error(GL_INVALID_OPERATION);
4734 }
4735 }
4736 }
4737 catch(std::bad_alloc&)
4738 {
4739 return error(GL_OUT_OF_MEMORY);
4740 }
4741}
4742
4743void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4744{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004745 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4746 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004747
4748 try
4749 {
4750 if (count < 0 || transpose != GL_FALSE)
4751 {
4752 return error(GL_INVALID_VALUE);
4753 }
4754
4755 if (location == -1)
4756 {
4757 return;
4758 }
4759
4760 gl::Context *context = gl::getContext();
4761
4762 if (context)
4763 {
4764 gl::Program *program = context->getCurrentProgram();
4765
4766 if (!program)
4767 {
4768 return error(GL_INVALID_OPERATION);
4769 }
4770
4771 if (!program->setUniformMatrix4fv(location, count, value))
4772 {
4773 return error(GL_INVALID_OPERATION);
4774 }
4775 }
4776 }
4777 catch(std::bad_alloc&)
4778 {
4779 return error(GL_OUT_OF_MEMORY);
4780 }
4781}
4782
4783void __stdcall glUseProgram(GLuint program)
4784{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004785 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004786
4787 try
4788 {
4789 gl::Context *context = gl::getContext();
4790
4791 if (context)
4792 {
4793 gl::Program *programObject = context->getProgram(program);
4794
daniel@transgaming.comc8478202010-04-13 19:53:35 +00004795 if (!programObject && program != 0)
4796 {
4797 if (context->getShader(program))
4798 {
4799 return error(GL_INVALID_OPERATION);
4800 }
4801 else
4802 {
4803 return error(GL_INVALID_VALUE);
4804 }
4805 }
4806
4807 if (program != 0 && !programObject->isLinked())
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004808 {
4809 return error(GL_INVALID_OPERATION);
4810 }
4811
4812 context->useProgram(program);
4813 }
4814 }
4815 catch(std::bad_alloc&)
4816 {
4817 return error(GL_OUT_OF_MEMORY);
4818 }
4819}
4820
4821void __stdcall glValidateProgram(GLuint program)
4822{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004823 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004824
4825 try
4826 {
daniel@transgaming.com86a7a132010-04-29 03:32:32 +00004827 gl::Context *context = gl::getContext();
4828
4829 if (context)
4830 {
4831 gl::Program *programObject = context->getProgram(program);
4832
4833 if (!programObject)
4834 {
4835 if (context->getShader(program))
4836 {
4837 return error(GL_INVALID_OPERATION);
4838 }
4839 else
4840 {
4841 return error(GL_INVALID_VALUE);
4842 }
4843 }
4844
4845 programObject->validate();
4846 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004847 }
4848 catch(std::bad_alloc&)
4849 {
4850 return error(GL_OUT_OF_MEMORY);
4851 }
4852}
4853
4854void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4855{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004856 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004857
4858 try
4859 {
4860 if (index >= gl::MAX_VERTEX_ATTRIBS)
4861 {
4862 return error(GL_INVALID_VALUE);
4863 }
4864
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004865 gl::Context *context = gl::getContext();
4866
4867 if (context)
4868 {
4869 GLfloat vals[4] = { x, 0, 0, 1 };
4870 context->setVertexAttrib(index, vals);
4871 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004872 }
4873 catch(std::bad_alloc&)
4874 {
4875 return error(GL_OUT_OF_MEMORY);
4876 }
4877}
4878
4879void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4880{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004881 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004882
4883 try
4884 {
4885 if (index >= gl::MAX_VERTEX_ATTRIBS)
4886 {
4887 return error(GL_INVALID_VALUE);
4888 }
4889
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004890 gl::Context *context = gl::getContext();
4891
4892 if (context)
4893 {
4894 GLfloat vals[4] = { values[0], 0, 0, 1 };
4895 context->setVertexAttrib(index, vals);
4896 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004897 }
4898 catch(std::bad_alloc&)
4899 {
4900 return error(GL_OUT_OF_MEMORY);
4901 }
4902}
4903
4904void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4905{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004906 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004907
4908 try
4909 {
4910 if (index >= gl::MAX_VERTEX_ATTRIBS)
4911 {
4912 return error(GL_INVALID_VALUE);
4913 }
4914
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004915 gl::Context *context = gl::getContext();
4916
4917 if (context)
4918 {
4919 GLfloat vals[4] = { x, y, 0, 1 };
4920 context->setVertexAttrib(index, vals);
4921 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004922 }
4923 catch(std::bad_alloc&)
4924 {
4925 return error(GL_OUT_OF_MEMORY);
4926 }
4927}
4928
4929void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4930{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004931 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004932
4933 try
4934 {
4935 if (index >= gl::MAX_VERTEX_ATTRIBS)
4936 {
4937 return error(GL_INVALID_VALUE);
4938 }
4939
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004940 gl::Context *context = gl::getContext();
4941
4942 if (context)
4943 {
4944 GLfloat vals[4] = { values[0], values[1], 0, 1 };
4945 context->setVertexAttrib(index, vals);
4946 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004947 }
4948 catch(std::bad_alloc&)
4949 {
4950 return error(GL_OUT_OF_MEMORY);
4951 }
4952}
4953
4954void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4955{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004956 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 +00004957
4958 try
4959 {
4960 if (index >= gl::MAX_VERTEX_ATTRIBS)
4961 {
4962 return error(GL_INVALID_VALUE);
4963 }
4964
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004965 gl::Context *context = gl::getContext();
4966
4967 if (context)
4968 {
4969 GLfloat vals[4] = { x, y, z, 1 };
4970 context->setVertexAttrib(index, vals);
4971 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004972 }
4973 catch(std::bad_alloc&)
4974 {
4975 return error(GL_OUT_OF_MEMORY);
4976 }
4977}
4978
4979void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4980{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004981 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004982
4983 try
4984 {
4985 if (index >= gl::MAX_VERTEX_ATTRIBS)
4986 {
4987 return error(GL_INVALID_VALUE);
4988 }
4989
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00004990 gl::Context *context = gl::getContext();
4991
4992 if (context)
4993 {
4994 GLfloat vals[4] = { values[0], values[1], values[2], 1 };
4995 context->setVertexAttrib(index, vals);
4996 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004997 }
4998 catch(std::bad_alloc&)
4999 {
5000 return error(GL_OUT_OF_MEMORY);
5001 }
5002}
5003
5004void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5005{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005006 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 +00005007
5008 try
5009 {
5010 if (index >= gl::MAX_VERTEX_ATTRIBS)
5011 {
5012 return error(GL_INVALID_VALUE);
5013 }
5014
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005015 gl::Context *context = gl::getContext();
5016
5017 if (context)
5018 {
5019 GLfloat vals[4] = { x, y, z, w };
5020 context->setVertexAttrib(index, vals);
5021 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005022 }
5023 catch(std::bad_alloc&)
5024 {
5025 return error(GL_OUT_OF_MEMORY);
5026 }
5027}
5028
5029void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5030{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005031 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005032
5033 try
5034 {
5035 if (index >= gl::MAX_VERTEX_ATTRIBS)
5036 {
5037 return error(GL_INVALID_VALUE);
5038 }
5039
daniel@transgaming.come4b08c82010-04-20 18:53:06 +00005040 gl::Context *context = gl::getContext();
5041
5042 if (context)
5043 {
5044 context->setVertexAttrib(index, values);
5045 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005046 }
5047 catch(std::bad_alloc&)
5048 {
5049 return error(GL_OUT_OF_MEMORY);
5050 }
5051}
5052
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005053void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005054{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005055 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005056 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005057 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005058
5059 try
5060 {
5061 if (index >= gl::MAX_VERTEX_ATTRIBS)
5062 {
5063 return error(GL_INVALID_VALUE);
5064 }
5065
5066 if (size < 1 || size > 4)
5067 {
5068 return error(GL_INVALID_VALUE);
5069 }
5070
5071 switch (type)
5072 {
5073 case GL_BYTE:
5074 case GL_UNSIGNED_BYTE:
5075 case GL_SHORT:
5076 case GL_UNSIGNED_SHORT:
5077 case GL_FIXED:
5078 case GL_FLOAT:
5079 break;
5080 default:
5081 return error(GL_INVALID_ENUM);
5082 }
5083
5084 if (stride < 0)
5085 {
5086 return error(GL_INVALID_VALUE);
5087 }
5088
5089 gl::Context *context = gl::getContext();
5090
5091 if (context)
5092 {
daniel@transgaming.com9ecb9f92010-07-28 19:21:12 +00005093 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005094 }
5095 }
5096 catch(std::bad_alloc&)
5097 {
5098 return error(GL_OUT_OF_MEMORY);
5099 }
5100}
5101
5102void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5103{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005104 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 +00005105
5106 try
5107 {
5108 if (width < 0 || height < 0)
5109 {
5110 return error(GL_INVALID_VALUE);
5111 }
5112
5113 gl::Context *context = gl::getContext();
5114
5115 if (context)
5116 {
daniel@transgaming.com428d1582010-05-04 03:35:25 +00005117 context->setViewportParams(x, y, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005118 }
5119 }
5120 catch(std::bad_alloc&)
5121 {
5122 return error(GL_OUT_OF_MEMORY);
5123 }
5124}
5125
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005126void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5127 GLbitfield mask, GLenum filter)
5128{
5129 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5130 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5131 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5132 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5133
5134 try
5135 {
5136 switch (filter)
5137 {
5138 case GL_NEAREST:
5139 break;
5140 default:
5141 return error(GL_INVALID_ENUM);
5142 }
5143
5144 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5145 {
5146 return error(GL_INVALID_VALUE);
5147 }
5148
5149 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5150 {
5151 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5152 return error(GL_INVALID_OPERATION);
5153 }
5154
5155 gl::Context *context = gl::getContext();
5156
5157 if (context)
5158 {
5159 if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5160 {
5161 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5162 return error(GL_INVALID_OPERATION);
5163 }
5164
5165 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5166 }
5167 }
5168 catch(std::bad_alloc&)
5169 {
5170 return error(GL_OUT_OF_MEMORY);
5171 }
5172}
5173
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005174void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5175 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005176{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00005177 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5178 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00005179 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005180 target, level, internalformat, width, height, depth, border, format, type, pixels);
5181
5182 try
5183 {
5184 UNIMPLEMENTED(); // FIXME
5185 }
5186 catch(std::bad_alloc&)
5187 {
5188 return error(GL_OUT_OF_MEMORY);
5189 }
5190}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005191
5192__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5193{
5194 struct Extension
5195 {
5196 const char *name;
5197 __eglMustCastToProperFunctionPointerType address;
5198 };
5199
5200 static const Extension glExtensions[] =
5201 {
5202 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
daniel@transgaming.com4cbc5902010-08-24 19:20:26 +00005203 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE}
daniel@transgaming.comce3d0f22010-05-04 03:35:14 +00005204 };
5205
5206 for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5207 {
5208 if (strcmp(procname, glExtensions[ext].name) == 0)
5209 {
5210 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5211 }
5212 }
5213
5214 return NULL;
5215}
5216
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00005217}