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