blob: fd81a9e83c0ae5805fde4f396f79e78c40d15e98 [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
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016#include "Context.h"
17#include "main.h"
18#include "Program.h"
19#include "Shader.h"
20#include "Buffer.h"
21#include "Texture.h"
22#include "Renderbuffer.h"
23#include "Framebuffer.h"
24#include "mathutil.h"
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000025#include "common/debug.h"
daniel@transgaming.com00c75962010-03-11 20:36:15 +000026#include "utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027
28extern "C"
29{
30
31void __stdcall glActiveTexture(GLenum texture)
32{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000033 TRACE("(GLenum texture = 0x%X)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034
35 try
36 {
37 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
38 {
39 return error(GL_INVALID_ENUM);
40 }
41
42 gl::Context *context = gl::getContext();
43
44 if (context)
45 {
46 context->activeSampler = texture - GL_TEXTURE0;
47 }
48 }
49 catch(std::bad_alloc&)
50 {
51 return error(GL_OUT_OF_MEMORY);
52 }
53}
54
55void __stdcall glAttachShader(GLuint program, GLuint shader)
56{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +000057 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000058
59 try
60 {
61 gl::Context *context = gl::getContext();
62
63 if (context)
64 {
65 gl::Program *programObject = context->getProgram(program);
66 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000067
daniel@transgaming.come2b22122010-03-11 19:22:14 +000068 if (!programObject || !shaderObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000069 {
70 return error(GL_INVALID_VALUE);
71 }
72
73 if (!programObject->attachShader(shaderObject))
74 {
75 return error(GL_INVALID_OPERATION);
76 }
77 }
78 }
79 catch(std::bad_alloc&)
80 {
81 return error(GL_OUT_OF_MEMORY);
82 }
83}
84
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +000085void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000086{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +000087 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000088
89 try
90 {
91 if (index >= gl::MAX_VERTEX_ATTRIBS)
92 {
93 return error(GL_INVALID_VALUE);
94 }
95
96 gl::Context *context = gl::getContext();
97
98 if (context)
99 {
100 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000101
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000102 if (!programObject)
103 {
104 return error(GL_INVALID_VALUE);
105 }
106
107 programObject->bindAttributeLocation(index, name);
108 }
109 }
110 catch(std::bad_alloc&)
111 {
112 return error(GL_OUT_OF_MEMORY);
113 }
114}
115
116void __stdcall glBindBuffer(GLenum target, GLuint buffer)
117{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000118 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000119
120 try
121 {
122 gl::Context *context = gl::getContext();
123
124 if (context)
125 {
126 switch (target)
127 {
128 case GL_ARRAY_BUFFER:
129 context->bindArrayBuffer(buffer);
130 return;
131 case GL_ELEMENT_ARRAY_BUFFER:
132 context->bindElementArrayBuffer(buffer);
133 return;
134 default:
135 return error(GL_INVALID_ENUM);
136 }
137 }
138 }
139 catch(std::bad_alloc&)
140 {
141 return error(GL_OUT_OF_MEMORY);
142 }
143}
144
145void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
146{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000147 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000148
149 try
150 {
151 if (target != GL_FRAMEBUFFER)
152 {
153 return error(GL_INVALID_ENUM);
154 }
155
156 gl::Context *context = gl::getContext();
157
158 if (context)
159 {
160 context->bindFramebuffer(framebuffer);
161 }
162 }
163 catch(std::bad_alloc&)
164 {
165 return error(GL_OUT_OF_MEMORY);
166 }
167}
168
169void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
170{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000171 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000172
173 try
174 {
175 if (target != GL_RENDERBUFFER)
176 {
177 return error(GL_INVALID_ENUM);
178 }
179
180 gl::Context *context = gl::getContext();
181
182 if (context)
183 {
184 context->bindRenderbuffer(renderbuffer);
185 }
186 }
187 catch(std::bad_alloc&)
188 {
189 return error(GL_OUT_OF_MEMORY);
190 }
191}
192
193void __stdcall glBindTexture(GLenum target, GLuint texture)
194{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000195 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000196
197 try
198 {
199 gl::Context *context = gl::getContext();
200
201 if (context)
202 {
203 gl::Texture *textureObject = context->getTexture(texture);
204
205 if (textureObject && textureObject->getTarget() != target && texture != 0)
206 {
207 return error(GL_INVALID_OPERATION);
208 }
209
210 switch (target)
211 {
212 case GL_TEXTURE_2D:
213 context->bindTexture2D(texture);
214 return;
215 case GL_TEXTURE_CUBE_MAP:
216 context->bindTextureCubeMap(texture);
217 return;
218 default:
219 return error(GL_INVALID_ENUM);
220 }
221 }
222 }
223 catch(std::bad_alloc&)
224 {
225 return error(GL_OUT_OF_MEMORY);
226 }
227}
228
229void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
230{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000231 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
232 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000233
234 try
235 {
236 gl::Context* context = gl::getContext();
237
238 if (context)
239 {
240 context->blendColor.red = gl::clamp01(red);
241 context->blendColor.blue = gl::clamp01(blue);
242 context->blendColor.green = gl::clamp01(green);
243 context->blendColor.alpha = gl::clamp01(alpha);
244 }
245 }
246 catch(std::bad_alloc&)
247 {
248 return error(GL_OUT_OF_MEMORY);
249 }
250}
251
252void __stdcall glBlendEquation(GLenum mode)
253{
254 glBlendEquationSeparate(mode, mode);
255}
256
257void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
258{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000259 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000260
261 try
262 {
263 switch (modeRGB)
264 {
265 case GL_FUNC_ADD:
266 case GL_FUNC_SUBTRACT:
267 case GL_FUNC_REVERSE_SUBTRACT:
268 break;
269 default:
270 return error(GL_INVALID_ENUM);
271 }
272
273 switch (modeAlpha)
274 {
275 case GL_FUNC_ADD:
276 case GL_FUNC_SUBTRACT:
277 case GL_FUNC_REVERSE_SUBTRACT:
278 break;
279 default:
280 return error(GL_INVALID_ENUM);
281 }
282
283 gl::Context *context = gl::getContext();
284
285 if (context)
286 {
287 context->blendEquationRGB = modeRGB;
288 context->blendEquationAlpha = modeAlpha;
289 }
290 }
291 catch(std::bad_alloc&)
292 {
293 return error(GL_OUT_OF_MEMORY);
294 }
295}
296
297void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
298{
299 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
300}
301
302void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
303{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000304 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
305 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000306
307 try
308 {
309 switch (srcRGB)
310 {
311 case GL_ZERO:
312 case GL_ONE:
313 case GL_SRC_COLOR:
314 case GL_ONE_MINUS_SRC_COLOR:
315 case GL_DST_COLOR:
316 case GL_ONE_MINUS_DST_COLOR:
317 case GL_SRC_ALPHA:
318 case GL_ONE_MINUS_SRC_ALPHA:
319 case GL_DST_ALPHA:
320 case GL_ONE_MINUS_DST_ALPHA:
321 case GL_CONSTANT_COLOR:
322 case GL_ONE_MINUS_CONSTANT_COLOR:
323 case GL_CONSTANT_ALPHA:
324 case GL_ONE_MINUS_CONSTANT_ALPHA:
325 case GL_SRC_ALPHA_SATURATE:
326 break;
327 default:
328 return error(GL_INVALID_ENUM);
329 }
330
331 switch (dstRGB)
332 {
333 case GL_ZERO:
334 case GL_ONE:
335 case GL_SRC_COLOR:
336 case GL_ONE_MINUS_SRC_COLOR:
337 case GL_DST_COLOR:
338 case GL_ONE_MINUS_DST_COLOR:
339 case GL_SRC_ALPHA:
340 case GL_ONE_MINUS_SRC_ALPHA:
341 case GL_DST_ALPHA:
342 case GL_ONE_MINUS_DST_ALPHA:
343 case GL_CONSTANT_COLOR:
344 case GL_ONE_MINUS_CONSTANT_COLOR:
345 case GL_CONSTANT_ALPHA:
346 case GL_ONE_MINUS_CONSTANT_ALPHA:
347 break;
348 default:
349 return error(GL_INVALID_ENUM);
350 }
351
352 switch (srcAlpha)
353 {
354 case GL_ZERO:
355 case GL_ONE:
356 case GL_SRC_COLOR:
357 case GL_ONE_MINUS_SRC_COLOR:
358 case GL_DST_COLOR:
359 case GL_ONE_MINUS_DST_COLOR:
360 case GL_SRC_ALPHA:
361 case GL_ONE_MINUS_SRC_ALPHA:
362 case GL_DST_ALPHA:
363 case GL_ONE_MINUS_DST_ALPHA:
364 case GL_CONSTANT_COLOR:
365 case GL_ONE_MINUS_CONSTANT_COLOR:
366 case GL_CONSTANT_ALPHA:
367 case GL_ONE_MINUS_CONSTANT_ALPHA:
368 case GL_SRC_ALPHA_SATURATE:
369 break;
370 default:
371 return error(GL_INVALID_ENUM);
372 }
373
374 switch (dstAlpha)
375 {
376 case GL_ZERO:
377 case GL_ONE:
378 case GL_SRC_COLOR:
379 case GL_ONE_MINUS_SRC_COLOR:
380 case GL_DST_COLOR:
381 case GL_ONE_MINUS_DST_COLOR:
382 case GL_SRC_ALPHA:
383 case GL_ONE_MINUS_SRC_ALPHA:
384 case GL_DST_ALPHA:
385 case GL_ONE_MINUS_DST_ALPHA:
386 case GL_CONSTANT_COLOR:
387 case GL_ONE_MINUS_CONSTANT_COLOR:
388 case GL_CONSTANT_ALPHA:
389 case GL_ONE_MINUS_CONSTANT_ALPHA:
390 break;
391 default:
392 return error(GL_INVALID_ENUM);
393 }
394
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000395 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
396 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
397
398 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
399 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
400
401 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000402 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000403 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
404 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000405 }
406
407 gl::Context *context = gl::getContext();
408
409 if (context)
410 {
411 context->sourceBlendRGB = srcRGB;
412 context->sourceBlendAlpha = srcAlpha;
413 context->destBlendRGB = dstRGB;
414 context->destBlendAlpha = dstAlpha;
415 }
416 }
417 catch(std::bad_alloc&)
418 {
419 return error(GL_OUT_OF_MEMORY);
420 }
421}
422
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000423void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000424{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000425 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 +0000426 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000427
428 try
429 {
430 if (size < 0)
431 {
432 return error(GL_INVALID_VALUE);
433 }
434
435 switch (usage)
436 {
437 case GL_STREAM_DRAW:
438 case GL_STATIC_DRAW:
439 case GL_DYNAMIC_DRAW:
440 break;
441 default:
442 return error(GL_INVALID_ENUM);
443 }
444
445 gl::Context *context = gl::getContext();
446
447 if (context)
448 {
449 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000450
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000451 switch (target)
452 {
453 case GL_ARRAY_BUFFER:
454 buffer = context->getArrayBuffer();
455 break;
456 case GL_ELEMENT_ARRAY_BUFFER:
457 buffer = context->getElementArrayBuffer();
458 break;
459 default:
460 return error(GL_INVALID_ENUM);
461 }
462
463 if (!buffer)
464 {
465 return error(GL_INVALID_OPERATION);
466 }
467
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000468 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000469 }
470 }
471 catch(std::bad_alloc&)
472 {
473 return error(GL_OUT_OF_MEMORY);
474 }
475}
476
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000477void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000478{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000479 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 +0000480 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000481
482 try
483 {
484 if (size < 0)
485 {
486 return error(GL_INVALID_VALUE);
487 }
488
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000489 if (data == NULL)
490 {
491 return;
492 }
493
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000494 gl::Context *context = gl::getContext();
495
496 if (context)
497 {
498 gl::Buffer *buffer;
499
500 switch (target)
501 {
502 case GL_ARRAY_BUFFER:
503 buffer = context->getArrayBuffer();
504 break;
505 case GL_ELEMENT_ARRAY_BUFFER:
506 buffer = context->getElementArrayBuffer();
507 break;
508 default:
509 return error(GL_INVALID_ENUM);
510 }
511
512 if (!buffer)
513 {
514 return error(GL_INVALID_OPERATION);
515 }
516
517 GLenum err = buffer->bufferSubData(data, size, offset);
518
519 if (err != GL_NO_ERROR)
520 {
521 return error(err);
522 }
523 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000524 }
525 catch(std::bad_alloc&)
526 {
527 return error(GL_OUT_OF_MEMORY);
528 }
529}
530
531GLenum __stdcall glCheckFramebufferStatus(GLenum target)
532{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000533 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000534
535 try
536 {
537 if (target != GL_FRAMEBUFFER)
538 {
539 return error(GL_INVALID_ENUM, 0);
540 }
541
542 gl::Context *context = gl::getContext();
543
544 if (context)
545 {
546 gl::Framebuffer *framebuffer = context->getFramebuffer();
547
548 return framebuffer->completeness();
549 }
550 }
551 catch(std::bad_alloc&)
552 {
553 return error(GL_OUT_OF_MEMORY, 0);
554 }
555
556 return 0;
557}
558
559void __stdcall glClear(GLbitfield mask)
560{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000561 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000562
563 try
564 {
565 gl::Context *context = gl::getContext();
566
567 if (context)
568 {
569 context->clear(mask);
570 }
571 }
572 catch(std::bad_alloc&)
573 {
574 return error(GL_OUT_OF_MEMORY);
575 }
576}
577
578void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
579{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000580 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
581 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000582
583 try
584 {
585 gl::Context *context = gl::getContext();
586
587 if (context)
588 {
589 context->setClearColor(red, green, blue, alpha);
590 }
591 }
592 catch(std::bad_alloc&)
593 {
594 return error(GL_OUT_OF_MEMORY);
595 }
596}
597
598void __stdcall glClearDepthf(GLclampf depth)
599{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000600 TRACE("(GLclampf depth = %f)", depth);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000601
602 try
603 {
604 gl::Context *context = gl::getContext();
605
606 if (context)
607 {
608 context->setClearDepth(depth);
609 }
610 }
611 catch(std::bad_alloc&)
612 {
613 return error(GL_OUT_OF_MEMORY);
614 }
615}
616
617void __stdcall glClearStencil(GLint s)
618{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000619 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000620
621 try
622 {
623 gl::Context *context = gl::getContext();
624
625 if (context)
626 {
627 context->setClearStencil(s);
628 }
629 }
630 catch(std::bad_alloc&)
631 {
632 return error(GL_OUT_OF_MEMORY);
633 }
634}
635
636void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
637{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000638 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
639 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000640
641 try
642 {
643 gl::Context *context = gl::getContext();
644
645 if (context)
646 {
647 context->colorMaskRed = red != GL_FALSE;
648 context->colorMaskGreen = green != GL_FALSE;
649 context->colorMaskBlue = blue != GL_FALSE;
650 context->colorMaskAlpha = alpha != GL_FALSE;
651 }
652 }
653 catch(std::bad_alloc&)
654 {
655 return error(GL_OUT_OF_MEMORY);
656 }
657}
658
659void __stdcall glCompileShader(GLuint shader)
660{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000661 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000662
663 try
664 {
665 gl::Context *context = gl::getContext();
666
667 if (context)
668 {
669 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000670
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000671 if (!shaderObject)
672 {
673 return error(GL_INVALID_VALUE);
674 }
675
676 shaderObject->compile();
677 }
678 }
679 catch(std::bad_alloc&)
680 {
681 return error(GL_OUT_OF_MEMORY);
682 }
683}
684
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000685void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
686 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000687{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000688 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000689 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000690 target, level, internalformat, width, height, border, imageSize, data);
691
692 try
693 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000694 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
695 {
696 return error(GL_INVALID_ENUM);
697 }
698
699 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000700 {
701 return error(GL_INVALID_VALUE);
702 }
703
daniel@transgaming.com41430492010-03-11 20:36:18 +0000704 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
705 {
706 return error(GL_INVALID_VALUE);
707 }
708
709 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000710 }
711 catch(std::bad_alloc&)
712 {
713 return error(GL_OUT_OF_MEMORY);
714 }
715}
716
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000717void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
718 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000719{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000720 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
721 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000722 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000723 target, level, xoffset, yoffset, width, height, format, imageSize, data);
724
725 try
726 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000727 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
728 {
729 return error(GL_INVALID_ENUM);
730 }
731
732 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000733 {
734 return error(GL_INVALID_VALUE);
735 }
736
daniel@transgaming.com41430492010-03-11 20:36:18 +0000737 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
738 {
739 return error(GL_INVALID_VALUE);
740 }
741
742 if (xoffset != 0 || yoffset != 0)
743 {
744 return error(GL_INVALID_OPERATION);
745 }
746
747 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000748 }
749 catch(std::bad_alloc&)
750 {
751 return error(GL_OUT_OF_MEMORY);
752 }
753}
754
755void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
756{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000757 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
758 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000759 target, level, internalformat, x, y, width, height, border);
760
761 try
762 {
763 if (width < 0 || height < 0)
764 {
765 return error(GL_INVALID_VALUE);
766 }
767
768 UNIMPLEMENTED(); // FIXME
769 }
770 catch(std::bad_alloc&)
771 {
772 return error(GL_OUT_OF_MEMORY);
773 }
774}
775
776void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
777{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000778 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
779 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000780 target, level, xoffset, yoffset, x, y, width, height);
781
782 try
783 {
784 if (width < 0 || height < 0)
785 {
786 return error(GL_INVALID_VALUE);
787 }
788
789 UNIMPLEMENTED(); // FIXME
790 }
791 catch(std::bad_alloc&)
792 {
793 return error(GL_OUT_OF_MEMORY);
794 }
795}
796
797GLuint __stdcall glCreateProgram(void)
798{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000799 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000800
801 try
802 {
803 gl::Context *context = gl::getContext();
804
805 if (context)
806 {
807 return context->createProgram();
808 }
809 }
810 catch(std::bad_alloc&)
811 {
812 return error(GL_OUT_OF_MEMORY, 0);
813 }
814
815 return 0;
816}
817
818GLuint __stdcall glCreateShader(GLenum type)
819{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000820 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000821
822 try
823 {
824 gl::Context *context = gl::getContext();
825
826 if (context)
827 {
828 switch (type)
829 {
830 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000831 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000832 return context->createShader(type);
833 default:
834 return error(GL_INVALID_ENUM, 0);
835 }
836 }
837 }
838 catch(std::bad_alloc&)
839 {
840 return error(GL_OUT_OF_MEMORY, 0);
841 }
842
843 return 0;
844}
845
846void __stdcall glCullFace(GLenum mode)
847{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000848 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000849
850 try
851 {
852 switch (mode)
853 {
854 case GL_FRONT:
855 case GL_BACK:
856 case GL_FRONT_AND_BACK:
857 {
858 gl::Context *context = gl::getContext();
859
860 if (context)
861 {
862 context->cullMode = mode;
863 }
864 }
865 break;
866 default:
867 return error(GL_INVALID_ENUM);
868 }
869 }
870 catch(std::bad_alloc&)
871 {
872 return error(GL_OUT_OF_MEMORY);
873 }
874}
875
876void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
877{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000878 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000879
880 try
881 {
882 if (n < 0)
883 {
884 return error(GL_INVALID_VALUE);
885 }
886
887 gl::Context *context = gl::getContext();
888
889 if (context)
890 {
891 for (int i = 0; i < n; i++)
892 {
893 context->deleteBuffer(buffers[i]);
894 }
895 }
896 }
897 catch(std::bad_alloc&)
898 {
899 return error(GL_OUT_OF_MEMORY);
900 }
901}
902
903void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
904{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000905 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000906
907 try
908 {
909 if (n < 0)
910 {
911 return error(GL_INVALID_VALUE);
912 }
913
914 gl::Context *context = gl::getContext();
915
916 if (context)
917 {
918 for (int i = 0; i < n; i++)
919 {
920 if (framebuffers[i] != 0)
921 {
922 context->deleteFramebuffer(framebuffers[i]);
923 }
924 }
925 }
926 }
927 catch(std::bad_alloc&)
928 {
929 return error(GL_OUT_OF_MEMORY);
930 }
931}
932
933void __stdcall glDeleteProgram(GLuint program)
934{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000935 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000936
937 try
938 {
939 gl::Context *context = gl::getContext();
940
941 if (context)
942 {
943 context->deleteProgram(program);
944 }
945 }
946 catch(std::bad_alloc&)
947 {
948 return error(GL_OUT_OF_MEMORY);
949 }
950}
951
952void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
953{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000954 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000955
956 try
957 {
958 if (n < 0)
959 {
960 return error(GL_INVALID_VALUE);
961 }
962
963 gl::Context *context = gl::getContext();
964
965 if (context)
966 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +0000967 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000968 {
969 context->deleteRenderbuffer(renderbuffers[i]);
970 }
971 }
972 }
973 catch(std::bad_alloc&)
974 {
975 return error(GL_OUT_OF_MEMORY);
976 }
977}
978
979void __stdcall glDeleteShader(GLuint shader)
980{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000981 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000982
983 try
984 {
985 gl::Context *context = gl::getContext();
986
987 if (context)
988 {
989 context->deleteShader(shader);
990 }
991 }
992 catch(std::bad_alloc&)
993 {
994 return error(GL_OUT_OF_MEMORY);
995 }
996}
997
998void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
999{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001000 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001001
1002 try
1003 {
1004 if (n < 0)
1005 {
1006 return error(GL_INVALID_VALUE);
1007 }
1008
1009 gl::Context *context = gl::getContext();
1010
1011 if (context)
1012 {
1013 for (int i = 0; i < n; i++)
1014 {
1015 if (textures[i] != 0)
1016 {
1017 context->deleteTexture(textures[i]);
1018 }
1019 }
1020 }
1021 }
1022 catch(std::bad_alloc&)
1023 {
1024 return error(GL_OUT_OF_MEMORY);
1025 }
1026}
1027
1028void __stdcall glDepthFunc(GLenum func)
1029{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001030 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001031
1032 try
1033 {
1034 switch (func)
1035 {
1036 case GL_NEVER:
1037 case GL_ALWAYS:
1038 case GL_LESS:
1039 case GL_LEQUAL:
1040 case GL_EQUAL:
1041 case GL_GREATER:
1042 case GL_GEQUAL:
1043 case GL_NOTEQUAL:
1044 break;
1045 default:
1046 return error(GL_INVALID_ENUM);
1047 }
1048
1049 gl::Context *context = gl::getContext();
1050
1051 if (context)
1052 {
1053 context->depthFunc = func;
1054 }
1055 }
1056 catch(std::bad_alloc&)
1057 {
1058 return error(GL_OUT_OF_MEMORY);
1059 }
1060}
1061
1062void __stdcall glDepthMask(GLboolean flag)
1063{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001064 TRACE("(GLboolean flag = %d)", flag);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001065
1066 try
1067 {
1068 gl::Context *context = gl::getContext();
1069
1070 if (context)
1071 {
1072 context->depthMask = flag != GL_FALSE;
1073 }
1074 }
1075 catch(std::bad_alloc&)
1076 {
1077 return error(GL_OUT_OF_MEMORY);
1078 }
1079}
1080
1081void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1082{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001083 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001084
1085 try
1086 {
1087 gl::Context *context = gl::getContext();
1088
1089 if (context)
1090 {
1091 context->zNear = zNear;
1092 context->zFar = zFar;
1093 }
1094 }
1095 catch(std::bad_alloc&)
1096 {
1097 return error(GL_OUT_OF_MEMORY);
1098 }
1099}
1100
1101void __stdcall glDetachShader(GLuint program, GLuint shader)
1102{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001103 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001104
1105 try
1106 {
1107 gl::Context *context = gl::getContext();
1108
1109 if (context)
1110 {
1111 gl::Program *programObject = context->getProgram(program);
1112 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00001113
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001114 if (!programObject || !shaderObject)
1115 {
1116 return error(GL_INVALID_VALUE);
1117 }
1118
1119 if (!programObject->detachShader(shaderObject))
1120 {
1121 return error(GL_INVALID_OPERATION);
1122 }
1123
1124 if (shaderObject->isDeletable())
1125 {
1126 context->deleteShader(shader);
1127 }
1128 }
1129 }
1130 catch(std::bad_alloc&)
1131 {
1132 return error(GL_OUT_OF_MEMORY);
1133 }
1134}
1135
1136void __stdcall glDisable(GLenum cap)
1137{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001138 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001139
1140 try
1141 {
1142 gl::Context *context = gl::getContext();
1143
1144 if (context)
1145 {
1146 switch (cap)
1147 {
1148 case GL_CULL_FACE: context->cullFace = false; break;
1149 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1150 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1151 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1152 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1153 case GL_STENCIL_TEST: context->stencilTest = false; break;
1154 case GL_DEPTH_TEST: context->depthTest = false; break;
1155 case GL_BLEND: context->blend = false; break;
1156 case GL_DITHER: context->dither = false; break;
1157 default:
1158 return error(GL_INVALID_ENUM);
1159 }
1160 }
1161 }
1162 catch(std::bad_alloc&)
1163 {
1164 return error(GL_OUT_OF_MEMORY);
1165 }
1166}
1167
1168void __stdcall glDisableVertexAttribArray(GLuint index)
1169{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001170 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001171
1172 try
1173 {
1174 if (index >= gl::MAX_VERTEX_ATTRIBS)
1175 {
1176 return error(GL_INVALID_VALUE);
1177 }
1178
1179 gl::Context *context = gl::getContext();
1180
1181 if (context)
1182 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001183 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001184 }
1185 }
1186 catch(std::bad_alloc&)
1187 {
1188 return error(GL_OUT_OF_MEMORY);
1189 }
1190}
1191
1192void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1193{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001194 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001195
1196 try
1197 {
1198 if (count < 0 || first < 0)
1199 {
1200 return error(GL_INVALID_VALUE);
1201 }
1202
1203 gl::Context *context = gl::getContext();
1204
1205 if (context)
1206 {
1207 context->drawArrays(mode, first, count);
1208 }
1209 }
1210 catch(std::bad_alloc&)
1211 {
1212 return error(GL_OUT_OF_MEMORY);
1213 }
1214}
1215
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001216void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001217{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001218 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 +00001219 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001220
1221 try
1222 {
1223 if (count < 0)
1224 {
1225 return error(GL_INVALID_VALUE);
1226 }
1227
1228 switch (type)
1229 {
1230 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001231 case GL_UNSIGNED_SHORT:
1232 break;
1233 default:
1234 return error(GL_INVALID_ENUM);
1235 }
1236
1237 gl::Context *context = gl::getContext();
1238
1239 if (context)
1240 {
1241 context->drawElements(mode, count, type, indices);
1242 }
1243 }
1244 catch(std::bad_alloc&)
1245 {
1246 return error(GL_OUT_OF_MEMORY);
1247 }
1248}
1249
1250void __stdcall glEnable(GLenum cap)
1251{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001252 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001253
1254 try
1255 {
1256 gl::Context *context = gl::getContext();
1257
1258 if (context)
1259 {
1260 switch (cap)
1261 {
1262 case GL_CULL_FACE: context->cullFace = true; break;
1263 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1264 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1265 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1266 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1267 case GL_STENCIL_TEST: context->stencilTest = true; break;
1268 case GL_DEPTH_TEST: context->depthTest = true; break;
1269 case GL_BLEND: context->blend = true; break;
1270 case GL_DITHER: context->dither = true; break;
1271 default:
1272 return error(GL_INVALID_ENUM);
1273 }
1274 }
1275 }
1276 catch(std::bad_alloc&)
1277 {
1278 return error(GL_OUT_OF_MEMORY);
1279 }
1280}
1281
1282void __stdcall glEnableVertexAttribArray(GLuint index)
1283{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001284 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001285
1286 try
1287 {
1288 if (index >= gl::MAX_VERTEX_ATTRIBS)
1289 {
1290 return error(GL_INVALID_VALUE);
1291 }
1292
1293 gl::Context *context = gl::getContext();
1294
1295 if (context)
1296 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001297 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001298 }
1299 }
1300 catch(std::bad_alloc&)
1301 {
1302 return error(GL_OUT_OF_MEMORY);
1303 }
1304}
1305
1306void __stdcall glFinish(void)
1307{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001308 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001309
1310 try
1311 {
1312 gl::Context *context = gl::getContext();
1313
1314 if (context)
1315 {
1316 context->finish();
1317 }
1318 }
1319 catch(std::bad_alloc&)
1320 {
1321 return error(GL_OUT_OF_MEMORY);
1322 }
1323}
1324
1325void __stdcall glFlush(void)
1326{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001327 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001328
1329 try
1330 {
1331 gl::Context *context = gl::getContext();
1332
1333 if (context)
1334 {
1335 context->flush();
1336 }
1337 }
1338 catch(std::bad_alloc&)
1339 {
1340 return error(GL_OUT_OF_MEMORY);
1341 }
1342}
1343
1344void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1345{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001346 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1347 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001348
1349 try
1350 {
1351 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1352 {
1353 return error(GL_INVALID_ENUM);
1354 }
1355
1356 gl::Context *context = gl::getContext();
1357
1358 if (context)
1359 {
1360 gl::Framebuffer *framebuffer = context->getFramebuffer();
1361
1362 if (context->framebuffer == 0 || !framebuffer)
1363 {
1364 return error(GL_INVALID_OPERATION);
1365 }
1366
1367 switch (attachment)
1368 {
1369 case GL_COLOR_ATTACHMENT0:
1370 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1371 break;
1372 case GL_DEPTH_ATTACHMENT:
1373 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1374 break;
1375 case GL_STENCIL_ATTACHMENT:
1376 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1377 break;
1378 default:
1379 return error(GL_INVALID_ENUM);
1380 }
1381 }
1382 }
1383 catch(std::bad_alloc&)
1384 {
1385 return error(GL_OUT_OF_MEMORY);
1386 }
1387}
1388
1389void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1390{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001391 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1392 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001393
1394 try
1395 {
1396 if (target != GL_FRAMEBUFFER)
1397 {
1398 return error(GL_INVALID_ENUM);
1399 }
1400
1401 switch (attachment)
1402 {
1403 case GL_COLOR_ATTACHMENT0:
1404 break;
1405 default:
1406 return error(GL_INVALID_ENUM);
1407 }
1408
1409 gl::Context *context = gl::getContext();
1410
1411 if (context)
1412 {
1413 if (texture)
1414 {
1415 switch (textarget)
1416 {
1417 case GL_TEXTURE_2D:
1418 if (!context->getTexture2D())
1419 {
1420 return error(GL_INVALID_OPERATION);
1421 }
1422 break;
1423 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1424 UNIMPLEMENTED(); // FIXME
1425 break;
1426 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1427 UNIMPLEMENTED(); // FIXME
1428 break;
1429 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1430 UNIMPLEMENTED(); // FIXME
1431 break;
1432 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1433 UNIMPLEMENTED(); // FIXME
1434 break;
1435 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1436 UNIMPLEMENTED(); // FIXME
1437 break;
1438 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1439 UNIMPLEMENTED(); // FIXME
1440 break;
1441 default:
1442 return error(GL_INVALID_ENUM);
1443 }
1444
1445 if (level != 0)
1446 {
1447 return error(GL_INVALID_VALUE);
1448 }
1449 }
1450
1451 gl::Framebuffer *framebuffer = context->getFramebuffer();
1452
1453 if (context->framebuffer == 0 || !framebuffer)
1454 {
1455 return error(GL_INVALID_OPERATION);
1456 }
1457
1458 framebuffer->setColorbuffer(GL_TEXTURE, texture);
1459 }
1460 }
1461 catch(std::bad_alloc&)
1462 {
1463 return error(GL_OUT_OF_MEMORY);
1464 }
1465}
1466
1467void __stdcall glFrontFace(GLenum mode)
1468{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001469 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001470
1471 try
1472 {
1473 switch (mode)
1474 {
1475 case GL_CW:
1476 case GL_CCW:
1477 {
1478 gl::Context *context = gl::getContext();
1479
1480 if (context)
1481 {
1482 context->frontFace = mode;
1483 }
1484 }
1485 break;
1486 default:
1487 return error(GL_INVALID_ENUM);
1488 }
1489 }
1490 catch(std::bad_alloc&)
1491 {
1492 return error(GL_OUT_OF_MEMORY);
1493 }
1494}
1495
1496void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1497{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001498 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001499
1500 try
1501 {
1502 if (n < 0)
1503 {
1504 return error(GL_INVALID_VALUE);
1505 }
1506
1507 gl::Context *context = gl::getContext();
1508
1509 if (context)
1510 {
1511 for (int i = 0; i < n; i++)
1512 {
1513 buffers[i] = context->createBuffer();
1514 }
1515 }
1516 }
1517 catch(std::bad_alloc&)
1518 {
1519 return error(GL_OUT_OF_MEMORY);
1520 }
1521}
1522
1523void __stdcall glGenerateMipmap(GLenum target)
1524{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001525 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001526
1527 try
1528 {
1529 UNIMPLEMENTED(); // FIXME
1530 }
1531 catch(std::bad_alloc&)
1532 {
1533 return error(GL_OUT_OF_MEMORY);
1534 }
1535}
1536
1537void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1538{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001539 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001540
1541 try
1542 {
1543 if (n < 0)
1544 {
1545 return error(GL_INVALID_VALUE);
1546 }
1547
1548 gl::Context *context = gl::getContext();
1549
1550 if (context)
1551 {
1552 for (int i = 0; i < n; i++)
1553 {
1554 framebuffers[i] = context->createFramebuffer();
1555 }
1556 }
1557 }
1558 catch(std::bad_alloc&)
1559 {
1560 return error(GL_OUT_OF_MEMORY);
1561 }
1562}
1563
1564void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1565{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001566 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001567
1568 try
1569 {
1570 if (n < 0)
1571 {
1572 return error(GL_INVALID_VALUE);
1573 }
1574
1575 gl::Context *context = gl::getContext();
1576
1577 if (context)
1578 {
1579 for (int i = 0; i < n; i++)
1580 {
1581 renderbuffers[i] = context->createRenderbuffer();
1582 }
1583 }
1584 }
1585 catch(std::bad_alloc&)
1586 {
1587 return error(GL_OUT_OF_MEMORY);
1588 }
1589}
1590
1591void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1592{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001593 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001594
1595 try
1596 {
1597 if (n < 0)
1598 {
1599 return error(GL_INVALID_VALUE);
1600 }
1601
1602 gl::Context *context = gl::getContext();
1603
1604 if (context)
1605 {
1606 for (int i = 0; i < n; i++)
1607 {
1608 textures[i] = context->createTexture();
1609 }
1610 }
1611 }
1612 catch(std::bad_alloc&)
1613 {
1614 return error(GL_OUT_OF_MEMORY);
1615 }
1616}
1617
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001618void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001619{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001620 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001621 "GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001622 program, index, bufsize, length, size, type, name);
1623
1624 try
1625 {
1626 if (bufsize < 0)
1627 {
1628 return error(GL_INVALID_VALUE);
1629 }
1630
1631 UNIMPLEMENTED(); // FIXME
1632 }
1633 catch(std::bad_alloc&)
1634 {
1635 return error(GL_OUT_OF_MEMORY);
1636 }
1637}
1638
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001639void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001640{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001641 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001642 "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 +00001643 program, index, bufsize, length, size, type, name);
1644
1645 try
1646 {
1647 if (bufsize < 0)
1648 {
1649 return error(GL_INVALID_VALUE);
1650 }
1651
1652 UNIMPLEMENTED(); // FIXME
1653 }
1654 catch(std::bad_alloc&)
1655 {
1656 return error(GL_OUT_OF_MEMORY);
1657 }
1658}
1659
1660void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1661{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001662 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1663 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001664
1665 try
1666 {
1667 if (maxcount < 0)
1668 {
1669 return error(GL_INVALID_VALUE);
1670 }
1671
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001672 gl::Context *context = gl::getContext();
1673
1674 if (context)
1675 {
1676 gl::Program *programObject = context->getProgram(program);
1677
1678 if (!programObject)
1679 {
1680 return error(GL_INVALID_VALUE);
1681 }
1682
1683 return programObject->getAttachedShaders(maxcount, count, shaders);
1684 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001685 }
1686 catch(std::bad_alloc&)
1687 {
1688 return error(GL_OUT_OF_MEMORY);
1689 }
1690}
1691
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001692int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001693{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001694 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001695
1696 try
1697 {
1698 gl::Context *context = gl::getContext();
1699
1700 if (context)
1701 {
1702 gl::Program *programObject = context->getProgram(program);
1703
1704 if (!programObject)
1705 {
1706 return error(GL_INVALID_VALUE, -1);
1707 }
1708
1709 return programObject->getAttributeLocation(name);
1710 }
1711 }
1712 catch(std::bad_alloc&)
1713 {
1714 return error(GL_OUT_OF_MEMORY, -1);
1715 }
1716
1717 return -1;
1718}
1719
1720void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1721{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001722 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001723
1724 try
1725 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001726 gl::Context *context = gl::getContext();
1727
1728 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001729 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001730 if (!(context->getBooleanv(pname, params)))
1731 {
1732 GLenum nativeType;
1733 unsigned int numParams = 0;
1734 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1735 return error(GL_INVALID_ENUM);
1736
1737 if (numParams == 0)
1738 return; // it is known that the pname is valid, but there are no parameters to return
1739
1740 if (nativeType == GL_FLOAT)
1741 {
1742 GLfloat *floatParams = NULL;
1743 floatParams = new GLfloat[numParams];
1744
1745 context->getFloatv(pname, floatParams);
1746
1747 for (unsigned int i = 0; i < numParams; ++i)
1748 {
1749 if (floatParams[i] == 0.0f)
1750 params[i] = GL_FALSE;
1751 else
1752 params[i] = GL_TRUE;
1753 }
1754
1755 delete [] floatParams;
1756 }
1757 else if (nativeType == GL_INT)
1758 {
1759 GLint *intParams = NULL;
1760 intParams = new GLint[numParams];
1761
1762 context->getIntegerv(pname, intParams);
1763
1764 for (unsigned int i = 0; i < numParams; ++i)
1765 {
1766 if (intParams[i] == 0)
1767 params[i] = GL_FALSE;
1768 else
1769 params[i] = GL_TRUE;
1770 }
1771
1772 delete [] intParams;
1773 }
1774 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001775 }
1776 }
1777 catch(std::bad_alloc&)
1778 {
1779 return error(GL_OUT_OF_MEMORY);
1780 }
1781}
1782
1783void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1784{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001785 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 +00001786
1787 try
1788 {
1789 UNIMPLEMENTED(); // FIXME
1790 }
1791 catch(std::bad_alloc&)
1792 {
1793 return error(GL_OUT_OF_MEMORY);
1794 }
1795}
1796
1797GLenum __stdcall glGetError(void)
1798{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001799 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001800
1801 gl::Context *context = gl::getContext();
1802
1803 if (context)
1804 {
1805 return context->getError();
1806 }
1807
1808 return GL_NO_ERROR;
1809}
1810
1811void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
1812{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001813 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001814
1815 try
1816 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001817 gl::Context *context = gl::getContext();
1818
1819 if (context)
1820 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001821 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001822 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001823 GLenum nativeType;
1824 unsigned int numParams = 0;
1825 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1826 return error(GL_INVALID_ENUM);
1827
1828 if (numParams == 0)
1829 return; // it is known that the pname is valid, but that there are no parameters to return.
1830
1831 if (nativeType == GL_BOOL)
1832 {
1833 GLboolean *boolParams = NULL;
1834 boolParams = new GLboolean[numParams];
1835
1836 context->getBooleanv(pname, boolParams);
1837
1838 for (unsigned int i = 0; i < numParams; ++i)
1839 {
1840 if (boolParams[i] == GL_FALSE)
1841 params[i] = 0.0f;
1842 else
1843 params[i] = 1.0f;
1844 }
1845
1846 delete [] boolParams;
1847 }
1848 else if (nativeType == GL_INT)
1849 {
1850 GLint *intParams = NULL;
1851 intParams = new GLint[numParams];
1852
1853 context->getIntegerv(pname, intParams);
1854
1855 for (unsigned int i = 0; i < numParams; ++i)
1856 {
1857 params[i] = (GLfloat)intParams[i];
1858 }
1859
1860 delete [] intParams;
1861 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001862 }
1863 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001864 }
1865 catch(std::bad_alloc&)
1866 {
1867 return error(GL_OUT_OF_MEMORY);
1868 }
1869}
1870
1871void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
1872{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001873 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
1874 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001875
1876 try
1877 {
1878 gl::Context *context = gl::getContext();
1879
1880 if (context)
1881 {
1882 if (context->framebuffer == 0)
1883 {
1884 return error(GL_INVALID_OPERATION);
1885 }
1886
1887 UNIMPLEMENTED(); // FIXME
1888 }
1889 }
1890 catch(std::bad_alloc&)
1891 {
1892 return error(GL_OUT_OF_MEMORY);
1893 }
1894}
1895
1896void __stdcall glGetIntegerv(GLenum pname, GLint* params)
1897{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001898 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001899
1900 try
1901 {
1902 gl::Context *context = gl::getContext();
1903
1904 if (context)
1905 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001906 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001907 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001908 GLenum nativeType;
1909 unsigned int numParams = 0;
1910 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1911 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001912
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001913 if (numParams == 0)
1914 return; // it is known that pname is valid, but there are no parameters to return
1915
1916 if (nativeType == GL_BOOL)
1917 {
1918 GLboolean *boolParams = NULL;
1919 boolParams = new GLboolean[numParams];
1920
1921 context->getBooleanv(pname, boolParams);
1922
1923 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001924 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001925 if (boolParams[i] == GL_FALSE)
1926 params[i] = 0;
1927 else
1928 params[i] = 1;
1929 }
1930
1931 delete [] boolParams;
1932 }
1933 else if (nativeType == GL_FLOAT)
1934 {
1935 GLfloat *floatParams = NULL;
1936 floatParams = new GLfloat[numParams];
1937
1938 context->getFloatv(pname, floatParams);
1939
1940 for (unsigned int i = 0; i < numParams; ++i)
1941 {
1942 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001943 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001944 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001945 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001946 else
1947 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 +00001948 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001949
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001950 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001951 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001952 }
1953 }
1954 }
1955 catch(std::bad_alloc&)
1956 {
1957 return error(GL_OUT_OF_MEMORY);
1958 }
1959}
1960
1961void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
1962{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001963 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001964
1965 try
1966 {
1967 gl::Context *context = gl::getContext();
1968
1969 if (context)
1970 {
1971 gl::Program *programObject = context->getProgram(program);
1972
1973 if (!programObject)
1974 {
1975 return error(GL_INVALID_VALUE);
1976 }
1977
1978 switch (pname)
1979 {
1980 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00001981 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001982 return;
1983 case GL_LINK_STATUS:
1984 *params = programObject->isLinked();
1985 return;
1986 case GL_VALIDATE_STATUS:
1987 UNIMPLEMENTED(); // FIXME
1988 *params = GL_TRUE;
1989 return;
1990 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00001991 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001992 return;
1993 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00001994 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001995 return;
1996 case GL_ACTIVE_ATTRIBUTES:
1997 UNIMPLEMENTED(); // FIXME
1998 *params = 0;
1999 return;
2000 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2001 UNIMPLEMENTED(); // FIXME
2002 *params = 0;
2003 return;
2004 case GL_ACTIVE_UNIFORMS:
2005 UNIMPLEMENTED(); // FIXME
2006 *params = 0;
2007 return;
2008 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2009 UNIMPLEMENTED(); // FIXME
2010 *params = 0;
2011 return;
2012 default:
2013 return error(GL_INVALID_ENUM);
2014 }
2015 }
2016 }
2017 catch(std::bad_alloc&)
2018 {
2019 return error(GL_OUT_OF_MEMORY);
2020 }
2021}
2022
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002023void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002024{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002025 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 +00002026 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002027
2028 try
2029 {
2030 if (bufsize < 0)
2031 {
2032 return error(GL_INVALID_VALUE);
2033 }
2034
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002035 gl::Context *context = gl::getContext();
2036
2037 if (context)
2038 {
2039 gl::Program *programObject = context->getProgram(program);
2040
2041 if (!programObject)
2042 {
2043 return error(GL_INVALID_VALUE);
2044 }
2045
2046 programObject->getInfoLog(bufsize, length, infolog);
2047 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002048 }
2049 catch(std::bad_alloc&)
2050 {
2051 return error(GL_OUT_OF_MEMORY);
2052 }
2053}
2054
2055void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2056{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002057 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 +00002058
2059 try
2060 {
2061 UNIMPLEMENTED(); // FIXME
2062 }
2063 catch(std::bad_alloc&)
2064 {
2065 return error(GL_OUT_OF_MEMORY);
2066 }
2067}
2068
2069void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2070{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002071 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002072
2073 try
2074 {
2075 gl::Context *context = gl::getContext();
2076
2077 if (context)
2078 {
2079 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002080
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002081 if (!shaderObject)
2082 {
2083 return error(GL_INVALID_VALUE);
2084 }
2085
2086 switch (pname)
2087 {
2088 case GL_SHADER_TYPE:
2089 *params = shaderObject->getType();
2090 return;
2091 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002092 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002093 return;
2094 case GL_COMPILE_STATUS:
2095 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2096 return;
2097 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002098 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002099 return;
2100 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002101 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002102 return;
2103 default:
2104 return error(GL_INVALID_ENUM);
2105 }
2106 }
2107 }
2108 catch(std::bad_alloc&)
2109 {
2110 return error(GL_OUT_OF_MEMORY);
2111 }
2112}
2113
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002114void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002115{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002116 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 +00002117 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002118
2119 try
2120 {
2121 if (bufsize < 0)
2122 {
2123 return error(GL_INVALID_VALUE);
2124 }
2125
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002126 gl::Context *context = gl::getContext();
2127
2128 if (context)
2129 {
2130 gl::Shader *shaderObject = context->getShader(shader);
2131
2132 if (!shaderObject)
2133 {
2134 return error(GL_INVALID_VALUE);
2135 }
2136
2137 shaderObject->getInfoLog(bufsize, length, infolog);
2138 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002139 }
2140 catch(std::bad_alloc&)
2141 {
2142 return error(GL_OUT_OF_MEMORY);
2143 }
2144}
2145
2146void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2147{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002148 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2149 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002150
2151 try
2152 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002153 switch (shadertype)
2154 {
2155 case GL_VERTEX_SHADER:
2156 case GL_FRAGMENT_SHADER:
2157 break;
2158 default:
2159 return error(GL_INVALID_ENUM);
2160 }
2161
2162 switch (precisiontype)
2163 {
2164 case GL_LOW_FLOAT:
2165 case GL_MEDIUM_FLOAT:
2166 case GL_HIGH_FLOAT:
2167 // Assume IEEE 754 precision
2168 range[0] = 127;
2169 range[1] = 127;
2170 precision[0] = 23;
2171 precision[1] = 23;
2172 break;
2173 case GL_LOW_INT:
2174 case GL_MEDIUM_INT:
2175 case GL_HIGH_INT:
2176 // Some (most) hardware only supports single-precision floating-point numbers,
2177 // which can accurately represent integers up to +/-16777216
2178 range[0] = 24;
2179 range[1] = 24;
2180 precision[0] = 0;
2181 precision[1] = 0;
2182 break;
2183 default:
2184 return error(GL_INVALID_ENUM);
2185 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002186 }
2187 catch(std::bad_alloc&)
2188 {
2189 return error(GL_OUT_OF_MEMORY);
2190 }
2191}
2192
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002193void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002194{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002195 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 +00002196 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002197
2198 try
2199 {
2200 if (bufsize < 0)
2201 {
2202 return error(GL_INVALID_VALUE);
2203 }
2204
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002205 gl::Context *context = gl::getContext();
2206
2207 if (context)
2208 {
2209 gl::Shader *shaderObject = context->getShader(shader);
2210
2211 if (!shaderObject)
2212 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002213 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002214 }
2215
2216 shaderObject->getSource(bufsize, length, source);
2217 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002218 }
2219 catch(std::bad_alloc&)
2220 {
2221 return error(GL_OUT_OF_MEMORY);
2222 }
2223}
2224
2225const GLubyte* __stdcall glGetString(GLenum name)
2226{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002227 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002228
2229 try
2230 {
2231 switch (name)
2232 {
2233 case GL_VENDOR:
2234 return (GLubyte*)"TransGaming Inc.";
2235 case GL_RENDERER:
2236 return (GLubyte*)"ANGLE";
2237 case GL_VERSION:
2238 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2239 case GL_SHADING_LANGUAGE_VERSION:
2240 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2241 case GL_EXTENSIONS:
2242 return (GLubyte*)"";
2243 default:
2244 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2245 }
2246 }
2247 catch(std::bad_alloc&)
2248 {
2249 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2250 }
2251
2252 return NULL;
2253}
2254
2255void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2256{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002257 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 +00002258
2259 try
2260 {
2261 UNIMPLEMENTED(); // FIXME
2262 }
2263 catch(std::bad_alloc&)
2264 {
2265 return error(GL_OUT_OF_MEMORY);
2266 }
2267}
2268
2269void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2270{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002271 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 +00002272
2273 try
2274 {
2275 UNIMPLEMENTED(); // FIXME
2276 }
2277 catch(std::bad_alloc&)
2278 {
2279 return error(GL_OUT_OF_MEMORY);
2280 }
2281}
2282
2283void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2284{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002285 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002286
2287 try
2288 {
2289 UNIMPLEMENTED(); // FIXME
2290 }
2291 catch(std::bad_alloc&)
2292 {
2293 return error(GL_OUT_OF_MEMORY);
2294 }
2295}
2296
2297void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2298{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002299 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002300
2301 try
2302 {
2303 UNIMPLEMENTED(); // FIXME
2304 }
2305 catch(std::bad_alloc&)
2306 {
2307 return error(GL_OUT_OF_MEMORY);
2308 }
2309}
2310
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002311int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002312{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002313 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002314
2315 try
2316 {
2317 gl::Context *context = gl::getContext();
2318
2319 if (strstr(name, "gl_") == name)
2320 {
2321 return -1;
2322 }
2323
2324 if (context)
2325 {
2326 gl::Program *programObject = context->getProgram(program);
2327
2328 if (!programObject)
2329 {
2330 return error(GL_INVALID_VALUE, -1);
2331 }
2332
2333 if (!programObject->isLinked())
2334 {
2335 return error(GL_INVALID_OPERATION, -1);
2336 }
2337
2338 return programObject->getUniformLocation(name);
2339 }
2340 }
2341 catch(std::bad_alloc&)
2342 {
2343 return error(GL_OUT_OF_MEMORY, -1);
2344 }
2345
2346 return -1;
2347}
2348
2349void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2350{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002351 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002352
2353 try
2354 {
2355 if (index >= gl::MAX_VERTEX_ATTRIBS)
2356 {
2357 return error(GL_INVALID_VALUE);
2358 }
2359
2360 UNIMPLEMENTED(); // FIXME
2361 }
2362 catch(std::bad_alloc&)
2363 {
2364 return error(GL_OUT_OF_MEMORY);
2365 }
2366}
2367
2368void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2369{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002370 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002371
2372 try
2373 {
2374 if (index >= gl::MAX_VERTEX_ATTRIBS)
2375 {
2376 return error(GL_INVALID_VALUE);
2377 }
2378
2379 UNIMPLEMENTED(); // FIXME
2380 }
2381 catch(std::bad_alloc&)
2382 {
2383 return error(GL_OUT_OF_MEMORY);
2384 }
2385}
2386
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002387void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002388{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002389 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002390
2391 try
2392 {
2393 if (index >= gl::MAX_VERTEX_ATTRIBS)
2394 {
2395 return error(GL_INVALID_VALUE);
2396 }
2397
2398 UNIMPLEMENTED(); // FIXME
2399 }
2400 catch(std::bad_alloc&)
2401 {
2402 return error(GL_OUT_OF_MEMORY);
2403 }
2404}
2405
2406void __stdcall glHint(GLenum target, GLenum mode)
2407{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002408 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002409
2410 try
2411 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002412 switch (target)
2413 {
2414 case GL_GENERATE_MIPMAP_HINT:
2415 switch (mode)
2416 {
2417 case GL_FASTEST:
2418 case GL_NICEST:
2419 case GL_DONT_CARE:
2420 break;
2421 default:
2422 return error(GL_INVALID_ENUM);
2423 }
2424 break;
2425 default:
2426 return error(GL_INVALID_ENUM);
2427 }
2428
2429 gl::Context *context = gl::getContext();
2430 if (context)
2431 {
2432 if (target == GL_GENERATE_MIPMAP_HINT)
2433 context->generateMipmapHint = mode;
2434 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002435 }
2436 catch(std::bad_alloc&)
2437 {
2438 return error(GL_OUT_OF_MEMORY);
2439 }
2440}
2441
2442GLboolean __stdcall glIsBuffer(GLuint buffer)
2443{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002444 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002445
2446 try
2447 {
2448 gl::Context *context = gl::getContext();
2449
2450 if (context && buffer)
2451 {
2452 gl::Buffer *bufferObject = context->getBuffer(buffer);
2453
2454 if (bufferObject)
2455 {
2456 return GL_TRUE;
2457 }
2458 }
2459 }
2460 catch(std::bad_alloc&)
2461 {
2462 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2463 }
2464
2465 return GL_FALSE;
2466}
2467
2468GLboolean __stdcall glIsEnabled(GLenum cap)
2469{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002470 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002471
2472 try
2473 {
2474 gl::Context *context = gl::getContext();
2475
2476 if (context)
2477 {
2478 switch (cap)
2479 {
2480 case GL_CULL_FACE: return context->cullFace;
2481 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
2482 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
2483 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
2484 case GL_SCISSOR_TEST: return context->scissorTest;
2485 case GL_STENCIL_TEST: return context->stencilTest;
2486 case GL_DEPTH_TEST: return context->depthTest;
2487 case GL_BLEND: return context->blend;
2488 case GL_DITHER: return context->dither;
2489 default:
2490 return error(GL_INVALID_ENUM, false);
2491 }
2492 }
2493 }
2494 catch(std::bad_alloc&)
2495 {
2496 return error(GL_OUT_OF_MEMORY, false);
2497 }
2498
2499 return false;
2500}
2501
2502GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
2503{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002504 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002505
2506 try
2507 {
2508 gl::Context *context = gl::getContext();
2509
2510 if (context && framebuffer)
2511 {
2512 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2513
2514 if (framebufferObject)
2515 {
2516 return GL_TRUE;
2517 }
2518 }
2519 }
2520 catch(std::bad_alloc&)
2521 {
2522 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2523 }
2524
2525 return GL_FALSE;
2526}
2527
2528GLboolean __stdcall glIsProgram(GLuint program)
2529{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002530 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002531
2532 try
2533 {
2534 gl::Context *context = gl::getContext();
2535
2536 if (context && program)
2537 {
2538 gl::Program *programObject = context->getProgram(program);
2539
2540 if (programObject)
2541 {
2542 return GL_TRUE;
2543 }
2544 }
2545 }
2546 catch(std::bad_alloc&)
2547 {
2548 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2549 }
2550
2551 return GL_FALSE;
2552}
2553
2554GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
2555{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002556 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002557
2558 try
2559 {
2560 gl::Context *context = gl::getContext();
2561
2562 if (context && renderbuffer)
2563 {
2564 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2565
2566 if (renderbufferObject)
2567 {
2568 return GL_TRUE;
2569 }
2570 }
2571 }
2572 catch(std::bad_alloc&)
2573 {
2574 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2575 }
2576
2577 return GL_FALSE;
2578}
2579
2580GLboolean __stdcall glIsShader(GLuint shader)
2581{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002582 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002583
2584 try
2585 {
2586 gl::Context *context = gl::getContext();
2587
2588 if (context && shader)
2589 {
2590 gl::Shader *shaderObject = context->getShader(shader);
2591
2592 if (shaderObject)
2593 {
2594 return GL_TRUE;
2595 }
2596 }
2597 }
2598 catch(std::bad_alloc&)
2599 {
2600 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2601 }
2602
2603 return GL_FALSE;
2604}
2605
2606GLboolean __stdcall glIsTexture(GLuint texture)
2607{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002608 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002609
2610 try
2611 {
2612 gl::Context *context = gl::getContext();
2613
2614 if (context && texture)
2615 {
2616 gl::Texture *textureObject = context->getTexture(texture);
2617
2618 if (textureObject)
2619 {
2620 return GL_TRUE;
2621 }
2622 }
2623 }
2624 catch(std::bad_alloc&)
2625 {
2626 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2627 }
2628
2629 return GL_FALSE;
2630}
2631
2632void __stdcall glLineWidth(GLfloat width)
2633{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002634 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002635
2636 try
2637 {
2638 if (width <= 0.0f)
2639 {
2640 return error(GL_INVALID_VALUE);
2641 }
2642
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002643 gl::Context *context = gl::getContext();
2644
2645 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002646 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002647 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002648 }
2649 }
2650 catch(std::bad_alloc&)
2651 {
2652 return error(GL_OUT_OF_MEMORY);
2653 }
2654}
2655
2656void __stdcall glLinkProgram(GLuint program)
2657{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002658 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002659
2660 try
2661 {
2662 gl::Context *context = gl::getContext();
2663
2664 if (context)
2665 {
2666 gl::Program *programObject = context->getProgram(program);
2667
2668 if (!programObject)
2669 {
2670 return error(GL_INVALID_VALUE);
2671 }
2672
2673 programObject->link();
2674 }
2675 }
2676 catch(std::bad_alloc&)
2677 {
2678 return error(GL_OUT_OF_MEMORY);
2679 }
2680}
2681
2682void __stdcall glPixelStorei(GLenum pname, GLint param)
2683{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002684 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002685
2686 try
2687 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002688 gl::Context *context = gl::getContext();
2689
2690 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002691 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002692 switch (pname)
2693 {
2694 case GL_UNPACK_ALIGNMENT:
2695 if (param != 1 && param != 2 && param != 4 && param != 8)
2696 {
2697 return error(GL_INVALID_VALUE);
2698 }
2699
2700 context->unpackAlignment = param;
2701 break;
2702
2703 case GL_PACK_ALIGNMENT:
2704 if (param != 1 && param != 2 && param != 4 && param != 8)
2705 {
2706 return error(GL_INVALID_VALUE);
2707 }
2708
2709 context->packAlignment = param;
2710 break;
2711
2712 default:
2713 return error(GL_INVALID_ENUM);
2714 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002715 }
2716 }
2717 catch(std::bad_alloc&)
2718 {
2719 return error(GL_OUT_OF_MEMORY);
2720 }
2721}
2722
2723void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
2724{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002725 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002726
2727 try
2728 {
2729 if (factor != 0.0f || units != 0.0f)
2730 {
2731 UNIMPLEMENTED(); // FIXME
2732 }
2733 }
2734 catch(std::bad_alloc&)
2735 {
2736 return error(GL_OUT_OF_MEMORY);
2737 }
2738}
2739
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002740void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002741{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002742 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002743 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002744 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002745
2746 try
2747 {
2748 if (width < 0 || height < 0)
2749 {
2750 return error(GL_INVALID_VALUE);
2751 }
2752
2753 switch (format)
2754 {
2755 case GL_RGBA:
2756 switch (type)
2757 {
2758 case GL_UNSIGNED_BYTE:
2759 break;
2760 default:
2761 return error(GL_INVALID_OPERATION);
2762 }
2763 break;
2764 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
2765 switch (type)
2766 {
2767 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
2768 break;
2769 default:
2770 return error(GL_INVALID_OPERATION);
2771 }
2772 break;
2773 default:
2774 return error(GL_INVALID_OPERATION);
2775 }
2776
2777 gl::Context *context = gl::getContext();
2778
2779 if (context)
2780 {
2781 context->readPixels(x, y, width, height, format, type, pixels);
2782 }
2783 }
2784 catch(std::bad_alloc&)
2785 {
2786 return error(GL_OUT_OF_MEMORY);
2787 }
2788}
2789
2790void __stdcall glReleaseShaderCompiler(void)
2791{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002792 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002793
2794 try
2795 {
2796 gl::Shader::releaseCompiler();
2797 }
2798 catch(std::bad_alloc&)
2799 {
2800 return error(GL_OUT_OF_MEMORY);
2801 }
2802}
2803
2804void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
2805{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002806 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
2807 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002808
2809 try
2810 {
2811 switch (target)
2812 {
2813 case GL_RENDERBUFFER:
2814 break;
2815 default:
2816 return error(GL_INVALID_ENUM);
2817 }
2818
2819 switch (internalformat)
2820 {
2821 case GL_DEPTH_COMPONENT16:
2822 case GL_RGBA4:
2823 case GL_RGB5_A1:
2824 case GL_RGB565:
2825 case GL_STENCIL_INDEX8:
2826 break;
2827 default:
2828 return error(GL_INVALID_ENUM);
2829 }
2830
2831 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
2832 {
2833 return error(GL_INVALID_VALUE);
2834 }
2835
2836 gl::Context *context = gl::getContext();
2837
2838 if (context)
2839 {
2840 if (context->framebuffer == 0 || context->renderbuffer == 0)
2841 {
2842 return error(GL_INVALID_OPERATION);
2843 }
2844
2845 switch (internalformat)
2846 {
2847 case GL_DEPTH_COMPONENT16:
2848 context->setRenderbuffer(new gl::Depthbuffer(width, height));
2849 break;
2850 case GL_RGBA4:
2851 case GL_RGB5_A1:
2852 case GL_RGB565:
2853 UNIMPLEMENTED(); // FIXME
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00002854 // context->setRenderbuffer(new Colorbuffer(renderTarget));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002855 break;
2856 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00002857 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002858 break;
2859 default:
2860 return error(GL_INVALID_ENUM);
2861 }
2862 }
2863 }
2864 catch(std::bad_alloc&)
2865 {
2866 return error(GL_OUT_OF_MEMORY);
2867 }
2868}
2869
2870void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
2871{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002872 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002873
2874 try
2875 {
2876 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002877
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002878 if (context)
2879 {
2880 context->sampleCoverageValue = gl::clamp01(value);
2881 context->sampleCoverageInvert = invert;
2882 }
2883 }
2884 catch(std::bad_alloc&)
2885 {
2886 return error(GL_OUT_OF_MEMORY);
2887 }
2888}
2889
2890void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
2891{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002892 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 +00002893
2894 try
2895 {
2896 if (width < 0 || height < 0)
2897 {
2898 return error(GL_INVALID_VALUE);
2899 }
2900
2901 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002902
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002903 if (context)
2904 {
2905 context->scissorX = x;
2906 context->scissorY = y;
2907 context->scissorWidth = width;
2908 context->scissorHeight = height;
2909 }
2910 }
2911 catch(std::bad_alloc&)
2912 {
2913 return error(GL_OUT_OF_MEMORY);
2914 }
2915}
2916
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002917void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002918{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002919 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002920 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002921 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002922
2923 try
2924 {
2925 if (n < 0 || length < 0)
2926 {
2927 return error(GL_INVALID_VALUE);
2928 }
2929
2930 UNIMPLEMENTED(); // FIXME
2931 }
2932 catch(std::bad_alloc&)
2933 {
2934 return error(GL_OUT_OF_MEMORY);
2935 }
2936}
2937
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002938void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002939{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002940 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 +00002941 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002942
2943 try
2944 {
daniel@transgaming.com57a0bab2010-04-03 20:56:10 +00002945 if (shader == 0 || count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002946 {
2947 return error(GL_INVALID_VALUE);
2948 }
2949
2950 gl::Context *context = gl::getContext();
2951
2952 if (context)
2953 {
2954 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002955
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002956 if (!shaderObject)
2957 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002958 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002959 }
2960
2961 shaderObject->setSource(count, string, length);
2962 }
2963 }
2964 catch(std::bad_alloc&)
2965 {
2966 return error(GL_OUT_OF_MEMORY);
2967 }
2968}
2969
2970void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
2971{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002972 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002973}
2974
2975void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
2976{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002977 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 +00002978
2979 try
2980 {
2981 switch (face)
2982 {
2983 case GL_FRONT:
2984 case GL_BACK:
2985 case GL_FRONT_AND_BACK:
2986 break;
2987 default:
2988 return error(GL_INVALID_ENUM);
2989 }
2990
2991 switch (func)
2992 {
2993 case GL_NEVER:
2994 case GL_ALWAYS:
2995 case GL_LESS:
2996 case GL_LEQUAL:
2997 case GL_EQUAL:
2998 case GL_GEQUAL:
2999 case GL_GREATER:
3000 case GL_NOTEQUAL:
3001 break;
3002 default:
3003 return error(GL_INVALID_ENUM);
3004 }
3005
3006 gl::Context *context = gl::getContext();
3007
3008 if (context)
3009 {
3010 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3011 {
3012 context->stencilFunc = func;
3013 context->stencilRef = ref;
3014 context->stencilMask = mask;
3015 }
3016
3017 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3018 {
3019 context->stencilBackFunc = func;
3020 context->stencilBackRef = ref;
3021 context->stencilBackMask = mask;
3022 }
3023 }
3024 }
3025 catch(std::bad_alloc&)
3026 {
3027 return error(GL_OUT_OF_MEMORY);
3028 }
3029}
3030
3031void __stdcall glStencilMask(GLuint mask)
3032{
3033 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3034}
3035
3036void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3037{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003038 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003039
3040 try
3041 {
3042 switch (face)
3043 {
3044 case GL_FRONT:
3045 case GL_BACK:
3046 case GL_FRONT_AND_BACK:
3047 break;
3048 default:
3049 return error(GL_INVALID_ENUM);
3050 }
3051
3052 gl::Context *context = gl::getContext();
3053
3054 if (context)
3055 {
3056 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3057 {
3058 context->stencilWritemask = mask;
3059 }
3060
3061 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3062 {
3063 context->stencilBackWritemask = mask;
3064 }
3065 }
3066 }
3067 catch(std::bad_alloc&)
3068 {
3069 return error(GL_OUT_OF_MEMORY);
3070 }
3071}
3072
3073void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3074{
3075 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3076}
3077
3078void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3079{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003080 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3081 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003082
3083 try
3084 {
3085 switch (face)
3086 {
3087 case GL_FRONT:
3088 case GL_BACK:
3089 case GL_FRONT_AND_BACK:
3090 break;
3091 default:
3092 return error(GL_INVALID_ENUM);
3093 }
3094
3095 switch (fail)
3096 {
3097 case GL_ZERO:
3098 case GL_KEEP:
3099 case GL_REPLACE:
3100 case GL_INCR:
3101 case GL_DECR:
3102 case GL_INVERT:
3103 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003104 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003105 break;
3106 default:
3107 return error(GL_INVALID_ENUM);
3108 }
3109
3110 switch (zfail)
3111 {
3112 case GL_ZERO:
3113 case GL_KEEP:
3114 case GL_REPLACE:
3115 case GL_INCR:
3116 case GL_DECR:
3117 case GL_INVERT:
3118 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003119 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003120 break;
3121 default:
3122 return error(GL_INVALID_ENUM);
3123 }
3124
3125 switch (zpass)
3126 {
3127 case GL_ZERO:
3128 case GL_KEEP:
3129 case GL_REPLACE:
3130 case GL_INCR:
3131 case GL_DECR:
3132 case GL_INVERT:
3133 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003134 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003135 break;
3136 default:
3137 return error(GL_INVALID_ENUM);
3138 }
3139
3140 gl::Context *context = gl::getContext();
3141
3142 if (context)
3143 {
3144 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3145 {
3146 context->stencilFail = fail;
3147 context->stencilPassDepthFail = zfail;
3148 context->stencilPassDepthPass = zpass;
3149 }
3150
3151 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3152 {
3153 context->stencilBackFail = fail;
3154 context->stencilBackPassDepthFail = zfail;
3155 context->stencilBackPassDepthPass = zpass;
3156 }
3157 }
3158 }
3159 catch(std::bad_alloc&)
3160 {
3161 return error(GL_OUT_OF_MEMORY);
3162 }
3163}
3164
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003165void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3166 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003167{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003168 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 +00003169 "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 +00003170 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003171
3172 try
3173 {
3174 if (level < 0 || width < 0 || height < 0)
3175 {
3176 return error(GL_INVALID_VALUE);
3177 }
3178
3179 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3180 {
3181 return error(GL_INVALID_VALUE);
3182 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003183
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003184 switch (target)
3185 {
3186 case GL_TEXTURE_2D:
3187 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3188 {
3189 return error(GL_INVALID_VALUE);
3190 }
3191 break;
3192 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3193 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3194 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3195 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3196 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3197 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3198 if (!gl::isPow2(width) || !gl::isPow2(height))
3199 {
3200 return error(GL_INVALID_VALUE);
3201 }
3202
3203 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3204 {
3205 return error(GL_INVALID_VALUE);
3206 }
3207 break;
3208 default:
3209 return error(GL_INVALID_ENUM);
3210 }
3211
3212 if (internalformat != format)
3213 {
3214 return error(GL_INVALID_OPERATION);
3215 }
3216
3217 switch (internalformat)
3218 {
3219 case GL_ALPHA:
3220 case GL_LUMINANCE:
3221 case GL_LUMINANCE_ALPHA:
3222 switch (type)
3223 {
3224 case GL_UNSIGNED_BYTE:
3225 break;
3226 default:
3227 return error(GL_INVALID_ENUM);
3228 }
3229 break;
3230 case GL_RGB:
3231 switch (type)
3232 {
3233 case GL_UNSIGNED_BYTE:
3234 case GL_UNSIGNED_SHORT_5_6_5:
3235 break;
3236 default:
3237 return error(GL_INVALID_ENUM);
3238 }
3239 break;
3240 case GL_RGBA:
3241 switch (type)
3242 {
3243 case GL_UNSIGNED_BYTE:
3244 case GL_UNSIGNED_SHORT_4_4_4_4:
3245 case GL_UNSIGNED_SHORT_5_5_5_1:
3246 break;
3247 default:
3248 return error(GL_INVALID_ENUM);
3249 }
3250 break;
3251 default:
3252 return error(GL_INVALID_VALUE);
3253 }
3254
3255 if (border != 0)
3256 {
3257 return error(GL_INVALID_VALUE);
3258 }
3259
3260 gl::Context *context = gl::getContext();
3261
3262 if (context)
3263 {
3264 if (target == GL_TEXTURE_2D)
3265 {
3266 gl::Texture2D *texture = context->getTexture2D();
3267
3268 if (!texture)
3269 {
3270 return error(GL_INVALID_OPERATION);
3271 }
3272
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003273 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003274 }
3275 else
3276 {
3277 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3278
3279 if (!texture)
3280 {
3281 return error(GL_INVALID_OPERATION);
3282 }
3283
3284 switch (target)
3285 {
3286 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003287 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003288 break;
3289 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003290 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003291 break;
3292 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003293 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003294 break;
3295 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003296 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003297 break;
3298 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003299 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003300 break;
3301 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003302 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003303 break;
3304 default: UNREACHABLE();
3305 }
3306 }
3307 }
3308 }
3309 catch(std::bad_alloc&)
3310 {
3311 return error(GL_OUT_OF_MEMORY);
3312 }
3313}
3314
3315void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3316{
3317 glTexParameteri(target, pname, (GLint)param);
3318}
3319
3320void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3321{
3322 glTexParameteri(target, pname, (GLint)*params);
3323}
3324
3325void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3326{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003327 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003328
3329 try
3330 {
3331 gl::Context *context = gl::getContext();
3332
3333 if (context)
3334 {
3335 gl::Texture *texture;
3336
3337 switch (target)
3338 {
3339 case GL_TEXTURE_2D:
3340 texture = context->getTexture2D();
3341 break;
3342 case GL_TEXTURE_CUBE_MAP:
3343 texture = context->getTextureCubeMap();
3344 break;
3345 default:
3346 return error(GL_INVALID_ENUM);
3347 }
3348
3349 switch (pname)
3350 {
3351 case GL_TEXTURE_WRAP_S:
3352 if (!texture->setWrapS((GLenum)param))
3353 {
3354 return error(GL_INVALID_ENUM);
3355 }
3356 break;
3357 case GL_TEXTURE_WRAP_T:
3358 if (!texture->setWrapT((GLenum)param))
3359 {
3360 return error(GL_INVALID_ENUM);
3361 }
3362 break;
3363 case GL_TEXTURE_MIN_FILTER:
3364 if (!texture->setMinFilter((GLenum)param))
3365 {
3366 return error(GL_INVALID_ENUM);
3367 }
3368 break;
3369 case GL_TEXTURE_MAG_FILTER:
3370 if (!texture->setMagFilter((GLenum)param))
3371 {
3372 return error(GL_INVALID_ENUM);
3373 }
3374 break;
3375 default:
3376 return error(GL_INVALID_ENUM);
3377 }
3378 }
3379 }
3380 catch(std::bad_alloc&)
3381 {
3382 return error(GL_OUT_OF_MEMORY);
3383 }
3384}
3385
3386void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3387{
3388 glTexParameteri(target, pname, *params);
3389}
3390
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003391void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3392 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003393{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003394 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3395 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003396 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003397 target, level, xoffset, yoffset, width, height, format, type, pixels);
3398
3399 try
3400 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003401 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
3402 {
3403 return error(GL_INVALID_ENUM);
3404 }
3405
3406 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003407 {
3408 return error(GL_INVALID_VALUE);
3409 }
3410
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003411 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
3412 {
3413 return error(GL_INVALID_VALUE);
3414 }
3415
3416 if (!es2dx::CheckTextureFormatType(format, type))
3417 {
3418 return error(GL_INVALID_ENUM);
3419 }
3420
3421 if (width == 0 || height == 0 || pixels == NULL)
3422 {
3423 return;
3424 }
3425
3426 gl::Context *context = gl::getContext();
3427
3428 if (context)
3429 {
3430 if (target == GL_TEXTURE_2D)
3431 {
3432 gl::Texture2D *texture = context->getTexture2D();
3433
3434 if (!texture)
3435 {
3436 return error(GL_INVALID_OPERATION);
3437 }
3438
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003439 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003440 }
3441 else if (es2dx::IsCubemapTextureTarget(target))
3442 {
3443 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3444
3445 if (!texture)
3446 {
3447 return error(GL_INVALID_OPERATION);
3448 }
3449
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003450 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003451 }
3452 else
3453 {
3454 UNREACHABLE();
3455 }
3456 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003457 }
3458 catch(std::bad_alloc&)
3459 {
3460 return error(GL_OUT_OF_MEMORY);
3461 }
3462}
3463
3464void __stdcall glUniform1f(GLint location, GLfloat x)
3465{
3466 glUniform1fv(location, 1, &x);
3467}
3468
3469void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
3470{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003471 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003472
3473 try
3474 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003475 if (count < 0)
3476 {
3477 return error(GL_INVALID_VALUE);
3478 }
3479
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003480 if (location == -1)
3481 {
3482 return;
3483 }
3484
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003485 gl::Context *context = gl::getContext();
3486
3487 if (context)
3488 {
3489 gl::Program *program = context->getCurrentProgram();
3490
3491 if (!program)
3492 {
3493 return error(GL_INVALID_OPERATION);
3494 }
3495
3496 if (!program->setUniform1fv(location, count, v))
3497 {
3498 return error(GL_INVALID_OPERATION);
3499 }
3500 }
3501 }
3502 catch(std::bad_alloc&)
3503 {
3504 return error(GL_OUT_OF_MEMORY);
3505 }
3506}
3507
3508void __stdcall glUniform1i(GLint location, GLint x)
3509{
3510 glUniform1iv(location, 1, &x);
3511}
3512
3513void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
3514{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003515 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003516
3517 try
3518 {
3519 if (count < 0)
3520 {
3521 return error(GL_INVALID_VALUE);
3522 }
3523
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003524 if (location == -1)
3525 {
3526 return;
3527 }
3528
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003529 gl::Context *context = gl::getContext();
3530
3531 if (context)
3532 {
3533 gl::Program *program = context->getCurrentProgram();
3534
3535 if (!program)
3536 {
3537 return error(GL_INVALID_OPERATION);
3538 }
3539
3540 if (!program->setUniform1iv(location, count, v))
3541 {
3542 return error(GL_INVALID_OPERATION);
3543 }
3544 }
3545 }
3546 catch(std::bad_alloc&)
3547 {
3548 return error(GL_OUT_OF_MEMORY);
3549 }
3550}
3551
3552void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
3553{
3554 GLfloat xy[2] = {x, y};
3555
3556 glUniform2fv(location, 1, (GLfloat*)&xy);
3557}
3558
3559void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
3560{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003561 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003562
3563 try
3564 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003565 if (count < 0)
3566 {
3567 return error(GL_INVALID_VALUE);
3568 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003569
3570 if (location == -1)
3571 {
3572 return;
3573 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003574
3575 gl::Context *context = gl::getContext();
3576
3577 if (context)
3578 {
3579 gl::Program *program = context->getCurrentProgram();
3580
3581 if (!program)
3582 {
3583 return error(GL_INVALID_OPERATION);
3584 }
3585
3586 if (!program->setUniform2fv(location, count, v))
3587 {
3588 return error(GL_INVALID_OPERATION);
3589 }
3590 }
3591 }
3592 catch(std::bad_alloc&)
3593 {
3594 return error(GL_OUT_OF_MEMORY);
3595 }
3596}
3597
3598void __stdcall glUniform2i(GLint location, GLint x, GLint y)
3599{
3600 GLint xy[4] = {x, y};
3601
3602 glUniform2iv(location, 1, (GLint*)&xy);
3603}
3604
3605void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
3606{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003607 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003608
3609 try
3610 {
3611 if (count < 0)
3612 {
3613 return error(GL_INVALID_VALUE);
3614 }
3615
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003616 if (location == -1)
3617 {
3618 return;
3619 }
3620
3621 gl::Context *context = gl::getContext();
3622
3623 if (context)
3624 {
3625 gl::Program *program = context->getCurrentProgram();
3626
3627 if (!program)
3628 {
3629 return error(GL_INVALID_OPERATION);
3630 }
3631
3632 if (!program->setUniform2iv(location, count, v))
3633 {
3634 return error(GL_INVALID_OPERATION);
3635 }
3636 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003637 }
3638 catch(std::bad_alloc&)
3639 {
3640 return error(GL_OUT_OF_MEMORY);
3641 }
3642}
3643
3644void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
3645{
3646 GLfloat xyz[3] = {x, y, z};
3647
3648 glUniform3fv(location, 1, (GLfloat*)&xyz);
3649}
3650
3651void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
3652{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003653 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003654
3655 try
3656 {
3657 if (count < 0)
3658 {
3659 return error(GL_INVALID_VALUE);
3660 }
3661
3662 if (location == -1)
3663 {
3664 return;
3665 }
3666
3667 gl::Context *context = gl::getContext();
3668
3669 if (context)
3670 {
3671 gl::Program *program = context->getCurrentProgram();
3672
3673 if (!program)
3674 {
3675 return error(GL_INVALID_OPERATION);
3676 }
3677
3678 if (!program->setUniform3fv(location, count, v))
3679 {
3680 return error(GL_INVALID_OPERATION);
3681 }
3682 }
3683 }
3684 catch(std::bad_alloc&)
3685 {
3686 return error(GL_OUT_OF_MEMORY);
3687 }
3688}
3689
3690void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
3691{
3692 GLint xyz[3] = {x, y, z};
3693
3694 glUniform3iv(location, 1, (GLint*)&xyz);
3695}
3696
3697void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
3698{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003699 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003700
3701 try
3702 {
3703 if (count < 0)
3704 {
3705 return error(GL_INVALID_VALUE);
3706 }
3707
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003708 if (location == -1)
3709 {
3710 return;
3711 }
3712
3713 gl::Context *context = gl::getContext();
3714
3715 if (context)
3716 {
3717 gl::Program *program = context->getCurrentProgram();
3718
3719 if (!program)
3720 {
3721 return error(GL_INVALID_OPERATION);
3722 }
3723
3724 if (!program->setUniform3iv(location, count, v))
3725 {
3726 return error(GL_INVALID_OPERATION);
3727 }
3728 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003729 }
3730 catch(std::bad_alloc&)
3731 {
3732 return error(GL_OUT_OF_MEMORY);
3733 }
3734}
3735
3736void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3737{
3738 GLfloat xyzw[4] = {x, y, z, w};
3739
3740 glUniform4fv(location, 1, (GLfloat*)&xyzw);
3741}
3742
3743void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
3744{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003745 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003746
3747 try
3748 {
3749 if (count < 0)
3750 {
3751 return error(GL_INVALID_VALUE);
3752 }
3753
3754 if (location == -1)
3755 {
3756 return;
3757 }
3758
3759 gl::Context *context = gl::getContext();
3760
3761 if (context)
3762 {
3763 gl::Program *program = context->getCurrentProgram();
3764
3765 if (!program)
3766 {
3767 return error(GL_INVALID_OPERATION);
3768 }
3769
3770 if (!program->setUniform4fv(location, count, v))
3771 {
3772 return error(GL_INVALID_OPERATION);
3773 }
3774 }
3775 }
3776 catch(std::bad_alloc&)
3777 {
3778 return error(GL_OUT_OF_MEMORY);
3779 }
3780}
3781
3782void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
3783{
3784 GLint xyzw[4] = {x, y, z, w};
3785
3786 glUniform4iv(location, 1, (GLint*)&xyzw);
3787}
3788
3789void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
3790{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003791 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003792
3793 try
3794 {
3795 if (count < 0)
3796 {
3797 return error(GL_INVALID_VALUE);
3798 }
3799
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003800 if (location == -1)
3801 {
3802 return;
3803 }
3804
3805 gl::Context *context = gl::getContext();
3806
3807 if (context)
3808 {
3809 gl::Program *program = context->getCurrentProgram();
3810
3811 if (!program)
3812 {
3813 return error(GL_INVALID_OPERATION);
3814 }
3815
3816 if (!program->setUniform4iv(location, count, v))
3817 {
3818 return error(GL_INVALID_OPERATION);
3819 }
3820 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003821 }
3822 catch(std::bad_alloc&)
3823 {
3824 return error(GL_OUT_OF_MEMORY);
3825 }
3826}
3827
3828void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
3829{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003830 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
3831 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003832
3833 try
3834 {
3835 if (count < 0 || transpose != GL_FALSE)
3836 {
3837 return error(GL_INVALID_VALUE);
3838 }
3839
3840 if (location == -1)
3841 {
3842 return;
3843 }
3844
3845 gl::Context *context = gl::getContext();
3846
3847 if (context)
3848 {
3849 gl::Program *program = context->getCurrentProgram();
3850
3851 if (!program)
3852 {
3853 return error(GL_INVALID_OPERATION);
3854 }
3855
3856 if (!program->setUniformMatrix2fv(location, count, value))
3857 {
3858 return error(GL_INVALID_OPERATION);
3859 }
3860 }
3861 }
3862 catch(std::bad_alloc&)
3863 {
3864 return error(GL_OUT_OF_MEMORY);
3865 }
3866}
3867
3868void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
3869{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003870 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
3871 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003872
3873 try
3874 {
3875 if (count < 0 || transpose != GL_FALSE)
3876 {
3877 return error(GL_INVALID_VALUE);
3878 }
3879
3880 if (location == -1)
3881 {
3882 return;
3883 }
3884
3885 gl::Context *context = gl::getContext();
3886
3887 if (context)
3888 {
3889 gl::Program *program = context->getCurrentProgram();
3890
3891 if (!program)
3892 {
3893 return error(GL_INVALID_OPERATION);
3894 }
3895
3896 if (!program->setUniformMatrix3fv(location, count, value))
3897 {
3898 return error(GL_INVALID_OPERATION);
3899 }
3900 }
3901 }
3902 catch(std::bad_alloc&)
3903 {
3904 return error(GL_OUT_OF_MEMORY);
3905 }
3906}
3907
3908void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
3909{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003910 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
3911 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003912
3913 try
3914 {
3915 if (count < 0 || transpose != GL_FALSE)
3916 {
3917 return error(GL_INVALID_VALUE);
3918 }
3919
3920 if (location == -1)
3921 {
3922 return;
3923 }
3924
3925 gl::Context *context = gl::getContext();
3926
3927 if (context)
3928 {
3929 gl::Program *program = context->getCurrentProgram();
3930
3931 if (!program)
3932 {
3933 return error(GL_INVALID_OPERATION);
3934 }
3935
3936 if (!program->setUniformMatrix4fv(location, count, value))
3937 {
3938 return error(GL_INVALID_OPERATION);
3939 }
3940 }
3941 }
3942 catch(std::bad_alloc&)
3943 {
3944 return error(GL_OUT_OF_MEMORY);
3945 }
3946}
3947
3948void __stdcall glUseProgram(GLuint program)
3949{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003950 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003951
3952 try
3953 {
3954 gl::Context *context = gl::getContext();
3955
3956 if (context)
3957 {
3958 gl::Program *programObject = context->getProgram(program);
3959
3960 if (programObject && !programObject->isLinked())
3961 {
3962 return error(GL_INVALID_OPERATION);
3963 }
3964
3965 context->useProgram(program);
3966 }
3967 }
3968 catch(std::bad_alloc&)
3969 {
3970 return error(GL_OUT_OF_MEMORY);
3971 }
3972}
3973
3974void __stdcall glValidateProgram(GLuint program)
3975{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003976 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003977
3978 try
3979 {
3980 UNIMPLEMENTED(); // FIXME
3981 }
3982 catch(std::bad_alloc&)
3983 {
3984 return error(GL_OUT_OF_MEMORY);
3985 }
3986}
3987
3988void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
3989{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003990 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003991
3992 try
3993 {
3994 if (index >= gl::MAX_VERTEX_ATTRIBS)
3995 {
3996 return error(GL_INVALID_VALUE);
3997 }
3998
3999 UNIMPLEMENTED(); // FIXME
4000 }
4001 catch(std::bad_alloc&)
4002 {
4003 return error(GL_OUT_OF_MEMORY);
4004 }
4005}
4006
4007void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4008{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004009 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004010
4011 try
4012 {
4013 if (index >= gl::MAX_VERTEX_ATTRIBS)
4014 {
4015 return error(GL_INVALID_VALUE);
4016 }
4017
4018 UNIMPLEMENTED(); // FIXME
4019 }
4020 catch(std::bad_alloc&)
4021 {
4022 return error(GL_OUT_OF_MEMORY);
4023 }
4024}
4025
4026void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4027{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004028 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004029
4030 try
4031 {
4032 if (index >= gl::MAX_VERTEX_ATTRIBS)
4033 {
4034 return error(GL_INVALID_VALUE);
4035 }
4036
4037 UNIMPLEMENTED(); // FIXME
4038 }
4039 catch(std::bad_alloc&)
4040 {
4041 return error(GL_OUT_OF_MEMORY);
4042 }
4043}
4044
4045void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4046{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004047 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004048
4049 try
4050 {
4051 if (index >= gl::MAX_VERTEX_ATTRIBS)
4052 {
4053 return error(GL_INVALID_VALUE);
4054 }
4055
4056 UNIMPLEMENTED(); // FIXME
4057 }
4058 catch(std::bad_alloc&)
4059 {
4060 return error(GL_OUT_OF_MEMORY);
4061 }
4062}
4063
4064void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4065{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004066 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 +00004067
4068 try
4069 {
4070 if (index >= gl::MAX_VERTEX_ATTRIBS)
4071 {
4072 return error(GL_INVALID_VALUE);
4073 }
4074
4075 UNIMPLEMENTED(); // FIXME
4076 }
4077 catch(std::bad_alloc&)
4078 {
4079 return error(GL_OUT_OF_MEMORY);
4080 }
4081}
4082
4083void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4084{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004085 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004086
4087 try
4088 {
4089 if (index >= gl::MAX_VERTEX_ATTRIBS)
4090 {
4091 return error(GL_INVALID_VALUE);
4092 }
4093
4094 UNIMPLEMENTED(); // FIXME
4095 }
4096 catch(std::bad_alloc&)
4097 {
4098 return error(GL_OUT_OF_MEMORY);
4099 }
4100}
4101
4102void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4103{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004104 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 +00004105
4106 try
4107 {
4108 if (index >= gl::MAX_VERTEX_ATTRIBS)
4109 {
4110 return error(GL_INVALID_VALUE);
4111 }
4112
4113 UNIMPLEMENTED(); // FIXME
4114 }
4115 catch(std::bad_alloc&)
4116 {
4117 return error(GL_OUT_OF_MEMORY);
4118 }
4119}
4120
4121void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4122{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004123 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004124
4125 try
4126 {
4127 if (index >= gl::MAX_VERTEX_ATTRIBS)
4128 {
4129 return error(GL_INVALID_VALUE);
4130 }
4131
4132 UNIMPLEMENTED(); // FIXME
4133 }
4134 catch(std::bad_alloc&)
4135 {
4136 return error(GL_OUT_OF_MEMORY);
4137 }
4138}
4139
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004140void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004141{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004142 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004143 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004144 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004145
4146 try
4147 {
4148 if (index >= gl::MAX_VERTEX_ATTRIBS)
4149 {
4150 return error(GL_INVALID_VALUE);
4151 }
4152
4153 if (size < 1 || size > 4)
4154 {
4155 return error(GL_INVALID_VALUE);
4156 }
4157
4158 switch (type)
4159 {
4160 case GL_BYTE:
4161 case GL_UNSIGNED_BYTE:
4162 case GL_SHORT:
4163 case GL_UNSIGNED_SHORT:
4164 case GL_FIXED:
4165 case GL_FLOAT:
4166 break;
4167 default:
4168 return error(GL_INVALID_ENUM);
4169 }
4170
4171 if (stride < 0)
4172 {
4173 return error(GL_INVALID_VALUE);
4174 }
4175
4176 gl::Context *context = gl::getContext();
4177
4178 if (context)
4179 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004180 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4181 context->vertexAttribute[index].mSize = size;
4182 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004183 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004184 context->vertexAttribute[index].mStride = stride;
4185 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004186 }
4187 }
4188 catch(std::bad_alloc&)
4189 {
4190 return error(GL_OUT_OF_MEMORY);
4191 }
4192}
4193
4194void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4195{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004196 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 +00004197
4198 try
4199 {
4200 if (width < 0 || height < 0)
4201 {
4202 return error(GL_INVALID_VALUE);
4203 }
4204
4205 gl::Context *context = gl::getContext();
4206
4207 if (context)
4208 {
4209 context->viewportX = x;
4210 context->viewportY = y;
4211 context->viewportWidth = width;
4212 context->viewportHeight = height;
4213 }
4214 }
4215 catch(std::bad_alloc&)
4216 {
4217 return error(GL_OUT_OF_MEMORY);
4218 }
4219}
4220
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004221void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4222 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004223{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004224 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4225 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004226 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004227 target, level, internalformat, width, height, depth, border, format, type, pixels);
4228
4229 try
4230 {
4231 UNIMPLEMENTED(); // FIXME
4232 }
4233 catch(std::bad_alloc&)
4234 {
4235 return error(GL_OUT_OF_MEMORY);
4236 }
4237}
4238}