blob: ea0039d355acee9af69ef9d9b5cfea3dc3cb7c0e [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.come9d6ed02010-04-13 03:26:23 +000068 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000069 {
daniel@transgaming.come9d6ed02010-04-13 03:26:23 +000070 if (context->getShader(program))
71 {
72 return error(GL_INVALID_OPERATION);
73 }
74 else
75 {
76 return error(GL_INVALID_VALUE);
77 }
78 }
79
80 if (!shaderObject)
81 {
82 if (context->getProgram(shader))
83 {
84 return error(GL_INVALID_OPERATION);
85 }
86 else
87 {
88 return error(GL_INVALID_VALUE);
89 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090 }
91
92 if (!programObject->attachShader(shaderObject))
93 {
94 return error(GL_INVALID_OPERATION);
95 }
96 }
97 }
98 catch(std::bad_alloc&)
99 {
100 return error(GL_OUT_OF_MEMORY);
101 }
102}
103
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000104void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000105{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000106 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107
108 try
109 {
110 if (index >= gl::MAX_VERTEX_ATTRIBS)
111 {
112 return error(GL_INVALID_VALUE);
113 }
114
115 gl::Context *context = gl::getContext();
116
117 if (context)
118 {
119 gl::Program *programObject = context->getProgram(program);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000120
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000121 if (!programObject)
122 {
123 return error(GL_INVALID_VALUE);
124 }
125
126 programObject->bindAttributeLocation(index, name);
127 }
128 }
129 catch(std::bad_alloc&)
130 {
131 return error(GL_OUT_OF_MEMORY);
132 }
133}
134
135void __stdcall glBindBuffer(GLenum target, GLuint buffer)
136{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000137 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000138
139 try
140 {
141 gl::Context *context = gl::getContext();
142
143 if (context)
144 {
145 switch (target)
146 {
147 case GL_ARRAY_BUFFER:
148 context->bindArrayBuffer(buffer);
149 return;
150 case GL_ELEMENT_ARRAY_BUFFER:
151 context->bindElementArrayBuffer(buffer);
152 return;
153 default:
154 return error(GL_INVALID_ENUM);
155 }
156 }
157 }
158 catch(std::bad_alloc&)
159 {
160 return error(GL_OUT_OF_MEMORY);
161 }
162}
163
164void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
165{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000166 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000167
168 try
169 {
170 if (target != GL_FRAMEBUFFER)
171 {
172 return error(GL_INVALID_ENUM);
173 }
174
175 gl::Context *context = gl::getContext();
176
177 if (context)
178 {
179 context->bindFramebuffer(framebuffer);
180 }
181 }
182 catch(std::bad_alloc&)
183 {
184 return error(GL_OUT_OF_MEMORY);
185 }
186}
187
188void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
189{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000190 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000191
192 try
193 {
194 if (target != GL_RENDERBUFFER)
195 {
196 return error(GL_INVALID_ENUM);
197 }
198
199 gl::Context *context = gl::getContext();
200
201 if (context)
202 {
203 context->bindRenderbuffer(renderbuffer);
204 }
205 }
206 catch(std::bad_alloc&)
207 {
208 return error(GL_OUT_OF_MEMORY);
209 }
210}
211
212void __stdcall glBindTexture(GLenum target, GLuint texture)
213{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000214 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000215
216 try
217 {
218 gl::Context *context = gl::getContext();
219
220 if (context)
221 {
222 gl::Texture *textureObject = context->getTexture(texture);
223
224 if (textureObject && textureObject->getTarget() != target && texture != 0)
225 {
226 return error(GL_INVALID_OPERATION);
227 }
228
229 switch (target)
230 {
231 case GL_TEXTURE_2D:
232 context->bindTexture2D(texture);
233 return;
234 case GL_TEXTURE_CUBE_MAP:
235 context->bindTextureCubeMap(texture);
236 return;
237 default:
238 return error(GL_INVALID_ENUM);
239 }
240 }
241 }
242 catch(std::bad_alloc&)
243 {
244 return error(GL_OUT_OF_MEMORY);
245 }
246}
247
248void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
249{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000250 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
251 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000252
253 try
254 {
255 gl::Context* context = gl::getContext();
256
257 if (context)
258 {
259 context->blendColor.red = gl::clamp01(red);
260 context->blendColor.blue = gl::clamp01(blue);
261 context->blendColor.green = gl::clamp01(green);
262 context->blendColor.alpha = gl::clamp01(alpha);
263 }
264 }
265 catch(std::bad_alloc&)
266 {
267 return error(GL_OUT_OF_MEMORY);
268 }
269}
270
271void __stdcall glBlendEquation(GLenum mode)
272{
273 glBlendEquationSeparate(mode, mode);
274}
275
276void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
277{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000278 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000279
280 try
281 {
282 switch (modeRGB)
283 {
284 case GL_FUNC_ADD:
285 case GL_FUNC_SUBTRACT:
286 case GL_FUNC_REVERSE_SUBTRACT:
287 break;
288 default:
289 return error(GL_INVALID_ENUM);
290 }
291
292 switch (modeAlpha)
293 {
294 case GL_FUNC_ADD:
295 case GL_FUNC_SUBTRACT:
296 case GL_FUNC_REVERSE_SUBTRACT:
297 break;
298 default:
299 return error(GL_INVALID_ENUM);
300 }
301
302 gl::Context *context = gl::getContext();
303
304 if (context)
305 {
306 context->blendEquationRGB = modeRGB;
307 context->blendEquationAlpha = modeAlpha;
308 }
309 }
310 catch(std::bad_alloc&)
311 {
312 return error(GL_OUT_OF_MEMORY);
313 }
314}
315
316void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
317{
318 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
319}
320
321void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
322{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000323 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
324 srcRGB, dstRGB, srcAlpha, dstAlpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000325
326 try
327 {
328 switch (srcRGB)
329 {
330 case GL_ZERO:
331 case GL_ONE:
332 case GL_SRC_COLOR:
333 case GL_ONE_MINUS_SRC_COLOR:
334 case GL_DST_COLOR:
335 case GL_ONE_MINUS_DST_COLOR:
336 case GL_SRC_ALPHA:
337 case GL_ONE_MINUS_SRC_ALPHA:
338 case GL_DST_ALPHA:
339 case GL_ONE_MINUS_DST_ALPHA:
340 case GL_CONSTANT_COLOR:
341 case GL_ONE_MINUS_CONSTANT_COLOR:
342 case GL_CONSTANT_ALPHA:
343 case GL_ONE_MINUS_CONSTANT_ALPHA:
344 case GL_SRC_ALPHA_SATURATE:
345 break;
346 default:
347 return error(GL_INVALID_ENUM);
348 }
349
350 switch (dstRGB)
351 {
352 case GL_ZERO:
353 case GL_ONE:
354 case GL_SRC_COLOR:
355 case GL_ONE_MINUS_SRC_COLOR:
356 case GL_DST_COLOR:
357 case GL_ONE_MINUS_DST_COLOR:
358 case GL_SRC_ALPHA:
359 case GL_ONE_MINUS_SRC_ALPHA:
360 case GL_DST_ALPHA:
361 case GL_ONE_MINUS_DST_ALPHA:
362 case GL_CONSTANT_COLOR:
363 case GL_ONE_MINUS_CONSTANT_COLOR:
364 case GL_CONSTANT_ALPHA:
365 case GL_ONE_MINUS_CONSTANT_ALPHA:
366 break;
367 default:
368 return error(GL_INVALID_ENUM);
369 }
370
371 switch (srcAlpha)
372 {
373 case GL_ZERO:
374 case GL_ONE:
375 case GL_SRC_COLOR:
376 case GL_ONE_MINUS_SRC_COLOR:
377 case GL_DST_COLOR:
378 case GL_ONE_MINUS_DST_COLOR:
379 case GL_SRC_ALPHA:
380 case GL_ONE_MINUS_SRC_ALPHA:
381 case GL_DST_ALPHA:
382 case GL_ONE_MINUS_DST_ALPHA:
383 case GL_CONSTANT_COLOR:
384 case GL_ONE_MINUS_CONSTANT_COLOR:
385 case GL_CONSTANT_ALPHA:
386 case GL_ONE_MINUS_CONSTANT_ALPHA:
387 case GL_SRC_ALPHA_SATURATE:
388 break;
389 default:
390 return error(GL_INVALID_ENUM);
391 }
392
393 switch (dstAlpha)
394 {
395 case GL_ZERO:
396 case GL_ONE:
397 case GL_SRC_COLOR:
398 case GL_ONE_MINUS_SRC_COLOR:
399 case GL_DST_COLOR:
400 case GL_ONE_MINUS_DST_COLOR:
401 case GL_SRC_ALPHA:
402 case GL_ONE_MINUS_SRC_ALPHA:
403 case GL_DST_ALPHA:
404 case GL_ONE_MINUS_DST_ALPHA:
405 case GL_CONSTANT_COLOR:
406 case GL_ONE_MINUS_CONSTANT_COLOR:
407 case GL_CONSTANT_ALPHA:
408 case GL_ONE_MINUS_CONSTANT_ALPHA:
409 break;
410 default:
411 return error(GL_INVALID_ENUM);
412 }
413
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000414 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
415 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
416
417 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
418 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
419
420 if (constantColorUsed && constantAlphaUsed)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000421 {
daniel@transgaming.comfe453652010-03-16 06:23:28 +0000422 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
423 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000424 }
425
426 gl::Context *context = gl::getContext();
427
428 if (context)
429 {
430 context->sourceBlendRGB = srcRGB;
431 context->sourceBlendAlpha = srcAlpha;
432 context->destBlendRGB = dstRGB;
433 context->destBlendAlpha = dstAlpha;
434 }
435 }
436 catch(std::bad_alloc&)
437 {
438 return error(GL_OUT_OF_MEMORY);
439 }
440}
441
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000442void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000443{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000444 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 +0000445 target, size, data, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000446
447 try
448 {
449 if (size < 0)
450 {
451 return error(GL_INVALID_VALUE);
452 }
453
454 switch (usage)
455 {
456 case GL_STREAM_DRAW:
457 case GL_STATIC_DRAW:
458 case GL_DYNAMIC_DRAW:
459 break;
460 default:
461 return error(GL_INVALID_ENUM);
462 }
463
464 gl::Context *context = gl::getContext();
465
466 if (context)
467 {
468 gl::Buffer *buffer;
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000469
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000470 switch (target)
471 {
472 case GL_ARRAY_BUFFER:
473 buffer = context->getArrayBuffer();
474 break;
475 case GL_ELEMENT_ARRAY_BUFFER:
476 buffer = context->getElementArrayBuffer();
477 break;
478 default:
479 return error(GL_INVALID_ENUM);
480 }
481
482 if (!buffer)
483 {
484 return error(GL_INVALID_OPERATION);
485 }
486
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000487 buffer->bufferData(data, size, usage);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000488 }
489 }
490 catch(std::bad_alloc&)
491 {
492 return error(GL_OUT_OF_MEMORY);
493 }
494}
495
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000496void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000497{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000498 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 +0000499 target, offset, size, data);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000500
501 try
502 {
503 if (size < 0)
504 {
505 return error(GL_INVALID_VALUE);
506 }
507
daniel@transgaming.comd4620a32010-03-21 04:31:28 +0000508 if (data == NULL)
509 {
510 return;
511 }
512
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000513 gl::Context *context = gl::getContext();
514
515 if (context)
516 {
517 gl::Buffer *buffer;
518
519 switch (target)
520 {
521 case GL_ARRAY_BUFFER:
522 buffer = context->getArrayBuffer();
523 break;
524 case GL_ELEMENT_ARRAY_BUFFER:
525 buffer = context->getElementArrayBuffer();
526 break;
527 default:
528 return error(GL_INVALID_ENUM);
529 }
530
531 if (!buffer)
532 {
533 return error(GL_INVALID_OPERATION);
534 }
535
536 GLenum err = buffer->bufferSubData(data, size, offset);
537
538 if (err != GL_NO_ERROR)
539 {
540 return error(err);
541 }
542 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000543 }
544 catch(std::bad_alloc&)
545 {
546 return error(GL_OUT_OF_MEMORY);
547 }
548}
549
550GLenum __stdcall glCheckFramebufferStatus(GLenum target)
551{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000552 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000553
554 try
555 {
556 if (target != GL_FRAMEBUFFER)
557 {
558 return error(GL_INVALID_ENUM, 0);
559 }
560
561 gl::Context *context = gl::getContext();
562
563 if (context)
564 {
565 gl::Framebuffer *framebuffer = context->getFramebuffer();
566
567 return framebuffer->completeness();
568 }
569 }
570 catch(std::bad_alloc&)
571 {
572 return error(GL_OUT_OF_MEMORY, 0);
573 }
574
575 return 0;
576}
577
578void __stdcall glClear(GLbitfield mask)
579{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000580 TRACE("(GLbitfield mask = %X)", mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000581
582 try
583 {
584 gl::Context *context = gl::getContext();
585
586 if (context)
587 {
588 context->clear(mask);
589 }
590 }
591 catch(std::bad_alloc&)
592 {
593 return error(GL_OUT_OF_MEMORY);
594 }
595}
596
597void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
598{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000599 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
600 red, green, blue, alpha);
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->setClearColor(red, green, blue, alpha);
609 }
610 }
611 catch(std::bad_alloc&)
612 {
613 return error(GL_OUT_OF_MEMORY);
614 }
615}
616
617void __stdcall glClearDepthf(GLclampf depth)
618{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000619 TRACE("(GLclampf depth = %f)", depth);
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->setClearDepth(depth);
628 }
629 }
630 catch(std::bad_alloc&)
631 {
632 return error(GL_OUT_OF_MEMORY);
633 }
634}
635
636void __stdcall glClearStencil(GLint s)
637{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000638 TRACE("(GLint s = %d)", s);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000639
640 try
641 {
642 gl::Context *context = gl::getContext();
643
644 if (context)
645 {
646 context->setClearStencil(s);
647 }
648 }
649 catch(std::bad_alloc&)
650 {
651 return error(GL_OUT_OF_MEMORY);
652 }
653}
654
655void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
656{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000657 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
658 red, green, blue, alpha);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000659
660 try
661 {
662 gl::Context *context = gl::getContext();
663
664 if (context)
665 {
666 context->colorMaskRed = red != GL_FALSE;
667 context->colorMaskGreen = green != GL_FALSE;
668 context->colorMaskBlue = blue != GL_FALSE;
669 context->colorMaskAlpha = alpha != GL_FALSE;
670 }
671 }
672 catch(std::bad_alloc&)
673 {
674 return error(GL_OUT_OF_MEMORY);
675 }
676}
677
678void __stdcall glCompileShader(GLuint shader)
679{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000680 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000681
682 try
683 {
684 gl::Context *context = gl::getContext();
685
686 if (context)
687 {
688 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000689
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000690 if (!shaderObject)
691 {
692 return error(GL_INVALID_VALUE);
693 }
694
695 shaderObject->compile();
696 }
697 }
698 catch(std::bad_alloc&)
699 {
700 return error(GL_OUT_OF_MEMORY);
701 }
702}
703
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000704void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
705 GLint border, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000706{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000707 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000708 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000709 target, level, internalformat, width, height, border, imageSize, data);
710
711 try
712 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000713 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
714 {
715 return error(GL_INVALID_ENUM);
716 }
717
718 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000719 {
720 return error(GL_INVALID_VALUE);
721 }
722
daniel@transgaming.com41430492010-03-11 20:36:18 +0000723 if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
724 {
725 return error(GL_INVALID_VALUE);
726 }
727
728 return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000729 }
730 catch(std::bad_alloc&)
731 {
732 return error(GL_OUT_OF_MEMORY);
733 }
734}
735
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000736void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
737 GLenum format, GLsizei imageSize, const GLvoid* data)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000738{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000739 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
740 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +0000741 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000742 target, level, xoffset, yoffset, width, height, format, imageSize, data);
743
744 try
745 {
daniel@transgaming.com41430492010-03-11 20:36:18 +0000746 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
747 {
748 return error(GL_INVALID_ENUM);
749 }
750
751 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000752 {
753 return error(GL_INVALID_VALUE);
754 }
755
daniel@transgaming.com41430492010-03-11 20:36:18 +0000756 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
757 {
758 return error(GL_INVALID_VALUE);
759 }
760
761 if (xoffset != 0 || yoffset != 0)
762 {
763 return error(GL_INVALID_OPERATION);
764 }
765
766 return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000767 }
768 catch(std::bad_alloc&)
769 {
770 return error(GL_OUT_OF_MEMORY);
771 }
772}
773
774void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
775{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000776 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
777 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000778 target, level, internalformat, x, y, width, height, border);
779
780 try
781 {
782 if (width < 0 || height < 0)
783 {
784 return error(GL_INVALID_VALUE);
785 }
786
787 UNIMPLEMENTED(); // FIXME
788 }
789 catch(std::bad_alloc&)
790 {
791 return error(GL_OUT_OF_MEMORY);
792 }
793}
794
795void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
796{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000797 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
798 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000799 target, level, xoffset, yoffset, x, y, width, height);
800
801 try
802 {
803 if (width < 0 || height < 0)
804 {
805 return error(GL_INVALID_VALUE);
806 }
807
808 UNIMPLEMENTED(); // FIXME
809 }
810 catch(std::bad_alloc&)
811 {
812 return error(GL_OUT_OF_MEMORY);
813 }
814}
815
816GLuint __stdcall glCreateProgram(void)
817{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000818 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000819
820 try
821 {
822 gl::Context *context = gl::getContext();
823
824 if (context)
825 {
826 return context->createProgram();
827 }
828 }
829 catch(std::bad_alloc&)
830 {
831 return error(GL_OUT_OF_MEMORY, 0);
832 }
833
834 return 0;
835}
836
837GLuint __stdcall glCreateShader(GLenum type)
838{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000839 TRACE("(GLenum type = 0x%X)", type);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000840
841 try
842 {
843 gl::Context *context = gl::getContext();
844
845 if (context)
846 {
847 switch (type)
848 {
849 case GL_FRAGMENT_SHADER:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +0000850 case GL_VERTEX_SHADER:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000851 return context->createShader(type);
852 default:
853 return error(GL_INVALID_ENUM, 0);
854 }
855 }
856 }
857 catch(std::bad_alloc&)
858 {
859 return error(GL_OUT_OF_MEMORY, 0);
860 }
861
862 return 0;
863}
864
865void __stdcall glCullFace(GLenum mode)
866{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000867 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000868
869 try
870 {
871 switch (mode)
872 {
873 case GL_FRONT:
874 case GL_BACK:
875 case GL_FRONT_AND_BACK:
876 {
877 gl::Context *context = gl::getContext();
878
879 if (context)
880 {
881 context->cullMode = mode;
882 }
883 }
884 break;
885 default:
886 return error(GL_INVALID_ENUM);
887 }
888 }
889 catch(std::bad_alloc&)
890 {
891 return error(GL_OUT_OF_MEMORY);
892 }
893}
894
895void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
896{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000897 TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000898
899 try
900 {
901 if (n < 0)
902 {
903 return error(GL_INVALID_VALUE);
904 }
905
906 gl::Context *context = gl::getContext();
907
908 if (context)
909 {
910 for (int i = 0; i < n; i++)
911 {
912 context->deleteBuffer(buffers[i]);
913 }
914 }
915 }
916 catch(std::bad_alloc&)
917 {
918 return error(GL_OUT_OF_MEMORY);
919 }
920}
921
922void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
923{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000924 TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000925
926 try
927 {
928 if (n < 0)
929 {
930 return error(GL_INVALID_VALUE);
931 }
932
933 gl::Context *context = gl::getContext();
934
935 if (context)
936 {
937 for (int i = 0; i < n; i++)
938 {
939 if (framebuffers[i] != 0)
940 {
941 context->deleteFramebuffer(framebuffers[i]);
942 }
943 }
944 }
945 }
946 catch(std::bad_alloc&)
947 {
948 return error(GL_OUT_OF_MEMORY);
949 }
950}
951
952void __stdcall glDeleteProgram(GLuint program)
953{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000954 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000955
956 try
957 {
958 gl::Context *context = gl::getContext();
959
960 if (context)
961 {
962 context->deleteProgram(program);
963 }
964 }
965 catch(std::bad_alloc&)
966 {
967 return error(GL_OUT_OF_MEMORY);
968 }
969}
970
971void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
972{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +0000973 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000974
975 try
976 {
977 if (n < 0)
978 {
979 return error(GL_INVALID_VALUE);
980 }
981
982 gl::Context *context = gl::getContext();
983
984 if (context)
985 {
daniel@transgaming.come2b22122010-03-11 19:22:14 +0000986 for (int i = 0; i < n; i++)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000987 {
988 context->deleteRenderbuffer(renderbuffers[i]);
989 }
990 }
991 }
992 catch(std::bad_alloc&)
993 {
994 return error(GL_OUT_OF_MEMORY);
995 }
996}
997
998void __stdcall glDeleteShader(GLuint shader)
999{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001000 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001001
1002 try
1003 {
1004 gl::Context *context = gl::getContext();
1005
1006 if (context)
1007 {
1008 context->deleteShader(shader);
1009 }
1010 }
1011 catch(std::bad_alloc&)
1012 {
1013 return error(GL_OUT_OF_MEMORY);
1014 }
1015}
1016
1017void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1018{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001019 TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001020
1021 try
1022 {
1023 if (n < 0)
1024 {
1025 return error(GL_INVALID_VALUE);
1026 }
1027
1028 gl::Context *context = gl::getContext();
1029
1030 if (context)
1031 {
1032 for (int i = 0; i < n; i++)
1033 {
1034 if (textures[i] != 0)
1035 {
1036 context->deleteTexture(textures[i]);
1037 }
1038 }
1039 }
1040 }
1041 catch(std::bad_alloc&)
1042 {
1043 return error(GL_OUT_OF_MEMORY);
1044 }
1045}
1046
1047void __stdcall glDepthFunc(GLenum func)
1048{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001049 TRACE("(GLenum func = 0x%X)", func);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001050
1051 try
1052 {
1053 switch (func)
1054 {
1055 case GL_NEVER:
1056 case GL_ALWAYS:
1057 case GL_LESS:
1058 case GL_LEQUAL:
1059 case GL_EQUAL:
1060 case GL_GREATER:
1061 case GL_GEQUAL:
1062 case GL_NOTEQUAL:
1063 break;
1064 default:
1065 return error(GL_INVALID_ENUM);
1066 }
1067
1068 gl::Context *context = gl::getContext();
1069
1070 if (context)
1071 {
1072 context->depthFunc = func;
1073 }
1074 }
1075 catch(std::bad_alloc&)
1076 {
1077 return error(GL_OUT_OF_MEMORY);
1078 }
1079}
1080
1081void __stdcall glDepthMask(GLboolean flag)
1082{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001083 TRACE("(GLboolean flag = %d)", flag);
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->depthMask = flag != GL_FALSE;
1092 }
1093 }
1094 catch(std::bad_alloc&)
1095 {
1096 return error(GL_OUT_OF_MEMORY);
1097 }
1098}
1099
1100void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1101{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001102 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001103
1104 try
1105 {
1106 gl::Context *context = gl::getContext();
1107
1108 if (context)
1109 {
1110 context->zNear = zNear;
1111 context->zFar = zFar;
1112 }
1113 }
1114 catch(std::bad_alloc&)
1115 {
1116 return error(GL_OUT_OF_MEMORY);
1117 }
1118}
1119
1120void __stdcall glDetachShader(GLuint program, GLuint shader)
1121{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001122 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001123
1124 try
1125 {
1126 gl::Context *context = gl::getContext();
1127
1128 if (context)
1129 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001130
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001131 gl::Program *programObject = context->getProgram(program);
1132 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001133
1134 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001135 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001136 gl::Shader *shaderByProgramHandle;
1137 shaderByProgramHandle = context->getShader(program);
1138 if (!shaderByProgramHandle)
1139 {
1140 return error(GL_INVALID_VALUE);
1141 }
1142 else
1143 {
1144 return error(GL_INVALID_OPERATION);
1145 }
1146 }
1147
1148 if (!shaderObject)
1149 {
1150 gl::Program *programByShaderHandle = context->getProgram(shader);
1151 if (!programByShaderHandle)
1152 {
1153 return error(GL_INVALID_VALUE);
1154 }
1155 else
1156 {
1157 return error(GL_INVALID_OPERATION);
1158 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001159 }
1160
1161 if (!programObject->detachShader(shaderObject))
1162 {
1163 return error(GL_INVALID_OPERATION);
1164 }
1165
1166 if (shaderObject->isDeletable())
1167 {
1168 context->deleteShader(shader);
1169 }
1170 }
1171 }
1172 catch(std::bad_alloc&)
1173 {
1174 return error(GL_OUT_OF_MEMORY);
1175 }
1176}
1177
1178void __stdcall glDisable(GLenum cap)
1179{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001180 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001181
1182 try
1183 {
1184 gl::Context *context = gl::getContext();
1185
1186 if (context)
1187 {
1188 switch (cap)
1189 {
1190 case GL_CULL_FACE: context->cullFace = false; break;
1191 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1192 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1193 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1194 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1195 case GL_STENCIL_TEST: context->stencilTest = false; break;
1196 case GL_DEPTH_TEST: context->depthTest = false; break;
1197 case GL_BLEND: context->blend = false; break;
1198 case GL_DITHER: context->dither = false; break;
1199 default:
1200 return error(GL_INVALID_ENUM);
1201 }
1202 }
1203 }
1204 catch(std::bad_alloc&)
1205 {
1206 return error(GL_OUT_OF_MEMORY);
1207 }
1208}
1209
1210void __stdcall glDisableVertexAttribArray(GLuint index)
1211{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001212 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001213
1214 try
1215 {
1216 if (index >= gl::MAX_VERTEX_ATTRIBS)
1217 {
1218 return error(GL_INVALID_VALUE);
1219 }
1220
1221 gl::Context *context = gl::getContext();
1222
1223 if (context)
1224 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001225 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001226 }
1227 }
1228 catch(std::bad_alloc&)
1229 {
1230 return error(GL_OUT_OF_MEMORY);
1231 }
1232}
1233
1234void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1235{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001236 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001237
1238 try
1239 {
1240 if (count < 0 || first < 0)
1241 {
1242 return error(GL_INVALID_VALUE);
1243 }
1244
1245 gl::Context *context = gl::getContext();
1246
1247 if (context)
1248 {
1249 context->drawArrays(mode, first, count);
1250 }
1251 }
1252 catch(std::bad_alloc&)
1253 {
1254 return error(GL_OUT_OF_MEMORY);
1255 }
1256}
1257
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001258void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001259{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001260 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 +00001261 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001262
1263 try
1264 {
1265 if (count < 0)
1266 {
1267 return error(GL_INVALID_VALUE);
1268 }
1269
1270 switch (type)
1271 {
1272 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001273 case GL_UNSIGNED_SHORT:
1274 break;
1275 default:
1276 return error(GL_INVALID_ENUM);
1277 }
1278
1279 gl::Context *context = gl::getContext();
1280
1281 if (context)
1282 {
1283 context->drawElements(mode, count, type, indices);
1284 }
1285 }
1286 catch(std::bad_alloc&)
1287 {
1288 return error(GL_OUT_OF_MEMORY);
1289 }
1290}
1291
1292void __stdcall glEnable(GLenum cap)
1293{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001294 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001295
1296 try
1297 {
1298 gl::Context *context = gl::getContext();
1299
1300 if (context)
1301 {
1302 switch (cap)
1303 {
1304 case GL_CULL_FACE: context->cullFace = true; break;
1305 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1306 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1307 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1308 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1309 case GL_STENCIL_TEST: context->stencilTest = true; break;
1310 case GL_DEPTH_TEST: context->depthTest = true; break;
1311 case GL_BLEND: context->blend = true; break;
1312 case GL_DITHER: context->dither = true; break;
1313 default:
1314 return error(GL_INVALID_ENUM);
1315 }
1316 }
1317 }
1318 catch(std::bad_alloc&)
1319 {
1320 return error(GL_OUT_OF_MEMORY);
1321 }
1322}
1323
1324void __stdcall glEnableVertexAttribArray(GLuint index)
1325{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001326 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001327
1328 try
1329 {
1330 if (index >= gl::MAX_VERTEX_ATTRIBS)
1331 {
1332 return error(GL_INVALID_VALUE);
1333 }
1334
1335 gl::Context *context = gl::getContext();
1336
1337 if (context)
1338 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001339 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001340 }
1341 }
1342 catch(std::bad_alloc&)
1343 {
1344 return error(GL_OUT_OF_MEMORY);
1345 }
1346}
1347
1348void __stdcall glFinish(void)
1349{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001350 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001351
1352 try
1353 {
1354 gl::Context *context = gl::getContext();
1355
1356 if (context)
1357 {
1358 context->finish();
1359 }
1360 }
1361 catch(std::bad_alloc&)
1362 {
1363 return error(GL_OUT_OF_MEMORY);
1364 }
1365}
1366
1367void __stdcall glFlush(void)
1368{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001369 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001370
1371 try
1372 {
1373 gl::Context *context = gl::getContext();
1374
1375 if (context)
1376 {
1377 context->flush();
1378 }
1379 }
1380 catch(std::bad_alloc&)
1381 {
1382 return error(GL_OUT_OF_MEMORY);
1383 }
1384}
1385
1386void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1387{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001388 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1389 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001390
1391 try
1392 {
1393 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1394 {
1395 return error(GL_INVALID_ENUM);
1396 }
1397
1398 gl::Context *context = gl::getContext();
1399
1400 if (context)
1401 {
1402 gl::Framebuffer *framebuffer = context->getFramebuffer();
1403
1404 if (context->framebuffer == 0 || !framebuffer)
1405 {
1406 return error(GL_INVALID_OPERATION);
1407 }
1408
1409 switch (attachment)
1410 {
1411 case GL_COLOR_ATTACHMENT0:
1412 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1413 break;
1414 case GL_DEPTH_ATTACHMENT:
1415 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1416 break;
1417 case GL_STENCIL_ATTACHMENT:
1418 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1419 break;
1420 default:
1421 return error(GL_INVALID_ENUM);
1422 }
1423 }
1424 }
1425 catch(std::bad_alloc&)
1426 {
1427 return error(GL_OUT_OF_MEMORY);
1428 }
1429}
1430
1431void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1432{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001433 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1434 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001435
1436 try
1437 {
1438 if (target != GL_FRAMEBUFFER)
1439 {
1440 return error(GL_INVALID_ENUM);
1441 }
1442
1443 switch (attachment)
1444 {
1445 case GL_COLOR_ATTACHMENT0:
1446 break;
1447 default:
1448 return error(GL_INVALID_ENUM);
1449 }
1450
1451 gl::Context *context = gl::getContext();
1452
1453 if (context)
1454 {
1455 if (texture)
1456 {
1457 switch (textarget)
1458 {
1459 case GL_TEXTURE_2D:
1460 if (!context->getTexture2D())
1461 {
1462 return error(GL_INVALID_OPERATION);
1463 }
1464 break;
1465 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1466 UNIMPLEMENTED(); // FIXME
1467 break;
1468 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1469 UNIMPLEMENTED(); // FIXME
1470 break;
1471 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1472 UNIMPLEMENTED(); // FIXME
1473 break;
1474 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1475 UNIMPLEMENTED(); // FIXME
1476 break;
1477 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1478 UNIMPLEMENTED(); // FIXME
1479 break;
1480 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1481 UNIMPLEMENTED(); // FIXME
1482 break;
1483 default:
1484 return error(GL_INVALID_ENUM);
1485 }
1486
1487 if (level != 0)
1488 {
1489 return error(GL_INVALID_VALUE);
1490 }
1491 }
1492
1493 gl::Framebuffer *framebuffer = context->getFramebuffer();
1494
1495 if (context->framebuffer == 0 || !framebuffer)
1496 {
1497 return error(GL_INVALID_OPERATION);
1498 }
1499
1500 framebuffer->setColorbuffer(GL_TEXTURE, texture);
1501 }
1502 }
1503 catch(std::bad_alloc&)
1504 {
1505 return error(GL_OUT_OF_MEMORY);
1506 }
1507}
1508
1509void __stdcall glFrontFace(GLenum mode)
1510{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001511 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001512
1513 try
1514 {
1515 switch (mode)
1516 {
1517 case GL_CW:
1518 case GL_CCW:
1519 {
1520 gl::Context *context = gl::getContext();
1521
1522 if (context)
1523 {
1524 context->frontFace = mode;
1525 }
1526 }
1527 break;
1528 default:
1529 return error(GL_INVALID_ENUM);
1530 }
1531 }
1532 catch(std::bad_alloc&)
1533 {
1534 return error(GL_OUT_OF_MEMORY);
1535 }
1536}
1537
1538void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1539{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001540 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001541
1542 try
1543 {
1544 if (n < 0)
1545 {
1546 return error(GL_INVALID_VALUE);
1547 }
1548
1549 gl::Context *context = gl::getContext();
1550
1551 if (context)
1552 {
1553 for (int i = 0; i < n; i++)
1554 {
1555 buffers[i] = context->createBuffer();
1556 }
1557 }
1558 }
1559 catch(std::bad_alloc&)
1560 {
1561 return error(GL_OUT_OF_MEMORY);
1562 }
1563}
1564
1565void __stdcall glGenerateMipmap(GLenum target)
1566{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001567 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001568
1569 try
1570 {
1571 UNIMPLEMENTED(); // FIXME
1572 }
1573 catch(std::bad_alloc&)
1574 {
1575 return error(GL_OUT_OF_MEMORY);
1576 }
1577}
1578
1579void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1580{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001581 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001582
1583 try
1584 {
1585 if (n < 0)
1586 {
1587 return error(GL_INVALID_VALUE);
1588 }
1589
1590 gl::Context *context = gl::getContext();
1591
1592 if (context)
1593 {
1594 for (int i = 0; i < n; i++)
1595 {
1596 framebuffers[i] = context->createFramebuffer();
1597 }
1598 }
1599 }
1600 catch(std::bad_alloc&)
1601 {
1602 return error(GL_OUT_OF_MEMORY);
1603 }
1604}
1605
1606void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1607{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001608 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001609
1610 try
1611 {
1612 if (n < 0)
1613 {
1614 return error(GL_INVALID_VALUE);
1615 }
1616
1617 gl::Context *context = gl::getContext();
1618
1619 if (context)
1620 {
1621 for (int i = 0; i < n; i++)
1622 {
1623 renderbuffers[i] = context->createRenderbuffer();
1624 }
1625 }
1626 }
1627 catch(std::bad_alloc&)
1628 {
1629 return error(GL_OUT_OF_MEMORY);
1630 }
1631}
1632
1633void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1634{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001635 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001636
1637 try
1638 {
1639 if (n < 0)
1640 {
1641 return error(GL_INVALID_VALUE);
1642 }
1643
1644 gl::Context *context = gl::getContext();
1645
1646 if (context)
1647 {
1648 for (int i = 0; i < n; i++)
1649 {
1650 textures[i] = context->createTexture();
1651 }
1652 }
1653 }
1654 catch(std::bad_alloc&)
1655 {
1656 return error(GL_OUT_OF_MEMORY);
1657 }
1658}
1659
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001660void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001661{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001662 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001663 "GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001664 program, index, bufsize, length, size, type, name);
1665
1666 try
1667 {
1668 if (bufsize < 0)
1669 {
1670 return error(GL_INVALID_VALUE);
1671 }
1672
1673 UNIMPLEMENTED(); // FIXME
1674 }
1675 catch(std::bad_alloc&)
1676 {
1677 return error(GL_OUT_OF_MEMORY);
1678 }
1679}
1680
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001681void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001682{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001683 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001684 "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 +00001685 program, index, bufsize, length, size, type, name);
1686
1687 try
1688 {
1689 if (bufsize < 0)
1690 {
1691 return error(GL_INVALID_VALUE);
1692 }
1693
1694 UNIMPLEMENTED(); // FIXME
1695 }
1696 catch(std::bad_alloc&)
1697 {
1698 return error(GL_OUT_OF_MEMORY);
1699 }
1700}
1701
1702void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1703{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001704 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1705 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001706
1707 try
1708 {
1709 if (maxcount < 0)
1710 {
1711 return error(GL_INVALID_VALUE);
1712 }
1713
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001714 gl::Context *context = gl::getContext();
1715
1716 if (context)
1717 {
1718 gl::Program *programObject = context->getProgram(program);
1719
1720 if (!programObject)
1721 {
1722 return error(GL_INVALID_VALUE);
1723 }
1724
1725 return programObject->getAttachedShaders(maxcount, count, shaders);
1726 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001727 }
1728 catch(std::bad_alloc&)
1729 {
1730 return error(GL_OUT_OF_MEMORY);
1731 }
1732}
1733
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001734int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001735{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001736 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001737
1738 try
1739 {
1740 gl::Context *context = gl::getContext();
1741
1742 if (context)
1743 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001744
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001745 gl::Program *programObject = context->getProgram(program);
1746
1747 if (!programObject)
1748 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001749 if (context->getShader(program))
1750 {
1751 return error(GL_INVALID_OPERATION, -1);
1752 }
1753 else
1754 {
1755 return error(GL_INVALID_VALUE, -1);
1756 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001757 }
1758
daniel@transgaming.comcf4aa872010-04-13 03:26:27 +00001759 if (!programObject->isLinked())
1760 {
1761 return error(GL_INVALID_OPERATION, -1);
1762 }
1763
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001764 return programObject->getAttributeLocation(name);
1765 }
1766 }
1767 catch(std::bad_alloc&)
1768 {
1769 return error(GL_OUT_OF_MEMORY, -1);
1770 }
1771
1772 return -1;
1773}
1774
1775void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1776{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001777 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001778
1779 try
1780 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001781 gl::Context *context = gl::getContext();
1782
1783 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001784 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001785 if (!(context->getBooleanv(pname, params)))
1786 {
1787 GLenum nativeType;
1788 unsigned int numParams = 0;
1789 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1790 return error(GL_INVALID_ENUM);
1791
1792 if (numParams == 0)
1793 return; // it is known that the pname is valid, but there are no parameters to return
1794
1795 if (nativeType == GL_FLOAT)
1796 {
1797 GLfloat *floatParams = NULL;
1798 floatParams = new GLfloat[numParams];
1799
1800 context->getFloatv(pname, floatParams);
1801
1802 for (unsigned int i = 0; i < numParams; ++i)
1803 {
1804 if (floatParams[i] == 0.0f)
1805 params[i] = GL_FALSE;
1806 else
1807 params[i] = GL_TRUE;
1808 }
1809
1810 delete [] floatParams;
1811 }
1812 else if (nativeType == GL_INT)
1813 {
1814 GLint *intParams = NULL;
1815 intParams = new GLint[numParams];
1816
1817 context->getIntegerv(pname, intParams);
1818
1819 for (unsigned int i = 0; i < numParams; ++i)
1820 {
1821 if (intParams[i] == 0)
1822 params[i] = GL_FALSE;
1823 else
1824 params[i] = GL_TRUE;
1825 }
1826
1827 delete [] intParams;
1828 }
1829 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001830 }
1831 }
1832 catch(std::bad_alloc&)
1833 {
1834 return error(GL_OUT_OF_MEMORY);
1835 }
1836}
1837
1838void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1839{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001840 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 +00001841
1842 try
1843 {
1844 UNIMPLEMENTED(); // FIXME
1845 }
1846 catch(std::bad_alloc&)
1847 {
1848 return error(GL_OUT_OF_MEMORY);
1849 }
1850}
1851
1852GLenum __stdcall glGetError(void)
1853{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001854 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001855
1856 gl::Context *context = gl::getContext();
1857
1858 if (context)
1859 {
1860 return context->getError();
1861 }
1862
1863 return GL_NO_ERROR;
1864}
1865
1866void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
1867{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001868 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001869
1870 try
1871 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001872 gl::Context *context = gl::getContext();
1873
1874 if (context)
1875 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001876 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001877 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001878 GLenum nativeType;
1879 unsigned int numParams = 0;
1880 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1881 return error(GL_INVALID_ENUM);
1882
1883 if (numParams == 0)
1884 return; // it is known that the pname is valid, but that there are no parameters to return.
1885
1886 if (nativeType == GL_BOOL)
1887 {
1888 GLboolean *boolParams = NULL;
1889 boolParams = new GLboolean[numParams];
1890
1891 context->getBooleanv(pname, boolParams);
1892
1893 for (unsigned int i = 0; i < numParams; ++i)
1894 {
1895 if (boolParams[i] == GL_FALSE)
1896 params[i] = 0.0f;
1897 else
1898 params[i] = 1.0f;
1899 }
1900
1901 delete [] boolParams;
1902 }
1903 else if (nativeType == GL_INT)
1904 {
1905 GLint *intParams = NULL;
1906 intParams = new GLint[numParams];
1907
1908 context->getIntegerv(pname, intParams);
1909
1910 for (unsigned int i = 0; i < numParams; ++i)
1911 {
1912 params[i] = (GLfloat)intParams[i];
1913 }
1914
1915 delete [] intParams;
1916 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001917 }
1918 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001919 }
1920 catch(std::bad_alloc&)
1921 {
1922 return error(GL_OUT_OF_MEMORY);
1923 }
1924}
1925
1926void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
1927{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001928 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
1929 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001930
1931 try
1932 {
1933 gl::Context *context = gl::getContext();
1934
1935 if (context)
1936 {
1937 if (context->framebuffer == 0)
1938 {
1939 return error(GL_INVALID_OPERATION);
1940 }
1941
1942 UNIMPLEMENTED(); // FIXME
1943 }
1944 }
1945 catch(std::bad_alloc&)
1946 {
1947 return error(GL_OUT_OF_MEMORY);
1948 }
1949}
1950
1951void __stdcall glGetIntegerv(GLenum pname, GLint* params)
1952{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001953 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001954
1955 try
1956 {
1957 gl::Context *context = gl::getContext();
1958
1959 if (context)
1960 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001961 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001962 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001963 GLenum nativeType;
1964 unsigned int numParams = 0;
1965 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1966 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001967
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001968 if (numParams == 0)
1969 return; // it is known that pname is valid, but there are no parameters to return
1970
1971 if (nativeType == GL_BOOL)
1972 {
1973 GLboolean *boolParams = NULL;
1974 boolParams = new GLboolean[numParams];
1975
1976 context->getBooleanv(pname, boolParams);
1977
1978 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001979 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001980 if (boolParams[i] == GL_FALSE)
1981 params[i] = 0;
1982 else
1983 params[i] = 1;
1984 }
1985
1986 delete [] boolParams;
1987 }
1988 else if (nativeType == GL_FLOAT)
1989 {
1990 GLfloat *floatParams = NULL;
1991 floatParams = new GLfloat[numParams];
1992
1993 context->getFloatv(pname, floatParams);
1994
1995 for (unsigned int i = 0; i < numParams; ++i)
1996 {
1997 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001998 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001999 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002000 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002001 else
2002 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 +00002003 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002004
daniel@transgaming.com777f2672010-04-07 03:25:16 +00002005 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002006 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002007 }
2008 }
2009 }
2010 catch(std::bad_alloc&)
2011 {
2012 return error(GL_OUT_OF_MEMORY);
2013 }
2014}
2015
2016void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2017{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002018 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002019
2020 try
2021 {
2022 gl::Context *context = gl::getContext();
2023
2024 if (context)
2025 {
2026 gl::Program *programObject = context->getProgram(program);
2027
2028 if (!programObject)
2029 {
2030 return error(GL_INVALID_VALUE);
2031 }
2032
2033 switch (pname)
2034 {
2035 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002036 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002037 return;
2038 case GL_LINK_STATUS:
2039 *params = programObject->isLinked();
2040 return;
2041 case GL_VALIDATE_STATUS:
2042 UNIMPLEMENTED(); // FIXME
2043 *params = GL_TRUE;
2044 return;
2045 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002046 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002047 return;
2048 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002049 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002050 return;
2051 case GL_ACTIVE_ATTRIBUTES:
2052 UNIMPLEMENTED(); // FIXME
2053 *params = 0;
2054 return;
2055 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2056 UNIMPLEMENTED(); // FIXME
2057 *params = 0;
2058 return;
2059 case GL_ACTIVE_UNIFORMS:
2060 UNIMPLEMENTED(); // FIXME
2061 *params = 0;
2062 return;
2063 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2064 UNIMPLEMENTED(); // FIXME
2065 *params = 0;
2066 return;
2067 default:
2068 return error(GL_INVALID_ENUM);
2069 }
2070 }
2071 }
2072 catch(std::bad_alloc&)
2073 {
2074 return error(GL_OUT_OF_MEMORY);
2075 }
2076}
2077
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002078void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002079{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002080 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 +00002081 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002082
2083 try
2084 {
2085 if (bufsize < 0)
2086 {
2087 return error(GL_INVALID_VALUE);
2088 }
2089
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002090 gl::Context *context = gl::getContext();
2091
2092 if (context)
2093 {
2094 gl::Program *programObject = context->getProgram(program);
2095
2096 if (!programObject)
2097 {
2098 return error(GL_INVALID_VALUE);
2099 }
2100
2101 programObject->getInfoLog(bufsize, length, infolog);
2102 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002103 }
2104 catch(std::bad_alloc&)
2105 {
2106 return error(GL_OUT_OF_MEMORY);
2107 }
2108}
2109
2110void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2111{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002112 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 +00002113
2114 try
2115 {
2116 UNIMPLEMENTED(); // FIXME
2117 }
2118 catch(std::bad_alloc&)
2119 {
2120 return error(GL_OUT_OF_MEMORY);
2121 }
2122}
2123
2124void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2125{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002126 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002127
2128 try
2129 {
2130 gl::Context *context = gl::getContext();
2131
2132 if (context)
2133 {
2134 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002135
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002136 if (!shaderObject)
2137 {
2138 return error(GL_INVALID_VALUE);
2139 }
2140
2141 switch (pname)
2142 {
2143 case GL_SHADER_TYPE:
2144 *params = shaderObject->getType();
2145 return;
2146 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002147 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002148 return;
2149 case GL_COMPILE_STATUS:
2150 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2151 return;
2152 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002153 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002154 return;
2155 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002156 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002157 return;
2158 default:
2159 return error(GL_INVALID_ENUM);
2160 }
2161 }
2162 }
2163 catch(std::bad_alloc&)
2164 {
2165 return error(GL_OUT_OF_MEMORY);
2166 }
2167}
2168
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002169void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002170{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002171 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 +00002172 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002173
2174 try
2175 {
2176 if (bufsize < 0)
2177 {
2178 return error(GL_INVALID_VALUE);
2179 }
2180
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002181 gl::Context *context = gl::getContext();
2182
2183 if (context)
2184 {
2185 gl::Shader *shaderObject = context->getShader(shader);
2186
2187 if (!shaderObject)
2188 {
2189 return error(GL_INVALID_VALUE);
2190 }
2191
2192 shaderObject->getInfoLog(bufsize, length, infolog);
2193 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002194 }
2195 catch(std::bad_alloc&)
2196 {
2197 return error(GL_OUT_OF_MEMORY);
2198 }
2199}
2200
2201void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2202{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002203 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2204 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002205
2206 try
2207 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002208 switch (shadertype)
2209 {
2210 case GL_VERTEX_SHADER:
2211 case GL_FRAGMENT_SHADER:
2212 break;
2213 default:
2214 return error(GL_INVALID_ENUM);
2215 }
2216
2217 switch (precisiontype)
2218 {
2219 case GL_LOW_FLOAT:
2220 case GL_MEDIUM_FLOAT:
2221 case GL_HIGH_FLOAT:
2222 // Assume IEEE 754 precision
2223 range[0] = 127;
2224 range[1] = 127;
2225 precision[0] = 23;
2226 precision[1] = 23;
2227 break;
2228 case GL_LOW_INT:
2229 case GL_MEDIUM_INT:
2230 case GL_HIGH_INT:
2231 // Some (most) hardware only supports single-precision floating-point numbers,
2232 // which can accurately represent integers up to +/-16777216
2233 range[0] = 24;
2234 range[1] = 24;
2235 precision[0] = 0;
2236 precision[1] = 0;
2237 break;
2238 default:
2239 return error(GL_INVALID_ENUM);
2240 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002241 }
2242 catch(std::bad_alloc&)
2243 {
2244 return error(GL_OUT_OF_MEMORY);
2245 }
2246}
2247
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002248void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002249{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002250 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 +00002251 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002252
2253 try
2254 {
2255 if (bufsize < 0)
2256 {
2257 return error(GL_INVALID_VALUE);
2258 }
2259
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002260 gl::Context *context = gl::getContext();
2261
2262 if (context)
2263 {
2264 gl::Shader *shaderObject = context->getShader(shader);
2265
2266 if (!shaderObject)
2267 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002268 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002269 }
2270
2271 shaderObject->getSource(bufsize, length, source);
2272 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002273 }
2274 catch(std::bad_alloc&)
2275 {
2276 return error(GL_OUT_OF_MEMORY);
2277 }
2278}
2279
2280const GLubyte* __stdcall glGetString(GLenum name)
2281{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002282 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002283
2284 try
2285 {
2286 switch (name)
2287 {
2288 case GL_VENDOR:
2289 return (GLubyte*)"TransGaming Inc.";
2290 case GL_RENDERER:
2291 return (GLubyte*)"ANGLE";
2292 case GL_VERSION:
2293 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2294 case GL_SHADING_LANGUAGE_VERSION:
2295 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2296 case GL_EXTENSIONS:
2297 return (GLubyte*)"";
2298 default:
2299 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2300 }
2301 }
2302 catch(std::bad_alloc&)
2303 {
2304 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2305 }
2306
2307 return NULL;
2308}
2309
2310void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2311{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002312 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 +00002313
2314 try
2315 {
2316 UNIMPLEMENTED(); // FIXME
2317 }
2318 catch(std::bad_alloc&)
2319 {
2320 return error(GL_OUT_OF_MEMORY);
2321 }
2322}
2323
2324void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2325{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002326 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 +00002327
2328 try
2329 {
2330 UNIMPLEMENTED(); // FIXME
2331 }
2332 catch(std::bad_alloc&)
2333 {
2334 return error(GL_OUT_OF_MEMORY);
2335 }
2336}
2337
2338void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2339{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002340 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002341
2342 try
2343 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002344 gl::Context *context = gl::getContext();
2345
2346 if (context)
2347 {
2348 if (program == 0)
2349 {
2350 return error(GL_INVALID_VALUE);
2351 }
2352
2353 gl::Program *programObject = context->getProgram(program);
2354
2355 if (!programObject || !programObject->isLinked())
2356 {
2357 return error(GL_INVALID_OPERATION);
2358 }
2359
2360 if (!programObject->getUniformfv(location, params))
2361 {
2362 return error(GL_INVALID_OPERATION);
2363 }
2364 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002365 }
2366 catch(std::bad_alloc&)
2367 {
2368 return error(GL_OUT_OF_MEMORY);
2369 }
2370}
2371
2372void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2373{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002374 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002375
2376 try
2377 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002378 gl::Context *context = gl::getContext();
2379
2380 if (context)
2381 {
2382 if (program == 0)
2383 {
2384 return error(GL_INVALID_VALUE);
2385 }
2386
2387 gl::Program *programObject = context->getProgram(program);
2388
2389 if (!programObject || !programObject->isLinked())
2390 {
2391 return error(GL_INVALID_OPERATION);
2392 }
2393
2394 if (!programObject)
2395 {
2396 return error(GL_INVALID_OPERATION);
2397 }
2398
2399 if (!programObject->getUniformiv(location, params))
2400 {
2401 return error(GL_INVALID_OPERATION);
2402 }
2403 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002404 }
2405 catch(std::bad_alloc&)
2406 {
2407 return error(GL_OUT_OF_MEMORY);
2408 }
2409}
2410
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002411int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002412{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002413 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002414
2415 try
2416 {
2417 gl::Context *context = gl::getContext();
2418
2419 if (strstr(name, "gl_") == name)
2420 {
2421 return -1;
2422 }
2423
2424 if (context)
2425 {
2426 gl::Program *programObject = context->getProgram(program);
2427
2428 if (!programObject)
2429 {
2430 return error(GL_INVALID_VALUE, -1);
2431 }
2432
2433 if (!programObject->isLinked())
2434 {
2435 return error(GL_INVALID_OPERATION, -1);
2436 }
2437
2438 return programObject->getUniformLocation(name);
2439 }
2440 }
2441 catch(std::bad_alloc&)
2442 {
2443 return error(GL_OUT_OF_MEMORY, -1);
2444 }
2445
2446 return -1;
2447}
2448
2449void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2450{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002451 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002452
2453 try
2454 {
2455 if (index >= gl::MAX_VERTEX_ATTRIBS)
2456 {
2457 return error(GL_INVALID_VALUE);
2458 }
2459
2460 UNIMPLEMENTED(); // FIXME
2461 }
2462 catch(std::bad_alloc&)
2463 {
2464 return error(GL_OUT_OF_MEMORY);
2465 }
2466}
2467
2468void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2469{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002470 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002471
2472 try
2473 {
2474 if (index >= gl::MAX_VERTEX_ATTRIBS)
2475 {
2476 return error(GL_INVALID_VALUE);
2477 }
2478
2479 UNIMPLEMENTED(); // FIXME
2480 }
2481 catch(std::bad_alloc&)
2482 {
2483 return error(GL_OUT_OF_MEMORY);
2484 }
2485}
2486
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002487void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002488{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002489 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002490
2491 try
2492 {
2493 if (index >= gl::MAX_VERTEX_ATTRIBS)
2494 {
2495 return error(GL_INVALID_VALUE);
2496 }
2497
2498 UNIMPLEMENTED(); // FIXME
2499 }
2500 catch(std::bad_alloc&)
2501 {
2502 return error(GL_OUT_OF_MEMORY);
2503 }
2504}
2505
2506void __stdcall glHint(GLenum target, GLenum mode)
2507{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002508 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002509
2510 try
2511 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002512 switch (target)
2513 {
2514 case GL_GENERATE_MIPMAP_HINT:
2515 switch (mode)
2516 {
2517 case GL_FASTEST:
2518 case GL_NICEST:
2519 case GL_DONT_CARE:
2520 break;
2521 default:
2522 return error(GL_INVALID_ENUM);
2523 }
2524 break;
2525 default:
2526 return error(GL_INVALID_ENUM);
2527 }
2528
2529 gl::Context *context = gl::getContext();
2530 if (context)
2531 {
2532 if (target == GL_GENERATE_MIPMAP_HINT)
2533 context->generateMipmapHint = mode;
2534 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002535 }
2536 catch(std::bad_alloc&)
2537 {
2538 return error(GL_OUT_OF_MEMORY);
2539 }
2540}
2541
2542GLboolean __stdcall glIsBuffer(GLuint buffer)
2543{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002544 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002545
2546 try
2547 {
2548 gl::Context *context = gl::getContext();
2549
2550 if (context && buffer)
2551 {
2552 gl::Buffer *bufferObject = context->getBuffer(buffer);
2553
2554 if (bufferObject)
2555 {
2556 return GL_TRUE;
2557 }
2558 }
2559 }
2560 catch(std::bad_alloc&)
2561 {
2562 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2563 }
2564
2565 return GL_FALSE;
2566}
2567
2568GLboolean __stdcall glIsEnabled(GLenum cap)
2569{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002570 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002571
2572 try
2573 {
2574 gl::Context *context = gl::getContext();
2575
2576 if (context)
2577 {
2578 switch (cap)
2579 {
2580 case GL_CULL_FACE: return context->cullFace;
2581 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
2582 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
2583 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
2584 case GL_SCISSOR_TEST: return context->scissorTest;
2585 case GL_STENCIL_TEST: return context->stencilTest;
2586 case GL_DEPTH_TEST: return context->depthTest;
2587 case GL_BLEND: return context->blend;
2588 case GL_DITHER: return context->dither;
2589 default:
2590 return error(GL_INVALID_ENUM, false);
2591 }
2592 }
2593 }
2594 catch(std::bad_alloc&)
2595 {
2596 return error(GL_OUT_OF_MEMORY, false);
2597 }
2598
2599 return false;
2600}
2601
2602GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
2603{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002604 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002605
2606 try
2607 {
2608 gl::Context *context = gl::getContext();
2609
2610 if (context && framebuffer)
2611 {
2612 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2613
2614 if (framebufferObject)
2615 {
2616 return GL_TRUE;
2617 }
2618 }
2619 }
2620 catch(std::bad_alloc&)
2621 {
2622 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2623 }
2624
2625 return GL_FALSE;
2626}
2627
2628GLboolean __stdcall glIsProgram(GLuint program)
2629{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002630 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002631
2632 try
2633 {
2634 gl::Context *context = gl::getContext();
2635
2636 if (context && program)
2637 {
2638 gl::Program *programObject = context->getProgram(program);
2639
2640 if (programObject)
2641 {
2642 return GL_TRUE;
2643 }
2644 }
2645 }
2646 catch(std::bad_alloc&)
2647 {
2648 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2649 }
2650
2651 return GL_FALSE;
2652}
2653
2654GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
2655{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002656 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002657
2658 try
2659 {
2660 gl::Context *context = gl::getContext();
2661
2662 if (context && renderbuffer)
2663 {
2664 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2665
2666 if (renderbufferObject)
2667 {
2668 return GL_TRUE;
2669 }
2670 }
2671 }
2672 catch(std::bad_alloc&)
2673 {
2674 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2675 }
2676
2677 return GL_FALSE;
2678}
2679
2680GLboolean __stdcall glIsShader(GLuint shader)
2681{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002682 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002683
2684 try
2685 {
2686 gl::Context *context = gl::getContext();
2687
2688 if (context && shader)
2689 {
2690 gl::Shader *shaderObject = context->getShader(shader);
2691
2692 if (shaderObject)
2693 {
2694 return GL_TRUE;
2695 }
2696 }
2697 }
2698 catch(std::bad_alloc&)
2699 {
2700 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2701 }
2702
2703 return GL_FALSE;
2704}
2705
2706GLboolean __stdcall glIsTexture(GLuint texture)
2707{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002708 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002709
2710 try
2711 {
2712 gl::Context *context = gl::getContext();
2713
2714 if (context && texture)
2715 {
2716 gl::Texture *textureObject = context->getTexture(texture);
2717
2718 if (textureObject)
2719 {
2720 return GL_TRUE;
2721 }
2722 }
2723 }
2724 catch(std::bad_alloc&)
2725 {
2726 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2727 }
2728
2729 return GL_FALSE;
2730}
2731
2732void __stdcall glLineWidth(GLfloat width)
2733{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002734 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002735
2736 try
2737 {
2738 if (width <= 0.0f)
2739 {
2740 return error(GL_INVALID_VALUE);
2741 }
2742
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002743 gl::Context *context = gl::getContext();
2744
2745 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002746 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002747 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002748 }
2749 }
2750 catch(std::bad_alloc&)
2751 {
2752 return error(GL_OUT_OF_MEMORY);
2753 }
2754}
2755
2756void __stdcall glLinkProgram(GLuint program)
2757{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002758 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002759
2760 try
2761 {
2762 gl::Context *context = gl::getContext();
2763
2764 if (context)
2765 {
2766 gl::Program *programObject = context->getProgram(program);
2767
2768 if (!programObject)
2769 {
2770 return error(GL_INVALID_VALUE);
2771 }
2772
2773 programObject->link();
2774 }
2775 }
2776 catch(std::bad_alloc&)
2777 {
2778 return error(GL_OUT_OF_MEMORY);
2779 }
2780}
2781
2782void __stdcall glPixelStorei(GLenum pname, GLint param)
2783{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002784 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002785
2786 try
2787 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002788 gl::Context *context = gl::getContext();
2789
2790 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002791 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002792 switch (pname)
2793 {
2794 case GL_UNPACK_ALIGNMENT:
2795 if (param != 1 && param != 2 && param != 4 && param != 8)
2796 {
2797 return error(GL_INVALID_VALUE);
2798 }
2799
2800 context->unpackAlignment = param;
2801 break;
2802
2803 case GL_PACK_ALIGNMENT:
2804 if (param != 1 && param != 2 && param != 4 && param != 8)
2805 {
2806 return error(GL_INVALID_VALUE);
2807 }
2808
2809 context->packAlignment = param;
2810 break;
2811
2812 default:
2813 return error(GL_INVALID_ENUM);
2814 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002815 }
2816 }
2817 catch(std::bad_alloc&)
2818 {
2819 return error(GL_OUT_OF_MEMORY);
2820 }
2821}
2822
2823void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
2824{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002825 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002826
2827 try
2828 {
2829 if (factor != 0.0f || units != 0.0f)
2830 {
2831 UNIMPLEMENTED(); // FIXME
2832 }
2833 }
2834 catch(std::bad_alloc&)
2835 {
2836 return error(GL_OUT_OF_MEMORY);
2837 }
2838}
2839
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002840void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002841{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002842 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002843 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002844 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002845
2846 try
2847 {
2848 if (width < 0 || height < 0)
2849 {
2850 return error(GL_INVALID_VALUE);
2851 }
2852
2853 switch (format)
2854 {
2855 case GL_RGBA:
2856 switch (type)
2857 {
2858 case GL_UNSIGNED_BYTE:
2859 break;
2860 default:
2861 return error(GL_INVALID_OPERATION);
2862 }
2863 break;
2864 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
2865 switch (type)
2866 {
2867 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
2868 break;
2869 default:
2870 return error(GL_INVALID_OPERATION);
2871 }
2872 break;
2873 default:
2874 return error(GL_INVALID_OPERATION);
2875 }
2876
2877 gl::Context *context = gl::getContext();
2878
2879 if (context)
2880 {
2881 context->readPixels(x, y, width, height, format, type, pixels);
2882 }
2883 }
2884 catch(std::bad_alloc&)
2885 {
2886 return error(GL_OUT_OF_MEMORY);
2887 }
2888}
2889
2890void __stdcall glReleaseShaderCompiler(void)
2891{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002892 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002893
2894 try
2895 {
2896 gl::Shader::releaseCompiler();
2897 }
2898 catch(std::bad_alloc&)
2899 {
2900 return error(GL_OUT_OF_MEMORY);
2901 }
2902}
2903
2904void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
2905{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002906 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
2907 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002908
2909 try
2910 {
2911 switch (target)
2912 {
2913 case GL_RENDERBUFFER:
2914 break;
2915 default:
2916 return error(GL_INVALID_ENUM);
2917 }
2918
2919 switch (internalformat)
2920 {
2921 case GL_DEPTH_COMPONENT16:
2922 case GL_RGBA4:
2923 case GL_RGB5_A1:
2924 case GL_RGB565:
2925 case GL_STENCIL_INDEX8:
2926 break;
2927 default:
2928 return error(GL_INVALID_ENUM);
2929 }
2930
2931 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
2932 {
2933 return error(GL_INVALID_VALUE);
2934 }
2935
2936 gl::Context *context = gl::getContext();
2937
2938 if (context)
2939 {
2940 if (context->framebuffer == 0 || context->renderbuffer == 0)
2941 {
2942 return error(GL_INVALID_OPERATION);
2943 }
2944
2945 switch (internalformat)
2946 {
2947 case GL_DEPTH_COMPONENT16:
2948 context->setRenderbuffer(new gl::Depthbuffer(width, height));
2949 break;
2950 case GL_RGBA4:
2951 case GL_RGB5_A1:
2952 case GL_RGB565:
2953 UNIMPLEMENTED(); // FIXME
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00002954 // context->setRenderbuffer(new Colorbuffer(renderTarget));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002955 break;
2956 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00002957 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002958 break;
2959 default:
2960 return error(GL_INVALID_ENUM);
2961 }
2962 }
2963 }
2964 catch(std::bad_alloc&)
2965 {
2966 return error(GL_OUT_OF_MEMORY);
2967 }
2968}
2969
2970void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
2971{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002972 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002973
2974 try
2975 {
2976 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002977
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002978 if (context)
2979 {
2980 context->sampleCoverageValue = gl::clamp01(value);
2981 context->sampleCoverageInvert = invert;
2982 }
2983 }
2984 catch(std::bad_alloc&)
2985 {
2986 return error(GL_OUT_OF_MEMORY);
2987 }
2988}
2989
2990void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
2991{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002992 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 +00002993
2994 try
2995 {
2996 if (width < 0 || height < 0)
2997 {
2998 return error(GL_INVALID_VALUE);
2999 }
3000
3001 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003002
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003003 if (context)
3004 {
3005 context->scissorX = x;
3006 context->scissorY = y;
3007 context->scissorWidth = width;
3008 context->scissorHeight = height;
3009 }
3010 }
3011 catch(std::bad_alloc&)
3012 {
3013 return error(GL_OUT_OF_MEMORY);
3014 }
3015}
3016
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003017void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003018{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003019 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003020 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003021 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003022
3023 try
3024 {
3025 if (n < 0 || length < 0)
3026 {
3027 return error(GL_INVALID_VALUE);
3028 }
3029
3030 UNIMPLEMENTED(); // FIXME
3031 }
3032 catch(std::bad_alloc&)
3033 {
3034 return error(GL_OUT_OF_MEMORY);
3035 }
3036}
3037
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003038void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003039{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003040 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 +00003041 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003042
3043 try
3044 {
daniel@transgaming.com57a0bab2010-04-03 20:56:10 +00003045 if (shader == 0 || count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003046 {
3047 return error(GL_INVALID_VALUE);
3048 }
3049
3050 gl::Context *context = gl::getContext();
3051
3052 if (context)
3053 {
3054 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003055
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003056 if (!shaderObject)
3057 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003058 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003059 }
3060
3061 shaderObject->setSource(count, string, length);
3062 }
3063 }
3064 catch(std::bad_alloc&)
3065 {
3066 return error(GL_OUT_OF_MEMORY);
3067 }
3068}
3069
3070void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3071{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003072 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003073}
3074
3075void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3076{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003077 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 +00003078
3079 try
3080 {
3081 switch (face)
3082 {
3083 case GL_FRONT:
3084 case GL_BACK:
3085 case GL_FRONT_AND_BACK:
3086 break;
3087 default:
3088 return error(GL_INVALID_ENUM);
3089 }
3090
3091 switch (func)
3092 {
3093 case GL_NEVER:
3094 case GL_ALWAYS:
3095 case GL_LESS:
3096 case GL_LEQUAL:
3097 case GL_EQUAL:
3098 case GL_GEQUAL:
3099 case GL_GREATER:
3100 case GL_NOTEQUAL:
3101 break;
3102 default:
3103 return error(GL_INVALID_ENUM);
3104 }
3105
3106 gl::Context *context = gl::getContext();
3107
3108 if (context)
3109 {
3110 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3111 {
3112 context->stencilFunc = func;
3113 context->stencilRef = ref;
3114 context->stencilMask = mask;
3115 }
3116
3117 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3118 {
3119 context->stencilBackFunc = func;
3120 context->stencilBackRef = ref;
3121 context->stencilBackMask = mask;
3122 }
3123 }
3124 }
3125 catch(std::bad_alloc&)
3126 {
3127 return error(GL_OUT_OF_MEMORY);
3128 }
3129}
3130
3131void __stdcall glStencilMask(GLuint mask)
3132{
3133 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3134}
3135
3136void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3137{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003138 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003139
3140 try
3141 {
3142 switch (face)
3143 {
3144 case GL_FRONT:
3145 case GL_BACK:
3146 case GL_FRONT_AND_BACK:
3147 break;
3148 default:
3149 return error(GL_INVALID_ENUM);
3150 }
3151
3152 gl::Context *context = gl::getContext();
3153
3154 if (context)
3155 {
3156 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3157 {
3158 context->stencilWritemask = mask;
3159 }
3160
3161 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3162 {
3163 context->stencilBackWritemask = mask;
3164 }
3165 }
3166 }
3167 catch(std::bad_alloc&)
3168 {
3169 return error(GL_OUT_OF_MEMORY);
3170 }
3171}
3172
3173void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3174{
3175 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3176}
3177
3178void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3179{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003180 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3181 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003182
3183 try
3184 {
3185 switch (face)
3186 {
3187 case GL_FRONT:
3188 case GL_BACK:
3189 case GL_FRONT_AND_BACK:
3190 break;
3191 default:
3192 return error(GL_INVALID_ENUM);
3193 }
3194
3195 switch (fail)
3196 {
3197 case GL_ZERO:
3198 case GL_KEEP:
3199 case GL_REPLACE:
3200 case GL_INCR:
3201 case GL_DECR:
3202 case GL_INVERT:
3203 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003204 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003205 break;
3206 default:
3207 return error(GL_INVALID_ENUM);
3208 }
3209
3210 switch (zfail)
3211 {
3212 case GL_ZERO:
3213 case GL_KEEP:
3214 case GL_REPLACE:
3215 case GL_INCR:
3216 case GL_DECR:
3217 case GL_INVERT:
3218 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003219 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003220 break;
3221 default:
3222 return error(GL_INVALID_ENUM);
3223 }
3224
3225 switch (zpass)
3226 {
3227 case GL_ZERO:
3228 case GL_KEEP:
3229 case GL_REPLACE:
3230 case GL_INCR:
3231 case GL_DECR:
3232 case GL_INVERT:
3233 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003234 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003235 break;
3236 default:
3237 return error(GL_INVALID_ENUM);
3238 }
3239
3240 gl::Context *context = gl::getContext();
3241
3242 if (context)
3243 {
3244 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3245 {
3246 context->stencilFail = fail;
3247 context->stencilPassDepthFail = zfail;
3248 context->stencilPassDepthPass = zpass;
3249 }
3250
3251 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3252 {
3253 context->stencilBackFail = fail;
3254 context->stencilBackPassDepthFail = zfail;
3255 context->stencilBackPassDepthPass = zpass;
3256 }
3257 }
3258 }
3259 catch(std::bad_alloc&)
3260 {
3261 return error(GL_OUT_OF_MEMORY);
3262 }
3263}
3264
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003265void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3266 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003267{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003268 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 +00003269 "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 +00003270 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003271
3272 try
3273 {
3274 if (level < 0 || width < 0 || height < 0)
3275 {
3276 return error(GL_INVALID_VALUE);
3277 }
3278
3279 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3280 {
3281 return error(GL_INVALID_VALUE);
3282 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003283
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003284 switch (target)
3285 {
3286 case GL_TEXTURE_2D:
3287 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3288 {
3289 return error(GL_INVALID_VALUE);
3290 }
3291 break;
3292 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3293 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3294 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3295 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3296 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3297 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3298 if (!gl::isPow2(width) || !gl::isPow2(height))
3299 {
3300 return error(GL_INVALID_VALUE);
3301 }
3302
3303 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3304 {
3305 return error(GL_INVALID_VALUE);
3306 }
3307 break;
3308 default:
3309 return error(GL_INVALID_ENUM);
3310 }
3311
3312 if (internalformat != format)
3313 {
3314 return error(GL_INVALID_OPERATION);
3315 }
3316
3317 switch (internalformat)
3318 {
3319 case GL_ALPHA:
3320 case GL_LUMINANCE:
3321 case GL_LUMINANCE_ALPHA:
3322 switch (type)
3323 {
3324 case GL_UNSIGNED_BYTE:
3325 break;
3326 default:
3327 return error(GL_INVALID_ENUM);
3328 }
3329 break;
3330 case GL_RGB:
3331 switch (type)
3332 {
3333 case GL_UNSIGNED_BYTE:
3334 case GL_UNSIGNED_SHORT_5_6_5:
3335 break;
3336 default:
3337 return error(GL_INVALID_ENUM);
3338 }
3339 break;
3340 case GL_RGBA:
3341 switch (type)
3342 {
3343 case GL_UNSIGNED_BYTE:
3344 case GL_UNSIGNED_SHORT_4_4_4_4:
3345 case GL_UNSIGNED_SHORT_5_5_5_1:
3346 break;
3347 default:
3348 return error(GL_INVALID_ENUM);
3349 }
3350 break;
3351 default:
3352 return error(GL_INVALID_VALUE);
3353 }
3354
3355 if (border != 0)
3356 {
3357 return error(GL_INVALID_VALUE);
3358 }
3359
3360 gl::Context *context = gl::getContext();
3361
3362 if (context)
3363 {
3364 if (target == GL_TEXTURE_2D)
3365 {
3366 gl::Texture2D *texture = context->getTexture2D();
3367
3368 if (!texture)
3369 {
3370 return error(GL_INVALID_OPERATION);
3371 }
3372
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003373 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003374 }
3375 else
3376 {
3377 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3378
3379 if (!texture)
3380 {
3381 return error(GL_INVALID_OPERATION);
3382 }
3383
3384 switch (target)
3385 {
3386 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003387 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003388 break;
3389 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003390 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003391 break;
3392 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003393 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003394 break;
3395 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003396 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003397 break;
3398 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003399 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003400 break;
3401 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003402 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003403 break;
3404 default: UNREACHABLE();
3405 }
3406 }
3407 }
3408 }
3409 catch(std::bad_alloc&)
3410 {
3411 return error(GL_OUT_OF_MEMORY);
3412 }
3413}
3414
3415void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3416{
3417 glTexParameteri(target, pname, (GLint)param);
3418}
3419
3420void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3421{
3422 glTexParameteri(target, pname, (GLint)*params);
3423}
3424
3425void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3426{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003427 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003428
3429 try
3430 {
3431 gl::Context *context = gl::getContext();
3432
3433 if (context)
3434 {
3435 gl::Texture *texture;
3436
3437 switch (target)
3438 {
3439 case GL_TEXTURE_2D:
3440 texture = context->getTexture2D();
3441 break;
3442 case GL_TEXTURE_CUBE_MAP:
3443 texture = context->getTextureCubeMap();
3444 break;
3445 default:
3446 return error(GL_INVALID_ENUM);
3447 }
3448
3449 switch (pname)
3450 {
3451 case GL_TEXTURE_WRAP_S:
3452 if (!texture->setWrapS((GLenum)param))
3453 {
3454 return error(GL_INVALID_ENUM);
3455 }
3456 break;
3457 case GL_TEXTURE_WRAP_T:
3458 if (!texture->setWrapT((GLenum)param))
3459 {
3460 return error(GL_INVALID_ENUM);
3461 }
3462 break;
3463 case GL_TEXTURE_MIN_FILTER:
3464 if (!texture->setMinFilter((GLenum)param))
3465 {
3466 return error(GL_INVALID_ENUM);
3467 }
3468 break;
3469 case GL_TEXTURE_MAG_FILTER:
3470 if (!texture->setMagFilter((GLenum)param))
3471 {
3472 return error(GL_INVALID_ENUM);
3473 }
3474 break;
3475 default:
3476 return error(GL_INVALID_ENUM);
3477 }
3478 }
3479 }
3480 catch(std::bad_alloc&)
3481 {
3482 return error(GL_OUT_OF_MEMORY);
3483 }
3484}
3485
3486void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3487{
3488 glTexParameteri(target, pname, *params);
3489}
3490
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003491void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3492 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003493{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003494 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3495 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003496 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003497 target, level, xoffset, yoffset, width, height, format, type, pixels);
3498
3499 try
3500 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003501 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
3502 {
3503 return error(GL_INVALID_ENUM);
3504 }
3505
3506 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003507 {
3508 return error(GL_INVALID_VALUE);
3509 }
3510
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003511 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
3512 {
3513 return error(GL_INVALID_VALUE);
3514 }
3515
3516 if (!es2dx::CheckTextureFormatType(format, type))
3517 {
3518 return error(GL_INVALID_ENUM);
3519 }
3520
3521 if (width == 0 || height == 0 || pixels == NULL)
3522 {
3523 return;
3524 }
3525
3526 gl::Context *context = gl::getContext();
3527
3528 if (context)
3529 {
3530 if (target == GL_TEXTURE_2D)
3531 {
3532 gl::Texture2D *texture = context->getTexture2D();
3533
3534 if (!texture)
3535 {
3536 return error(GL_INVALID_OPERATION);
3537 }
3538
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003539 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003540 }
3541 else if (es2dx::IsCubemapTextureTarget(target))
3542 {
3543 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3544
3545 if (!texture)
3546 {
3547 return error(GL_INVALID_OPERATION);
3548 }
3549
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003550 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003551 }
3552 else
3553 {
3554 UNREACHABLE();
3555 }
3556 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003557 }
3558 catch(std::bad_alloc&)
3559 {
3560 return error(GL_OUT_OF_MEMORY);
3561 }
3562}
3563
3564void __stdcall glUniform1f(GLint location, GLfloat x)
3565{
3566 glUniform1fv(location, 1, &x);
3567}
3568
3569void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
3570{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003571 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003572
3573 try
3574 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003575 if (count < 0)
3576 {
3577 return error(GL_INVALID_VALUE);
3578 }
3579
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003580 if (location == -1)
3581 {
3582 return;
3583 }
3584
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003585 gl::Context *context = gl::getContext();
3586
3587 if (context)
3588 {
3589 gl::Program *program = context->getCurrentProgram();
3590
3591 if (!program)
3592 {
3593 return error(GL_INVALID_OPERATION);
3594 }
3595
3596 if (!program->setUniform1fv(location, count, v))
3597 {
3598 return error(GL_INVALID_OPERATION);
3599 }
3600 }
3601 }
3602 catch(std::bad_alloc&)
3603 {
3604 return error(GL_OUT_OF_MEMORY);
3605 }
3606}
3607
3608void __stdcall glUniform1i(GLint location, GLint x)
3609{
3610 glUniform1iv(location, 1, &x);
3611}
3612
3613void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
3614{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003615 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003616
3617 try
3618 {
3619 if (count < 0)
3620 {
3621 return error(GL_INVALID_VALUE);
3622 }
3623
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003624 if (location == -1)
3625 {
3626 return;
3627 }
3628
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003629 gl::Context *context = gl::getContext();
3630
3631 if (context)
3632 {
3633 gl::Program *program = context->getCurrentProgram();
3634
3635 if (!program)
3636 {
3637 return error(GL_INVALID_OPERATION);
3638 }
3639
3640 if (!program->setUniform1iv(location, count, v))
3641 {
3642 return error(GL_INVALID_OPERATION);
3643 }
3644 }
3645 }
3646 catch(std::bad_alloc&)
3647 {
3648 return error(GL_OUT_OF_MEMORY);
3649 }
3650}
3651
3652void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
3653{
3654 GLfloat xy[2] = {x, y};
3655
3656 glUniform2fv(location, 1, (GLfloat*)&xy);
3657}
3658
3659void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
3660{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003661 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003662
3663 try
3664 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003665 if (count < 0)
3666 {
3667 return error(GL_INVALID_VALUE);
3668 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003669
3670 if (location == -1)
3671 {
3672 return;
3673 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003674
3675 gl::Context *context = gl::getContext();
3676
3677 if (context)
3678 {
3679 gl::Program *program = context->getCurrentProgram();
3680
3681 if (!program)
3682 {
3683 return error(GL_INVALID_OPERATION);
3684 }
3685
3686 if (!program->setUniform2fv(location, count, v))
3687 {
3688 return error(GL_INVALID_OPERATION);
3689 }
3690 }
3691 }
3692 catch(std::bad_alloc&)
3693 {
3694 return error(GL_OUT_OF_MEMORY);
3695 }
3696}
3697
3698void __stdcall glUniform2i(GLint location, GLint x, GLint y)
3699{
3700 GLint xy[4] = {x, y};
3701
3702 glUniform2iv(location, 1, (GLint*)&xy);
3703}
3704
3705void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
3706{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003707 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003708
3709 try
3710 {
3711 if (count < 0)
3712 {
3713 return error(GL_INVALID_VALUE);
3714 }
3715
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003716 if (location == -1)
3717 {
3718 return;
3719 }
3720
3721 gl::Context *context = gl::getContext();
3722
3723 if (context)
3724 {
3725 gl::Program *program = context->getCurrentProgram();
3726
3727 if (!program)
3728 {
3729 return error(GL_INVALID_OPERATION);
3730 }
3731
3732 if (!program->setUniform2iv(location, count, v))
3733 {
3734 return error(GL_INVALID_OPERATION);
3735 }
3736 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003737 }
3738 catch(std::bad_alloc&)
3739 {
3740 return error(GL_OUT_OF_MEMORY);
3741 }
3742}
3743
3744void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
3745{
3746 GLfloat xyz[3] = {x, y, z};
3747
3748 glUniform3fv(location, 1, (GLfloat*)&xyz);
3749}
3750
3751void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
3752{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003753 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003754
3755 try
3756 {
3757 if (count < 0)
3758 {
3759 return error(GL_INVALID_VALUE);
3760 }
3761
3762 if (location == -1)
3763 {
3764 return;
3765 }
3766
3767 gl::Context *context = gl::getContext();
3768
3769 if (context)
3770 {
3771 gl::Program *program = context->getCurrentProgram();
3772
3773 if (!program)
3774 {
3775 return error(GL_INVALID_OPERATION);
3776 }
3777
3778 if (!program->setUniform3fv(location, count, v))
3779 {
3780 return error(GL_INVALID_OPERATION);
3781 }
3782 }
3783 }
3784 catch(std::bad_alloc&)
3785 {
3786 return error(GL_OUT_OF_MEMORY);
3787 }
3788}
3789
3790void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
3791{
3792 GLint xyz[3] = {x, y, z};
3793
3794 glUniform3iv(location, 1, (GLint*)&xyz);
3795}
3796
3797void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
3798{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003799 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003800
3801 try
3802 {
3803 if (count < 0)
3804 {
3805 return error(GL_INVALID_VALUE);
3806 }
3807
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003808 if (location == -1)
3809 {
3810 return;
3811 }
3812
3813 gl::Context *context = gl::getContext();
3814
3815 if (context)
3816 {
3817 gl::Program *program = context->getCurrentProgram();
3818
3819 if (!program)
3820 {
3821 return error(GL_INVALID_OPERATION);
3822 }
3823
3824 if (!program->setUniform3iv(location, count, v))
3825 {
3826 return error(GL_INVALID_OPERATION);
3827 }
3828 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003829 }
3830 catch(std::bad_alloc&)
3831 {
3832 return error(GL_OUT_OF_MEMORY);
3833 }
3834}
3835
3836void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3837{
3838 GLfloat xyzw[4] = {x, y, z, w};
3839
3840 glUniform4fv(location, 1, (GLfloat*)&xyzw);
3841}
3842
3843void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
3844{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003845 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003846
3847 try
3848 {
3849 if (count < 0)
3850 {
3851 return error(GL_INVALID_VALUE);
3852 }
3853
3854 if (location == -1)
3855 {
3856 return;
3857 }
3858
3859 gl::Context *context = gl::getContext();
3860
3861 if (context)
3862 {
3863 gl::Program *program = context->getCurrentProgram();
3864
3865 if (!program)
3866 {
3867 return error(GL_INVALID_OPERATION);
3868 }
3869
3870 if (!program->setUniform4fv(location, count, v))
3871 {
3872 return error(GL_INVALID_OPERATION);
3873 }
3874 }
3875 }
3876 catch(std::bad_alloc&)
3877 {
3878 return error(GL_OUT_OF_MEMORY);
3879 }
3880}
3881
3882void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
3883{
3884 GLint xyzw[4] = {x, y, z, w};
3885
3886 glUniform4iv(location, 1, (GLint*)&xyzw);
3887}
3888
3889void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
3890{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003891 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003892
3893 try
3894 {
3895 if (count < 0)
3896 {
3897 return error(GL_INVALID_VALUE);
3898 }
3899
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003900 if (location == -1)
3901 {
3902 return;
3903 }
3904
3905 gl::Context *context = gl::getContext();
3906
3907 if (context)
3908 {
3909 gl::Program *program = context->getCurrentProgram();
3910
3911 if (!program)
3912 {
3913 return error(GL_INVALID_OPERATION);
3914 }
3915
3916 if (!program->setUniform4iv(location, count, v))
3917 {
3918 return error(GL_INVALID_OPERATION);
3919 }
3920 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003921 }
3922 catch(std::bad_alloc&)
3923 {
3924 return error(GL_OUT_OF_MEMORY);
3925 }
3926}
3927
3928void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
3929{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003930 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
3931 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003932
3933 try
3934 {
3935 if (count < 0 || transpose != GL_FALSE)
3936 {
3937 return error(GL_INVALID_VALUE);
3938 }
3939
3940 if (location == -1)
3941 {
3942 return;
3943 }
3944
3945 gl::Context *context = gl::getContext();
3946
3947 if (context)
3948 {
3949 gl::Program *program = context->getCurrentProgram();
3950
3951 if (!program)
3952 {
3953 return error(GL_INVALID_OPERATION);
3954 }
3955
3956 if (!program->setUniformMatrix2fv(location, count, value))
3957 {
3958 return error(GL_INVALID_OPERATION);
3959 }
3960 }
3961 }
3962 catch(std::bad_alloc&)
3963 {
3964 return error(GL_OUT_OF_MEMORY);
3965 }
3966}
3967
3968void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
3969{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003970 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
3971 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003972
3973 try
3974 {
3975 if (count < 0 || transpose != GL_FALSE)
3976 {
3977 return error(GL_INVALID_VALUE);
3978 }
3979
3980 if (location == -1)
3981 {
3982 return;
3983 }
3984
3985 gl::Context *context = gl::getContext();
3986
3987 if (context)
3988 {
3989 gl::Program *program = context->getCurrentProgram();
3990
3991 if (!program)
3992 {
3993 return error(GL_INVALID_OPERATION);
3994 }
3995
3996 if (!program->setUniformMatrix3fv(location, count, value))
3997 {
3998 return error(GL_INVALID_OPERATION);
3999 }
4000 }
4001 }
4002 catch(std::bad_alloc&)
4003 {
4004 return error(GL_OUT_OF_MEMORY);
4005 }
4006}
4007
4008void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
4009{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004010 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
4011 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004012
4013 try
4014 {
4015 if (count < 0 || transpose != GL_FALSE)
4016 {
4017 return error(GL_INVALID_VALUE);
4018 }
4019
4020 if (location == -1)
4021 {
4022 return;
4023 }
4024
4025 gl::Context *context = gl::getContext();
4026
4027 if (context)
4028 {
4029 gl::Program *program = context->getCurrentProgram();
4030
4031 if (!program)
4032 {
4033 return error(GL_INVALID_OPERATION);
4034 }
4035
4036 if (!program->setUniformMatrix4fv(location, count, value))
4037 {
4038 return error(GL_INVALID_OPERATION);
4039 }
4040 }
4041 }
4042 catch(std::bad_alloc&)
4043 {
4044 return error(GL_OUT_OF_MEMORY);
4045 }
4046}
4047
4048void __stdcall glUseProgram(GLuint program)
4049{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004050 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004051
4052 try
4053 {
4054 gl::Context *context = gl::getContext();
4055
4056 if (context)
4057 {
4058 gl::Program *programObject = context->getProgram(program);
4059
4060 if (programObject && !programObject->isLinked())
4061 {
4062 return error(GL_INVALID_OPERATION);
4063 }
4064
4065 context->useProgram(program);
4066 }
4067 }
4068 catch(std::bad_alloc&)
4069 {
4070 return error(GL_OUT_OF_MEMORY);
4071 }
4072}
4073
4074void __stdcall glValidateProgram(GLuint program)
4075{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004076 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004077
4078 try
4079 {
4080 UNIMPLEMENTED(); // FIXME
4081 }
4082 catch(std::bad_alloc&)
4083 {
4084 return error(GL_OUT_OF_MEMORY);
4085 }
4086}
4087
4088void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4089{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004090 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004091
4092 try
4093 {
4094 if (index >= gl::MAX_VERTEX_ATTRIBS)
4095 {
4096 return error(GL_INVALID_VALUE);
4097 }
4098
4099 UNIMPLEMENTED(); // FIXME
4100 }
4101 catch(std::bad_alloc&)
4102 {
4103 return error(GL_OUT_OF_MEMORY);
4104 }
4105}
4106
4107void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4108{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004109 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004110
4111 try
4112 {
4113 if (index >= gl::MAX_VERTEX_ATTRIBS)
4114 {
4115 return error(GL_INVALID_VALUE);
4116 }
4117
4118 UNIMPLEMENTED(); // FIXME
4119 }
4120 catch(std::bad_alloc&)
4121 {
4122 return error(GL_OUT_OF_MEMORY);
4123 }
4124}
4125
4126void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4127{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004128 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004129
4130 try
4131 {
4132 if (index >= gl::MAX_VERTEX_ATTRIBS)
4133 {
4134 return error(GL_INVALID_VALUE);
4135 }
4136
4137 UNIMPLEMENTED(); // FIXME
4138 }
4139 catch(std::bad_alloc&)
4140 {
4141 return error(GL_OUT_OF_MEMORY);
4142 }
4143}
4144
4145void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4146{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004147 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004148
4149 try
4150 {
4151 if (index >= gl::MAX_VERTEX_ATTRIBS)
4152 {
4153 return error(GL_INVALID_VALUE);
4154 }
4155
4156 UNIMPLEMENTED(); // FIXME
4157 }
4158 catch(std::bad_alloc&)
4159 {
4160 return error(GL_OUT_OF_MEMORY);
4161 }
4162}
4163
4164void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4165{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004166 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 +00004167
4168 try
4169 {
4170 if (index >= gl::MAX_VERTEX_ATTRIBS)
4171 {
4172 return error(GL_INVALID_VALUE);
4173 }
4174
4175 UNIMPLEMENTED(); // FIXME
4176 }
4177 catch(std::bad_alloc&)
4178 {
4179 return error(GL_OUT_OF_MEMORY);
4180 }
4181}
4182
4183void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4184{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004185 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004186
4187 try
4188 {
4189 if (index >= gl::MAX_VERTEX_ATTRIBS)
4190 {
4191 return error(GL_INVALID_VALUE);
4192 }
4193
4194 UNIMPLEMENTED(); // FIXME
4195 }
4196 catch(std::bad_alloc&)
4197 {
4198 return error(GL_OUT_OF_MEMORY);
4199 }
4200}
4201
4202void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4203{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004204 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 +00004205
4206 try
4207 {
4208 if (index >= gl::MAX_VERTEX_ATTRIBS)
4209 {
4210 return error(GL_INVALID_VALUE);
4211 }
4212
4213 UNIMPLEMENTED(); // FIXME
4214 }
4215 catch(std::bad_alloc&)
4216 {
4217 return error(GL_OUT_OF_MEMORY);
4218 }
4219}
4220
4221void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4222{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004223 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004224
4225 try
4226 {
4227 if (index >= gl::MAX_VERTEX_ATTRIBS)
4228 {
4229 return error(GL_INVALID_VALUE);
4230 }
4231
4232 UNIMPLEMENTED(); // FIXME
4233 }
4234 catch(std::bad_alloc&)
4235 {
4236 return error(GL_OUT_OF_MEMORY);
4237 }
4238}
4239
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004240void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004241{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004242 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004243 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004244 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004245
4246 try
4247 {
4248 if (index >= gl::MAX_VERTEX_ATTRIBS)
4249 {
4250 return error(GL_INVALID_VALUE);
4251 }
4252
4253 if (size < 1 || size > 4)
4254 {
4255 return error(GL_INVALID_VALUE);
4256 }
4257
4258 switch (type)
4259 {
4260 case GL_BYTE:
4261 case GL_UNSIGNED_BYTE:
4262 case GL_SHORT:
4263 case GL_UNSIGNED_SHORT:
4264 case GL_FIXED:
4265 case GL_FLOAT:
4266 break;
4267 default:
4268 return error(GL_INVALID_ENUM);
4269 }
4270
4271 if (stride < 0)
4272 {
4273 return error(GL_INVALID_VALUE);
4274 }
4275
4276 gl::Context *context = gl::getContext();
4277
4278 if (context)
4279 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004280 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4281 context->vertexAttribute[index].mSize = size;
4282 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004283 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004284 context->vertexAttribute[index].mStride = stride;
4285 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004286 }
4287 }
4288 catch(std::bad_alloc&)
4289 {
4290 return error(GL_OUT_OF_MEMORY);
4291 }
4292}
4293
4294void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4295{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004296 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 +00004297
4298 try
4299 {
4300 if (width < 0 || height < 0)
4301 {
4302 return error(GL_INVALID_VALUE);
4303 }
4304
4305 gl::Context *context = gl::getContext();
4306
4307 if (context)
4308 {
4309 context->viewportX = x;
4310 context->viewportY = y;
4311 context->viewportWidth = width;
4312 context->viewportHeight = height;
4313 }
4314 }
4315 catch(std::bad_alloc&)
4316 {
4317 return error(GL_OUT_OF_MEMORY);
4318 }
4319}
4320
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004321void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4322 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004323{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004324 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4325 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004326 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004327 target, level, internalformat, width, height, depth, border, format, type, pixels);
4328
4329 try
4330 {
4331 UNIMPLEMENTED(); // FIXME
4332 }
4333 catch(std::bad_alloc&)
4334 {
4335 return error(GL_OUT_OF_MEMORY);
4336 }
4337}
4338}