blob: 8260525b0482998a4a280e231f13550e685434c3 [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 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001111
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001112 gl::Program *programObject = context->getProgram(program);
1113 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001114
1115 if (!programObject)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001116 {
daniel@transgaming.com73c2c2e2010-04-13 03:26:11 +00001117 gl::Shader *shaderByProgramHandle;
1118 shaderByProgramHandle = context->getShader(program);
1119 if (!shaderByProgramHandle)
1120 {
1121 return error(GL_INVALID_VALUE);
1122 }
1123 else
1124 {
1125 return error(GL_INVALID_OPERATION);
1126 }
1127 }
1128
1129 if (!shaderObject)
1130 {
1131 gl::Program *programByShaderHandle = context->getProgram(shader);
1132 if (!programByShaderHandle)
1133 {
1134 return error(GL_INVALID_VALUE);
1135 }
1136 else
1137 {
1138 return error(GL_INVALID_OPERATION);
1139 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001140 }
1141
1142 if (!programObject->detachShader(shaderObject))
1143 {
1144 return error(GL_INVALID_OPERATION);
1145 }
1146
1147 if (shaderObject->isDeletable())
1148 {
1149 context->deleteShader(shader);
1150 }
1151 }
1152 }
1153 catch(std::bad_alloc&)
1154 {
1155 return error(GL_OUT_OF_MEMORY);
1156 }
1157}
1158
1159void __stdcall glDisable(GLenum cap)
1160{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001161 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001162
1163 try
1164 {
1165 gl::Context *context = gl::getContext();
1166
1167 if (context)
1168 {
1169 switch (cap)
1170 {
1171 case GL_CULL_FACE: context->cullFace = false; break;
1172 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = false; break;
1173 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = false; break;
1174 case GL_SAMPLE_COVERAGE: context->sampleCoverage = false; break;
1175 case GL_SCISSOR_TEST: context->scissorTest = false; break;
1176 case GL_STENCIL_TEST: context->stencilTest = false; break;
1177 case GL_DEPTH_TEST: context->depthTest = false; break;
1178 case GL_BLEND: context->blend = false; break;
1179 case GL_DITHER: context->dither = false; break;
1180 default:
1181 return error(GL_INVALID_ENUM);
1182 }
1183 }
1184 }
1185 catch(std::bad_alloc&)
1186 {
1187 return error(GL_OUT_OF_MEMORY);
1188 }
1189}
1190
1191void __stdcall glDisableVertexAttribArray(GLuint index)
1192{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001193 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001194
1195 try
1196 {
1197 if (index >= gl::MAX_VERTEX_ATTRIBS)
1198 {
1199 return error(GL_INVALID_VALUE);
1200 }
1201
1202 gl::Context *context = gl::getContext();
1203
1204 if (context)
1205 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001206 context->vertexAttribute[index].mEnabled = false;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001207 }
1208 }
1209 catch(std::bad_alloc&)
1210 {
1211 return error(GL_OUT_OF_MEMORY);
1212 }
1213}
1214
1215void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1216{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001217 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001218
1219 try
1220 {
1221 if (count < 0 || first < 0)
1222 {
1223 return error(GL_INVALID_VALUE);
1224 }
1225
1226 gl::Context *context = gl::getContext();
1227
1228 if (context)
1229 {
1230 context->drawArrays(mode, first, count);
1231 }
1232 }
1233 catch(std::bad_alloc&)
1234 {
1235 return error(GL_OUT_OF_MEMORY);
1236 }
1237}
1238
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001239void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001240{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001241 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 +00001242 mode, count, type, indices);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001243
1244 try
1245 {
1246 if (count < 0)
1247 {
1248 return error(GL_INVALID_VALUE);
1249 }
1250
1251 switch (type)
1252 {
1253 case GL_UNSIGNED_BYTE:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001254 case GL_UNSIGNED_SHORT:
1255 break;
1256 default:
1257 return error(GL_INVALID_ENUM);
1258 }
1259
1260 gl::Context *context = gl::getContext();
1261
1262 if (context)
1263 {
1264 context->drawElements(mode, count, type, indices);
1265 }
1266 }
1267 catch(std::bad_alloc&)
1268 {
1269 return error(GL_OUT_OF_MEMORY);
1270 }
1271}
1272
1273void __stdcall glEnable(GLenum cap)
1274{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001275 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001276
1277 try
1278 {
1279 gl::Context *context = gl::getContext();
1280
1281 if (context)
1282 {
1283 switch (cap)
1284 {
1285 case GL_CULL_FACE: context->cullFace = true; break;
1286 case GL_POLYGON_OFFSET_FILL: context->polygonOffsetFill = true; break;
1287 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->sampleAlphaToCoverage = true; break;
1288 case GL_SAMPLE_COVERAGE: context->sampleCoverage = true; break;
1289 case GL_SCISSOR_TEST: context->scissorTest = true; break;
1290 case GL_STENCIL_TEST: context->stencilTest = true; break;
1291 case GL_DEPTH_TEST: context->depthTest = true; break;
1292 case GL_BLEND: context->blend = true; break;
1293 case GL_DITHER: context->dither = true; break;
1294 default:
1295 return error(GL_INVALID_ENUM);
1296 }
1297 }
1298 }
1299 catch(std::bad_alloc&)
1300 {
1301 return error(GL_OUT_OF_MEMORY);
1302 }
1303}
1304
1305void __stdcall glEnableVertexAttribArray(GLuint index)
1306{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001307 TRACE("(GLuint index = %d)", index);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001308
1309 try
1310 {
1311 if (index >= gl::MAX_VERTEX_ATTRIBS)
1312 {
1313 return error(GL_INVALID_VALUE);
1314 }
1315
1316 gl::Context *context = gl::getContext();
1317
1318 if (context)
1319 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001320 context->vertexAttribute[index].mEnabled = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001321 }
1322 }
1323 catch(std::bad_alloc&)
1324 {
1325 return error(GL_OUT_OF_MEMORY);
1326 }
1327}
1328
1329void __stdcall glFinish(void)
1330{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001331 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001332
1333 try
1334 {
1335 gl::Context *context = gl::getContext();
1336
1337 if (context)
1338 {
1339 context->finish();
1340 }
1341 }
1342 catch(std::bad_alloc&)
1343 {
1344 return error(GL_OUT_OF_MEMORY);
1345 }
1346}
1347
1348void __stdcall glFlush(void)
1349{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001350 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001351
1352 try
1353 {
1354 gl::Context *context = gl::getContext();
1355
1356 if (context)
1357 {
1358 context->flush();
1359 }
1360 }
1361 catch(std::bad_alloc&)
1362 {
1363 return error(GL_OUT_OF_MEMORY);
1364 }
1365}
1366
1367void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1368{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001369 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1370 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001371
1372 try
1373 {
1374 if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
1375 {
1376 return error(GL_INVALID_ENUM);
1377 }
1378
1379 gl::Context *context = gl::getContext();
1380
1381 if (context)
1382 {
1383 gl::Framebuffer *framebuffer = context->getFramebuffer();
1384
1385 if (context->framebuffer == 0 || !framebuffer)
1386 {
1387 return error(GL_INVALID_OPERATION);
1388 }
1389
1390 switch (attachment)
1391 {
1392 case GL_COLOR_ATTACHMENT0:
1393 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1394 break;
1395 case GL_DEPTH_ATTACHMENT:
1396 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1397 break;
1398 case GL_STENCIL_ATTACHMENT:
1399 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1400 break;
1401 default:
1402 return error(GL_INVALID_ENUM);
1403 }
1404 }
1405 }
1406 catch(std::bad_alloc&)
1407 {
1408 return error(GL_OUT_OF_MEMORY);
1409 }
1410}
1411
1412void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1413{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001414 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1415 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001416
1417 try
1418 {
1419 if (target != GL_FRAMEBUFFER)
1420 {
1421 return error(GL_INVALID_ENUM);
1422 }
1423
1424 switch (attachment)
1425 {
1426 case GL_COLOR_ATTACHMENT0:
1427 break;
1428 default:
1429 return error(GL_INVALID_ENUM);
1430 }
1431
1432 gl::Context *context = gl::getContext();
1433
1434 if (context)
1435 {
1436 if (texture)
1437 {
1438 switch (textarget)
1439 {
1440 case GL_TEXTURE_2D:
1441 if (!context->getTexture2D())
1442 {
1443 return error(GL_INVALID_OPERATION);
1444 }
1445 break;
1446 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1447 UNIMPLEMENTED(); // FIXME
1448 break;
1449 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1450 UNIMPLEMENTED(); // FIXME
1451 break;
1452 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1453 UNIMPLEMENTED(); // FIXME
1454 break;
1455 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1456 UNIMPLEMENTED(); // FIXME
1457 break;
1458 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1459 UNIMPLEMENTED(); // FIXME
1460 break;
1461 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1462 UNIMPLEMENTED(); // FIXME
1463 break;
1464 default:
1465 return error(GL_INVALID_ENUM);
1466 }
1467
1468 if (level != 0)
1469 {
1470 return error(GL_INVALID_VALUE);
1471 }
1472 }
1473
1474 gl::Framebuffer *framebuffer = context->getFramebuffer();
1475
1476 if (context->framebuffer == 0 || !framebuffer)
1477 {
1478 return error(GL_INVALID_OPERATION);
1479 }
1480
1481 framebuffer->setColorbuffer(GL_TEXTURE, texture);
1482 }
1483 }
1484 catch(std::bad_alloc&)
1485 {
1486 return error(GL_OUT_OF_MEMORY);
1487 }
1488}
1489
1490void __stdcall glFrontFace(GLenum mode)
1491{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001492 TRACE("(GLenum mode = 0x%X)", mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001493
1494 try
1495 {
1496 switch (mode)
1497 {
1498 case GL_CW:
1499 case GL_CCW:
1500 {
1501 gl::Context *context = gl::getContext();
1502
1503 if (context)
1504 {
1505 context->frontFace = mode;
1506 }
1507 }
1508 break;
1509 default:
1510 return error(GL_INVALID_ENUM);
1511 }
1512 }
1513 catch(std::bad_alloc&)
1514 {
1515 return error(GL_OUT_OF_MEMORY);
1516 }
1517}
1518
1519void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
1520{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001521 TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001522
1523 try
1524 {
1525 if (n < 0)
1526 {
1527 return error(GL_INVALID_VALUE);
1528 }
1529
1530 gl::Context *context = gl::getContext();
1531
1532 if (context)
1533 {
1534 for (int i = 0; i < n; i++)
1535 {
1536 buffers[i] = context->createBuffer();
1537 }
1538 }
1539 }
1540 catch(std::bad_alloc&)
1541 {
1542 return error(GL_OUT_OF_MEMORY);
1543 }
1544}
1545
1546void __stdcall glGenerateMipmap(GLenum target)
1547{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001548 TRACE("(GLenum target = 0x%X)", target);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001549
1550 try
1551 {
1552 UNIMPLEMENTED(); // FIXME
1553 }
1554 catch(std::bad_alloc&)
1555 {
1556 return error(GL_OUT_OF_MEMORY);
1557 }
1558}
1559
1560void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
1561{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001562 TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001563
1564 try
1565 {
1566 if (n < 0)
1567 {
1568 return error(GL_INVALID_VALUE);
1569 }
1570
1571 gl::Context *context = gl::getContext();
1572
1573 if (context)
1574 {
1575 for (int i = 0; i < n; i++)
1576 {
1577 framebuffers[i] = context->createFramebuffer();
1578 }
1579 }
1580 }
1581 catch(std::bad_alloc&)
1582 {
1583 return error(GL_OUT_OF_MEMORY);
1584 }
1585}
1586
1587void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
1588{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001589 TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001590
1591 try
1592 {
1593 if (n < 0)
1594 {
1595 return error(GL_INVALID_VALUE);
1596 }
1597
1598 gl::Context *context = gl::getContext();
1599
1600 if (context)
1601 {
1602 for (int i = 0; i < n; i++)
1603 {
1604 renderbuffers[i] = context->createRenderbuffer();
1605 }
1606 }
1607 }
1608 catch(std::bad_alloc&)
1609 {
1610 return error(GL_OUT_OF_MEMORY);
1611 }
1612}
1613
1614void __stdcall glGenTextures(GLsizei n, GLuint* textures)
1615{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001616 TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001617
1618 try
1619 {
1620 if (n < 0)
1621 {
1622 return error(GL_INVALID_VALUE);
1623 }
1624
1625 gl::Context *context = gl::getContext();
1626
1627 if (context)
1628 {
1629 for (int i = 0; i < n; i++)
1630 {
1631 textures[i] = context->createTexture();
1632 }
1633 }
1634 }
1635 catch(std::bad_alloc&)
1636 {
1637 return error(GL_OUT_OF_MEMORY);
1638 }
1639}
1640
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001641void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001642{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001643 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001644 "GLint* size = 0x%0.8p, GLenum* type = %0.8p, GLchar* name = %0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001645 program, index, bufsize, length, size, type, name);
1646
1647 try
1648 {
1649 if (bufsize < 0)
1650 {
1651 return error(GL_INVALID_VALUE);
1652 }
1653
1654 UNIMPLEMENTED(); // FIXME
1655 }
1656 catch(std::bad_alloc&)
1657 {
1658 return error(GL_OUT_OF_MEMORY);
1659 }
1660}
1661
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001662void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001663{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001664 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001665 "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 +00001666 program, index, bufsize, length, size, type, name);
1667
1668 try
1669 {
1670 if (bufsize < 0)
1671 {
1672 return error(GL_INVALID_VALUE);
1673 }
1674
1675 UNIMPLEMENTED(); // FIXME
1676 }
1677 catch(std::bad_alloc&)
1678 {
1679 return error(GL_OUT_OF_MEMORY);
1680 }
1681}
1682
1683void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1684{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001685 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1686 program, maxcount, count, shaders);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001687
1688 try
1689 {
1690 if (maxcount < 0)
1691 {
1692 return error(GL_INVALID_VALUE);
1693 }
1694
daniel@transgaming.com6c785212010-03-30 03:36:17 +00001695 gl::Context *context = gl::getContext();
1696
1697 if (context)
1698 {
1699 gl::Program *programObject = context->getProgram(program);
1700
1701 if (!programObject)
1702 {
1703 return error(GL_INVALID_VALUE);
1704 }
1705
1706 return programObject->getAttachedShaders(maxcount, count, shaders);
1707 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001708 }
1709 catch(std::bad_alloc&)
1710 {
1711 return error(GL_OUT_OF_MEMORY);
1712 }
1713}
1714
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001715int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001716{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00001717 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001718
1719 try
1720 {
1721 gl::Context *context = gl::getContext();
1722
1723 if (context)
1724 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001725
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001726 gl::Program *programObject = context->getProgram(program);
1727
1728 if (!programObject)
1729 {
daniel@transgaming.combb274c32010-04-13 03:26:21 +00001730 if (context->getShader(program))
1731 {
1732 return error(GL_INVALID_OPERATION, -1);
1733 }
1734 else
1735 {
1736 return error(GL_INVALID_VALUE, -1);
1737 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001738 }
1739
1740 return programObject->getAttributeLocation(name);
1741 }
1742 }
1743 catch(std::bad_alloc&)
1744 {
1745 return error(GL_OUT_OF_MEMORY, -1);
1746 }
1747
1748 return -1;
1749}
1750
1751void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
1752{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001753 TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001754
1755 try
1756 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001757 gl::Context *context = gl::getContext();
1758
1759 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001760 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001761 if (!(context->getBooleanv(pname, params)))
1762 {
1763 GLenum nativeType;
1764 unsigned int numParams = 0;
1765 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1766 return error(GL_INVALID_ENUM);
1767
1768 if (numParams == 0)
1769 return; // it is known that the pname is valid, but there are no parameters to return
1770
1771 if (nativeType == GL_FLOAT)
1772 {
1773 GLfloat *floatParams = NULL;
1774 floatParams = new GLfloat[numParams];
1775
1776 context->getFloatv(pname, floatParams);
1777
1778 for (unsigned int i = 0; i < numParams; ++i)
1779 {
1780 if (floatParams[i] == 0.0f)
1781 params[i] = GL_FALSE;
1782 else
1783 params[i] = GL_TRUE;
1784 }
1785
1786 delete [] floatParams;
1787 }
1788 else if (nativeType == GL_INT)
1789 {
1790 GLint *intParams = NULL;
1791 intParams = new GLint[numParams];
1792
1793 context->getIntegerv(pname, intParams);
1794
1795 for (unsigned int i = 0; i < numParams; ++i)
1796 {
1797 if (intParams[i] == 0)
1798 params[i] = GL_FALSE;
1799 else
1800 params[i] = GL_TRUE;
1801 }
1802
1803 delete [] intParams;
1804 }
1805 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001806 }
1807 }
1808 catch(std::bad_alloc&)
1809 {
1810 return error(GL_OUT_OF_MEMORY);
1811 }
1812}
1813
1814void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1815{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001816 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 +00001817
1818 try
1819 {
1820 UNIMPLEMENTED(); // FIXME
1821 }
1822 catch(std::bad_alloc&)
1823 {
1824 return error(GL_OUT_OF_MEMORY);
1825 }
1826}
1827
1828GLenum __stdcall glGetError(void)
1829{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001830 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001831
1832 gl::Context *context = gl::getContext();
1833
1834 if (context)
1835 {
1836 return context->getError();
1837 }
1838
1839 return GL_NO_ERROR;
1840}
1841
1842void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
1843{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001844 TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001845
1846 try
1847 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001848 gl::Context *context = gl::getContext();
1849
1850 if (context)
1851 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001852 if (!(context->getFloatv(pname, params)))
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001853 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001854 GLenum nativeType;
1855 unsigned int numParams = 0;
1856 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1857 return error(GL_INVALID_ENUM);
1858
1859 if (numParams == 0)
1860 return; // it is known that the pname is valid, but that there are no parameters to return.
1861
1862 if (nativeType == GL_BOOL)
1863 {
1864 GLboolean *boolParams = NULL;
1865 boolParams = new GLboolean[numParams];
1866
1867 context->getBooleanv(pname, boolParams);
1868
1869 for (unsigned int i = 0; i < numParams; ++i)
1870 {
1871 if (boolParams[i] == GL_FALSE)
1872 params[i] = 0.0f;
1873 else
1874 params[i] = 1.0f;
1875 }
1876
1877 delete [] boolParams;
1878 }
1879 else if (nativeType == GL_INT)
1880 {
1881 GLint *intParams = NULL;
1882 intParams = new GLint[numParams];
1883
1884 context->getIntegerv(pname, intParams);
1885
1886 for (unsigned int i = 0; i < numParams; ++i)
1887 {
1888 params[i] = (GLfloat)intParams[i];
1889 }
1890
1891 delete [] intParams;
1892 }
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00001893 }
1894 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001895 }
1896 catch(std::bad_alloc&)
1897 {
1898 return error(GL_OUT_OF_MEMORY);
1899 }
1900}
1901
1902void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
1903{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001904 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
1905 target, attachment, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001906
1907 try
1908 {
1909 gl::Context *context = gl::getContext();
1910
1911 if (context)
1912 {
1913 if (context->framebuffer == 0)
1914 {
1915 return error(GL_INVALID_OPERATION);
1916 }
1917
1918 UNIMPLEMENTED(); // FIXME
1919 }
1920 }
1921 catch(std::bad_alloc&)
1922 {
1923 return error(GL_OUT_OF_MEMORY);
1924 }
1925}
1926
1927void __stdcall glGetIntegerv(GLenum pname, GLint* params)
1928{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001929 TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001930
1931 try
1932 {
1933 gl::Context *context = gl::getContext();
1934
1935 if (context)
1936 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001937 if (!(context->getIntegerv(pname, params)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001938 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001939 GLenum nativeType;
1940 unsigned int numParams = 0;
1941 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
1942 return error(GL_INVALID_ENUM);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001943
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001944 if (numParams == 0)
1945 return; // it is known that pname is valid, but there are no parameters to return
1946
1947 if (nativeType == GL_BOOL)
1948 {
1949 GLboolean *boolParams = NULL;
1950 boolParams = new GLboolean[numParams];
1951
1952 context->getBooleanv(pname, boolParams);
1953
1954 for (unsigned int i = 0; i < numParams; ++i)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001955 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001956 if (boolParams[i] == GL_FALSE)
1957 params[i] = 0;
1958 else
1959 params[i] = 1;
1960 }
1961
1962 delete [] boolParams;
1963 }
1964 else if (nativeType == GL_FLOAT)
1965 {
1966 GLfloat *floatParams = NULL;
1967 floatParams = new GLfloat[numParams];
1968
1969 context->getFloatv(pname, floatParams);
1970
1971 for (unsigned int i = 0; i < numParams; ++i)
1972 {
1973 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001974 {
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001975 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001976 }
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001977 else
1978 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 +00001979 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001980
daniel@transgaming.com777f2672010-04-07 03:25:16 +00001981 delete [] floatParams;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001982 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001983 }
1984 }
1985 }
1986 catch(std::bad_alloc&)
1987 {
1988 return error(GL_OUT_OF_MEMORY);
1989 }
1990}
1991
1992void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
1993{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00001994 TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001995
1996 try
1997 {
1998 gl::Context *context = gl::getContext();
1999
2000 if (context)
2001 {
2002 gl::Program *programObject = context->getProgram(program);
2003
2004 if (!programObject)
2005 {
2006 return error(GL_INVALID_VALUE);
2007 }
2008
2009 switch (pname)
2010 {
2011 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002012 *params = programObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002013 return;
2014 case GL_LINK_STATUS:
2015 *params = programObject->isLinked();
2016 return;
2017 case GL_VALIDATE_STATUS:
2018 UNIMPLEMENTED(); // FIXME
2019 *params = GL_TRUE;
2020 return;
2021 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002022 *params = programObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002023 return;
2024 case GL_ATTACHED_SHADERS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002025 *params = programObject->getAttachedShadersCount();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002026 return;
2027 case GL_ACTIVE_ATTRIBUTES:
2028 UNIMPLEMENTED(); // FIXME
2029 *params = 0;
2030 return;
2031 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2032 UNIMPLEMENTED(); // FIXME
2033 *params = 0;
2034 return;
2035 case GL_ACTIVE_UNIFORMS:
2036 UNIMPLEMENTED(); // FIXME
2037 *params = 0;
2038 return;
2039 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2040 UNIMPLEMENTED(); // FIXME
2041 *params = 0;
2042 return;
2043 default:
2044 return error(GL_INVALID_ENUM);
2045 }
2046 }
2047 }
2048 catch(std::bad_alloc&)
2049 {
2050 return error(GL_OUT_OF_MEMORY);
2051 }
2052}
2053
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002054void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002055{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002056 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 +00002057 program, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002058
2059 try
2060 {
2061 if (bufsize < 0)
2062 {
2063 return error(GL_INVALID_VALUE);
2064 }
2065
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002066 gl::Context *context = gl::getContext();
2067
2068 if (context)
2069 {
2070 gl::Program *programObject = context->getProgram(program);
2071
2072 if (!programObject)
2073 {
2074 return error(GL_INVALID_VALUE);
2075 }
2076
2077 programObject->getInfoLog(bufsize, length, infolog);
2078 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002079 }
2080 catch(std::bad_alloc&)
2081 {
2082 return error(GL_OUT_OF_MEMORY);
2083 }
2084}
2085
2086void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2087{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002088 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 +00002089
2090 try
2091 {
2092 UNIMPLEMENTED(); // FIXME
2093 }
2094 catch(std::bad_alloc&)
2095 {
2096 return error(GL_OUT_OF_MEMORY);
2097 }
2098}
2099
2100void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
2101{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002102 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002103
2104 try
2105 {
2106 gl::Context *context = gl::getContext();
2107
2108 if (context)
2109 {
2110 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002111
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002112 if (!shaderObject)
2113 {
2114 return error(GL_INVALID_VALUE);
2115 }
2116
2117 switch (pname)
2118 {
2119 case GL_SHADER_TYPE:
2120 *params = shaderObject->getType();
2121 return;
2122 case GL_DELETE_STATUS:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002123 *params = shaderObject->isFlaggedForDeletion();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002124 return;
2125 case GL_COMPILE_STATUS:
2126 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
2127 return;
2128 case GL_INFO_LOG_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002129 *params = shaderObject->getInfoLogLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002130 return;
2131 case GL_SHADER_SOURCE_LENGTH:
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002132 *params = shaderObject->getSourceLength();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002133 return;
2134 default:
2135 return error(GL_INVALID_ENUM);
2136 }
2137 }
2138 }
2139 catch(std::bad_alloc&)
2140 {
2141 return error(GL_OUT_OF_MEMORY);
2142 }
2143}
2144
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002145void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002146{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002147 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 +00002148 shader, bufsize, length, infolog);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002149
2150 try
2151 {
2152 if (bufsize < 0)
2153 {
2154 return error(GL_INVALID_VALUE);
2155 }
2156
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002157 gl::Context *context = gl::getContext();
2158
2159 if (context)
2160 {
2161 gl::Shader *shaderObject = context->getShader(shader);
2162
2163 if (!shaderObject)
2164 {
2165 return error(GL_INVALID_VALUE);
2166 }
2167
2168 shaderObject->getInfoLog(bufsize, length, infolog);
2169 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002170 }
2171 catch(std::bad_alloc&)
2172 {
2173 return error(GL_OUT_OF_MEMORY);
2174 }
2175}
2176
2177void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
2178{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002179 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
2180 shadertype, precisiontype, range, precision);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002181
2182 try
2183 {
daniel@transgaming.com6c785212010-03-30 03:36:17 +00002184 switch (shadertype)
2185 {
2186 case GL_VERTEX_SHADER:
2187 case GL_FRAGMENT_SHADER:
2188 break;
2189 default:
2190 return error(GL_INVALID_ENUM);
2191 }
2192
2193 switch (precisiontype)
2194 {
2195 case GL_LOW_FLOAT:
2196 case GL_MEDIUM_FLOAT:
2197 case GL_HIGH_FLOAT:
2198 // Assume IEEE 754 precision
2199 range[0] = 127;
2200 range[1] = 127;
2201 precision[0] = 23;
2202 precision[1] = 23;
2203 break;
2204 case GL_LOW_INT:
2205 case GL_MEDIUM_INT:
2206 case GL_HIGH_INT:
2207 // Some (most) hardware only supports single-precision floating-point numbers,
2208 // which can accurately represent integers up to +/-16777216
2209 range[0] = 24;
2210 range[1] = 24;
2211 precision[0] = 0;
2212 precision[1] = 0;
2213 break;
2214 default:
2215 return error(GL_INVALID_ENUM);
2216 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002217 }
2218 catch(std::bad_alloc&)
2219 {
2220 return error(GL_OUT_OF_MEMORY);
2221 }
2222}
2223
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002224void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002225{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002226 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 +00002227 shader, bufsize, length, source);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002228
2229 try
2230 {
2231 if (bufsize < 0)
2232 {
2233 return error(GL_INVALID_VALUE);
2234 }
2235
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002236 gl::Context *context = gl::getContext();
2237
2238 if (context)
2239 {
2240 gl::Shader *shaderObject = context->getShader(shader);
2241
2242 if (!shaderObject)
2243 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00002244 return error(GL_INVALID_OPERATION);
daniel@transgaming.comcba50572010-03-28 19:36:09 +00002245 }
2246
2247 shaderObject->getSource(bufsize, length, source);
2248 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002249 }
2250 catch(std::bad_alloc&)
2251 {
2252 return error(GL_OUT_OF_MEMORY);
2253 }
2254}
2255
2256const GLubyte* __stdcall glGetString(GLenum name)
2257{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002258 TRACE("(GLenum name = 0x%X)", name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002259
2260 try
2261 {
2262 switch (name)
2263 {
2264 case GL_VENDOR:
2265 return (GLubyte*)"TransGaming Inc.";
2266 case GL_RENDERER:
2267 return (GLubyte*)"ANGLE";
2268 case GL_VERSION:
2269 return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
2270 case GL_SHADING_LANGUAGE_VERSION:
2271 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
2272 case GL_EXTENSIONS:
2273 return (GLubyte*)"";
2274 default:
2275 return error(GL_INVALID_ENUM, (GLubyte*)NULL);
2276 }
2277 }
2278 catch(std::bad_alloc&)
2279 {
2280 return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
2281 }
2282
2283 return NULL;
2284}
2285
2286void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2287{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002288 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 +00002289
2290 try
2291 {
2292 UNIMPLEMENTED(); // FIXME
2293 }
2294 catch(std::bad_alloc&)
2295 {
2296 return error(GL_OUT_OF_MEMORY);
2297 }
2298}
2299
2300void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2301{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002302 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 +00002303
2304 try
2305 {
2306 UNIMPLEMENTED(); // FIXME
2307 }
2308 catch(std::bad_alloc&)
2309 {
2310 return error(GL_OUT_OF_MEMORY);
2311 }
2312}
2313
2314void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
2315{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002316 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002317
2318 try
2319 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002320 gl::Context *context = gl::getContext();
2321
2322 if (context)
2323 {
2324 if (program == 0)
2325 {
2326 return error(GL_INVALID_VALUE);
2327 }
2328
2329 gl::Program *programObject = context->getProgram(program);
2330
2331 if (!programObject || !programObject->isLinked())
2332 {
2333 return error(GL_INVALID_OPERATION);
2334 }
2335
2336 if (!programObject->getUniformfv(location, params))
2337 {
2338 return error(GL_INVALID_OPERATION);
2339 }
2340 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002341 }
2342 catch(std::bad_alloc&)
2343 {
2344 return error(GL_OUT_OF_MEMORY);
2345 }
2346}
2347
2348void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
2349{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002350 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002351
2352 try
2353 {
daniel@transgaming.combb3d9d02010-04-13 03:26:06 +00002354 gl::Context *context = gl::getContext();
2355
2356 if (context)
2357 {
2358 if (program == 0)
2359 {
2360 return error(GL_INVALID_VALUE);
2361 }
2362
2363 gl::Program *programObject = context->getProgram(program);
2364
2365 if (!programObject || !programObject->isLinked())
2366 {
2367 return error(GL_INVALID_OPERATION);
2368 }
2369
2370 if (!programObject)
2371 {
2372 return error(GL_INVALID_OPERATION);
2373 }
2374
2375 if (!programObject->getUniformiv(location, params))
2376 {
2377 return error(GL_INVALID_OPERATION);
2378 }
2379 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002380 }
2381 catch(std::bad_alloc&)
2382 {
2383 return error(GL_OUT_OF_MEMORY);
2384 }
2385}
2386
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002387int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002388{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002389 TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002390
2391 try
2392 {
2393 gl::Context *context = gl::getContext();
2394
2395 if (strstr(name, "gl_") == name)
2396 {
2397 return -1;
2398 }
2399
2400 if (context)
2401 {
2402 gl::Program *programObject = context->getProgram(program);
2403
2404 if (!programObject)
2405 {
2406 return error(GL_INVALID_VALUE, -1);
2407 }
2408
2409 if (!programObject->isLinked())
2410 {
2411 return error(GL_INVALID_OPERATION, -1);
2412 }
2413
2414 return programObject->getUniformLocation(name);
2415 }
2416 }
2417 catch(std::bad_alloc&)
2418 {
2419 return error(GL_OUT_OF_MEMORY, -1);
2420 }
2421
2422 return -1;
2423}
2424
2425void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
2426{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002427 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002428
2429 try
2430 {
2431 if (index >= gl::MAX_VERTEX_ATTRIBS)
2432 {
2433 return error(GL_INVALID_VALUE);
2434 }
2435
2436 UNIMPLEMENTED(); // FIXME
2437 }
2438 catch(std::bad_alloc&)
2439 {
2440 return error(GL_OUT_OF_MEMORY);
2441 }
2442}
2443
2444void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
2445{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002446 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002447
2448 try
2449 {
2450 if (index >= gl::MAX_VERTEX_ATTRIBS)
2451 {
2452 return error(GL_INVALID_VALUE);
2453 }
2454
2455 UNIMPLEMENTED(); // FIXME
2456 }
2457 catch(std::bad_alloc&)
2458 {
2459 return error(GL_OUT_OF_MEMORY);
2460 }
2461}
2462
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002463void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002464{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002465 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002466
2467 try
2468 {
2469 if (index >= gl::MAX_VERTEX_ATTRIBS)
2470 {
2471 return error(GL_INVALID_VALUE);
2472 }
2473
2474 UNIMPLEMENTED(); // FIXME
2475 }
2476 catch(std::bad_alloc&)
2477 {
2478 return error(GL_OUT_OF_MEMORY);
2479 }
2480}
2481
2482void __stdcall glHint(GLenum target, GLenum mode)
2483{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002484 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002485
2486 try
2487 {
daniel@transgaming.com5949aa12010-03-21 04:31:15 +00002488 switch (target)
2489 {
2490 case GL_GENERATE_MIPMAP_HINT:
2491 switch (mode)
2492 {
2493 case GL_FASTEST:
2494 case GL_NICEST:
2495 case GL_DONT_CARE:
2496 break;
2497 default:
2498 return error(GL_INVALID_ENUM);
2499 }
2500 break;
2501 default:
2502 return error(GL_INVALID_ENUM);
2503 }
2504
2505 gl::Context *context = gl::getContext();
2506 if (context)
2507 {
2508 if (target == GL_GENERATE_MIPMAP_HINT)
2509 context->generateMipmapHint = mode;
2510 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002511 }
2512 catch(std::bad_alloc&)
2513 {
2514 return error(GL_OUT_OF_MEMORY);
2515 }
2516}
2517
2518GLboolean __stdcall glIsBuffer(GLuint buffer)
2519{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002520 TRACE("(GLuint buffer = %d)", buffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002521
2522 try
2523 {
2524 gl::Context *context = gl::getContext();
2525
2526 if (context && buffer)
2527 {
2528 gl::Buffer *bufferObject = context->getBuffer(buffer);
2529
2530 if (bufferObject)
2531 {
2532 return GL_TRUE;
2533 }
2534 }
2535 }
2536 catch(std::bad_alloc&)
2537 {
2538 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2539 }
2540
2541 return GL_FALSE;
2542}
2543
2544GLboolean __stdcall glIsEnabled(GLenum cap)
2545{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002546 TRACE("(GLenum cap = 0x%X)", cap);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002547
2548 try
2549 {
2550 gl::Context *context = gl::getContext();
2551
2552 if (context)
2553 {
2554 switch (cap)
2555 {
2556 case GL_CULL_FACE: return context->cullFace;
2557 case GL_POLYGON_OFFSET_FILL: return context->polygonOffsetFill;
2558 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->sampleAlphaToCoverage;
2559 case GL_SAMPLE_COVERAGE: return context->sampleCoverage;
2560 case GL_SCISSOR_TEST: return context->scissorTest;
2561 case GL_STENCIL_TEST: return context->stencilTest;
2562 case GL_DEPTH_TEST: return context->depthTest;
2563 case GL_BLEND: return context->blend;
2564 case GL_DITHER: return context->dither;
2565 default:
2566 return error(GL_INVALID_ENUM, false);
2567 }
2568 }
2569 }
2570 catch(std::bad_alloc&)
2571 {
2572 return error(GL_OUT_OF_MEMORY, false);
2573 }
2574
2575 return false;
2576}
2577
2578GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
2579{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002580 TRACE("(GLuint framebuffer = %d)", framebuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002581
2582 try
2583 {
2584 gl::Context *context = gl::getContext();
2585
2586 if (context && framebuffer)
2587 {
2588 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2589
2590 if (framebufferObject)
2591 {
2592 return GL_TRUE;
2593 }
2594 }
2595 }
2596 catch(std::bad_alloc&)
2597 {
2598 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2599 }
2600
2601 return GL_FALSE;
2602}
2603
2604GLboolean __stdcall glIsProgram(GLuint program)
2605{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002606 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002607
2608 try
2609 {
2610 gl::Context *context = gl::getContext();
2611
2612 if (context && program)
2613 {
2614 gl::Program *programObject = context->getProgram(program);
2615
2616 if (programObject)
2617 {
2618 return GL_TRUE;
2619 }
2620 }
2621 }
2622 catch(std::bad_alloc&)
2623 {
2624 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2625 }
2626
2627 return GL_FALSE;
2628}
2629
2630GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
2631{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002632 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002633
2634 try
2635 {
2636 gl::Context *context = gl::getContext();
2637
2638 if (context && renderbuffer)
2639 {
2640 gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2641
2642 if (renderbufferObject)
2643 {
2644 return GL_TRUE;
2645 }
2646 }
2647 }
2648 catch(std::bad_alloc&)
2649 {
2650 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2651 }
2652
2653 return GL_FALSE;
2654}
2655
2656GLboolean __stdcall glIsShader(GLuint shader)
2657{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002658 TRACE("(GLuint shader = %d)", shader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002659
2660 try
2661 {
2662 gl::Context *context = gl::getContext();
2663
2664 if (context && shader)
2665 {
2666 gl::Shader *shaderObject = context->getShader(shader);
2667
2668 if (shaderObject)
2669 {
2670 return GL_TRUE;
2671 }
2672 }
2673 }
2674 catch(std::bad_alloc&)
2675 {
2676 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2677 }
2678
2679 return GL_FALSE;
2680}
2681
2682GLboolean __stdcall glIsTexture(GLuint texture)
2683{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002684 TRACE("(GLuint texture = %d)", texture);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002685
2686 try
2687 {
2688 gl::Context *context = gl::getContext();
2689
2690 if (context && texture)
2691 {
2692 gl::Texture *textureObject = context->getTexture(texture);
2693
2694 if (textureObject)
2695 {
2696 return GL_TRUE;
2697 }
2698 }
2699 }
2700 catch(std::bad_alloc&)
2701 {
2702 return error(GL_OUT_OF_MEMORY, GL_FALSE);
2703 }
2704
2705 return GL_FALSE;
2706}
2707
2708void __stdcall glLineWidth(GLfloat width)
2709{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002710 TRACE("(GLfloat width = %f)", width);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002711
2712 try
2713 {
2714 if (width <= 0.0f)
2715 {
2716 return error(GL_INVALID_VALUE);
2717 }
2718
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002719 gl::Context *context = gl::getContext();
2720
2721 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002722 {
daniel@transgaming.com32e58cd2010-03-24 09:44:10 +00002723 context->lineWidth = width;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002724 }
2725 }
2726 catch(std::bad_alloc&)
2727 {
2728 return error(GL_OUT_OF_MEMORY);
2729 }
2730}
2731
2732void __stdcall glLinkProgram(GLuint program)
2733{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002734 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002735
2736 try
2737 {
2738 gl::Context *context = gl::getContext();
2739
2740 if (context)
2741 {
2742 gl::Program *programObject = context->getProgram(program);
2743
2744 if (!programObject)
2745 {
2746 return error(GL_INVALID_VALUE);
2747 }
2748
2749 programObject->link();
2750 }
2751 }
2752 catch(std::bad_alloc&)
2753 {
2754 return error(GL_OUT_OF_MEMORY);
2755 }
2756}
2757
2758void __stdcall glPixelStorei(GLenum pname, GLint param)
2759{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002760 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002761
2762 try
2763 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002764 gl::Context *context = gl::getContext();
2765
2766 if (context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002767 {
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00002768 switch (pname)
2769 {
2770 case GL_UNPACK_ALIGNMENT:
2771 if (param != 1 && param != 2 && param != 4 && param != 8)
2772 {
2773 return error(GL_INVALID_VALUE);
2774 }
2775
2776 context->unpackAlignment = param;
2777 break;
2778
2779 case GL_PACK_ALIGNMENT:
2780 if (param != 1 && param != 2 && param != 4 && param != 8)
2781 {
2782 return error(GL_INVALID_VALUE);
2783 }
2784
2785 context->packAlignment = param;
2786 break;
2787
2788 default:
2789 return error(GL_INVALID_ENUM);
2790 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002791 }
2792 }
2793 catch(std::bad_alloc&)
2794 {
2795 return error(GL_OUT_OF_MEMORY);
2796 }
2797}
2798
2799void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
2800{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002801 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002802
2803 try
2804 {
2805 if (factor != 0.0f || units != 0.0f)
2806 {
2807 UNIMPLEMENTED(); // FIXME
2808 }
2809 }
2810 catch(std::bad_alloc&)
2811 {
2812 return error(GL_OUT_OF_MEMORY);
2813 }
2814}
2815
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002816void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002817{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002818 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002819 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002820 x, y, width, height, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002821
2822 try
2823 {
2824 if (width < 0 || height < 0)
2825 {
2826 return error(GL_INVALID_VALUE);
2827 }
2828
2829 switch (format)
2830 {
2831 case GL_RGBA:
2832 switch (type)
2833 {
2834 case GL_UNSIGNED_BYTE:
2835 break;
2836 default:
2837 return error(GL_INVALID_OPERATION);
2838 }
2839 break;
2840 case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
2841 switch (type)
2842 {
2843 case gl::IMPLEMENTATION_COLOR_READ_TYPE:
2844 break;
2845 default:
2846 return error(GL_INVALID_OPERATION);
2847 }
2848 break;
2849 default:
2850 return error(GL_INVALID_OPERATION);
2851 }
2852
2853 gl::Context *context = gl::getContext();
2854
2855 if (context)
2856 {
2857 context->readPixels(x, y, width, height, format, type, pixels);
2858 }
2859 }
2860 catch(std::bad_alloc&)
2861 {
2862 return error(GL_OUT_OF_MEMORY);
2863 }
2864}
2865
2866void __stdcall glReleaseShaderCompiler(void)
2867{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002868 TRACE("()");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002869
2870 try
2871 {
2872 gl::Shader::releaseCompiler();
2873 }
2874 catch(std::bad_alloc&)
2875 {
2876 return error(GL_OUT_OF_MEMORY);
2877 }
2878}
2879
2880void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
2881{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002882 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
2883 target, internalformat, width, height);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002884
2885 try
2886 {
2887 switch (target)
2888 {
2889 case GL_RENDERBUFFER:
2890 break;
2891 default:
2892 return error(GL_INVALID_ENUM);
2893 }
2894
2895 switch (internalformat)
2896 {
2897 case GL_DEPTH_COMPONENT16:
2898 case GL_RGBA4:
2899 case GL_RGB5_A1:
2900 case GL_RGB565:
2901 case GL_STENCIL_INDEX8:
2902 break;
2903 default:
2904 return error(GL_INVALID_ENUM);
2905 }
2906
2907 if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
2908 {
2909 return error(GL_INVALID_VALUE);
2910 }
2911
2912 gl::Context *context = gl::getContext();
2913
2914 if (context)
2915 {
2916 if (context->framebuffer == 0 || context->renderbuffer == 0)
2917 {
2918 return error(GL_INVALID_OPERATION);
2919 }
2920
2921 switch (internalformat)
2922 {
2923 case GL_DEPTH_COMPONENT16:
2924 context->setRenderbuffer(new gl::Depthbuffer(width, height));
2925 break;
2926 case GL_RGBA4:
2927 case GL_RGB5_A1:
2928 case GL_RGB565:
2929 UNIMPLEMENTED(); // FIXME
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00002930 // context->setRenderbuffer(new Colorbuffer(renderTarget));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002931 break;
2932 case GL_STENCIL_INDEX8:
daniel@transgaming.com4a9d65c2010-03-08 21:30:56 +00002933 context->setRenderbuffer(new gl::Stencilbuffer(width, height));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002934 break;
2935 default:
2936 return error(GL_INVALID_ENUM);
2937 }
2938 }
2939 }
2940 catch(std::bad_alloc&)
2941 {
2942 return error(GL_OUT_OF_MEMORY);
2943 }
2944}
2945
2946void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
2947{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002948 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002949
2950 try
2951 {
2952 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002953
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002954 if (context)
2955 {
2956 context->sampleCoverageValue = gl::clamp01(value);
2957 context->sampleCoverageInvert = invert;
2958 }
2959 }
2960 catch(std::bad_alloc&)
2961 {
2962 return error(GL_OUT_OF_MEMORY);
2963 }
2964}
2965
2966void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
2967{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002968 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 +00002969
2970 try
2971 {
2972 if (width < 0 || height < 0)
2973 {
2974 return error(GL_INVALID_VALUE);
2975 }
2976
2977 gl::Context* context = gl::getContext();
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00002978
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002979 if (context)
2980 {
2981 context->scissorX = x;
2982 context->scissorY = y;
2983 context->scissorWidth = width;
2984 context->scissorHeight = height;
2985 }
2986 }
2987 catch(std::bad_alloc&)
2988 {
2989 return error(GL_OUT_OF_MEMORY);
2990 }
2991}
2992
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002993void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002994{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002995 TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00002996 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00002997 n, shaders, binaryformat, binary, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00002998
2999 try
3000 {
3001 if (n < 0 || length < 0)
3002 {
3003 return error(GL_INVALID_VALUE);
3004 }
3005
3006 UNIMPLEMENTED(); // FIXME
3007 }
3008 catch(std::bad_alloc&)
3009 {
3010 return error(GL_OUT_OF_MEMORY);
3011 }
3012}
3013
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003014void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003015{
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003016 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 +00003017 shader, count, string, length);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003018
3019 try
3020 {
daniel@transgaming.com57a0bab2010-04-03 20:56:10 +00003021 if (shader == 0 || count < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003022 {
3023 return error(GL_INVALID_VALUE);
3024 }
3025
3026 gl::Context *context = gl::getContext();
3027
3028 if (context)
3029 {
3030 gl::Shader *shaderObject = context->getShader(shader);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003031
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003032 if (!shaderObject)
3033 {
daniel@transgaming.com41187f12010-04-01 13:39:29 +00003034 return error(GL_INVALID_OPERATION);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003035 }
3036
3037 shaderObject->setSource(count, string, length);
3038 }
3039 }
3040 catch(std::bad_alloc&)
3041 {
3042 return error(GL_OUT_OF_MEMORY);
3043 }
3044}
3045
3046void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
3047{
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003048 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003049}
3050
3051void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
3052{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003053 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 +00003054
3055 try
3056 {
3057 switch (face)
3058 {
3059 case GL_FRONT:
3060 case GL_BACK:
3061 case GL_FRONT_AND_BACK:
3062 break;
3063 default:
3064 return error(GL_INVALID_ENUM);
3065 }
3066
3067 switch (func)
3068 {
3069 case GL_NEVER:
3070 case GL_ALWAYS:
3071 case GL_LESS:
3072 case GL_LEQUAL:
3073 case GL_EQUAL:
3074 case GL_GEQUAL:
3075 case GL_GREATER:
3076 case GL_NOTEQUAL:
3077 break;
3078 default:
3079 return error(GL_INVALID_ENUM);
3080 }
3081
3082 gl::Context *context = gl::getContext();
3083
3084 if (context)
3085 {
3086 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3087 {
3088 context->stencilFunc = func;
3089 context->stencilRef = ref;
3090 context->stencilMask = mask;
3091 }
3092
3093 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3094 {
3095 context->stencilBackFunc = func;
3096 context->stencilBackRef = ref;
3097 context->stencilBackMask = mask;
3098 }
3099 }
3100 }
3101 catch(std::bad_alloc&)
3102 {
3103 return error(GL_OUT_OF_MEMORY);
3104 }
3105}
3106
3107void __stdcall glStencilMask(GLuint mask)
3108{
3109 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
3110}
3111
3112void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
3113{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003114 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003115
3116 try
3117 {
3118 switch (face)
3119 {
3120 case GL_FRONT:
3121 case GL_BACK:
3122 case GL_FRONT_AND_BACK:
3123 break;
3124 default:
3125 return error(GL_INVALID_ENUM);
3126 }
3127
3128 gl::Context *context = gl::getContext();
3129
3130 if (context)
3131 {
3132 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3133 {
3134 context->stencilWritemask = mask;
3135 }
3136
3137 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3138 {
3139 context->stencilBackWritemask = mask;
3140 }
3141 }
3142 }
3143 catch(std::bad_alloc&)
3144 {
3145 return error(GL_OUT_OF_MEMORY);
3146 }
3147}
3148
3149void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3150{
3151 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
3152}
3153
3154void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
3155{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003156 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
3157 face, fail, zfail, zpass);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003158
3159 try
3160 {
3161 switch (face)
3162 {
3163 case GL_FRONT:
3164 case GL_BACK:
3165 case GL_FRONT_AND_BACK:
3166 break;
3167 default:
3168 return error(GL_INVALID_ENUM);
3169 }
3170
3171 switch (fail)
3172 {
3173 case GL_ZERO:
3174 case GL_KEEP:
3175 case GL_REPLACE:
3176 case GL_INCR:
3177 case GL_DECR:
3178 case GL_INVERT:
3179 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003180 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003181 break;
3182 default:
3183 return error(GL_INVALID_ENUM);
3184 }
3185
3186 switch (zfail)
3187 {
3188 case GL_ZERO:
3189 case GL_KEEP:
3190 case GL_REPLACE:
3191 case GL_INCR:
3192 case GL_DECR:
3193 case GL_INVERT:
3194 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003195 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003196 break;
3197 default:
3198 return error(GL_INVALID_ENUM);
3199 }
3200
3201 switch (zpass)
3202 {
3203 case GL_ZERO:
3204 case GL_KEEP:
3205 case GL_REPLACE:
3206 case GL_INCR:
3207 case GL_DECR:
3208 case GL_INVERT:
3209 case GL_INCR_WRAP:
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003210 case GL_DECR_WRAP:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003211 break;
3212 default:
3213 return error(GL_INVALID_ENUM);
3214 }
3215
3216 gl::Context *context = gl::getContext();
3217
3218 if (context)
3219 {
3220 if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
3221 {
3222 context->stencilFail = fail;
3223 context->stencilPassDepthFail = zfail;
3224 context->stencilPassDepthPass = zpass;
3225 }
3226
3227 if (face == GL_BACK || face == GL_FRONT_AND_BACK)
3228 {
3229 context->stencilBackFail = fail;
3230 context->stencilBackPassDepthFail = zfail;
3231 context->stencilBackPassDepthPass = zpass;
3232 }
3233 }
3234 }
3235 catch(std::bad_alloc&)
3236 {
3237 return error(GL_OUT_OF_MEMORY);
3238 }
3239}
3240
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003241void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
3242 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003243{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003244 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 +00003245 "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 +00003246 target, level, internalformat, width, height, border, format, type, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003247
3248 try
3249 {
3250 if (level < 0 || width < 0 || height < 0)
3251 {
3252 return error(GL_INVALID_VALUE);
3253 }
3254
3255 if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
3256 {
3257 return error(GL_INVALID_VALUE);
3258 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +00003259
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003260 switch (target)
3261 {
3262 case GL_TEXTURE_2D:
3263 if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
3264 {
3265 return error(GL_INVALID_VALUE);
3266 }
3267 break;
3268 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
3269 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
3270 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
3271 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
3272 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
3273 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
3274 if (!gl::isPow2(width) || !gl::isPow2(height))
3275 {
3276 return error(GL_INVALID_VALUE);
3277 }
3278
3279 if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
3280 {
3281 return error(GL_INVALID_VALUE);
3282 }
3283 break;
3284 default:
3285 return error(GL_INVALID_ENUM);
3286 }
3287
3288 if (internalformat != format)
3289 {
3290 return error(GL_INVALID_OPERATION);
3291 }
3292
3293 switch (internalformat)
3294 {
3295 case GL_ALPHA:
3296 case GL_LUMINANCE:
3297 case GL_LUMINANCE_ALPHA:
3298 switch (type)
3299 {
3300 case GL_UNSIGNED_BYTE:
3301 break;
3302 default:
3303 return error(GL_INVALID_ENUM);
3304 }
3305 break;
3306 case GL_RGB:
3307 switch (type)
3308 {
3309 case GL_UNSIGNED_BYTE:
3310 case GL_UNSIGNED_SHORT_5_6_5:
3311 break;
3312 default:
3313 return error(GL_INVALID_ENUM);
3314 }
3315 break;
3316 case GL_RGBA:
3317 switch (type)
3318 {
3319 case GL_UNSIGNED_BYTE:
3320 case GL_UNSIGNED_SHORT_4_4_4_4:
3321 case GL_UNSIGNED_SHORT_5_5_5_1:
3322 break;
3323 default:
3324 return error(GL_INVALID_ENUM);
3325 }
3326 break;
3327 default:
3328 return error(GL_INVALID_VALUE);
3329 }
3330
3331 if (border != 0)
3332 {
3333 return error(GL_INVALID_VALUE);
3334 }
3335
3336 gl::Context *context = gl::getContext();
3337
3338 if (context)
3339 {
3340 if (target == GL_TEXTURE_2D)
3341 {
3342 gl::Texture2D *texture = context->getTexture2D();
3343
3344 if (!texture)
3345 {
3346 return error(GL_INVALID_OPERATION);
3347 }
3348
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003349 texture->setImage(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003350 }
3351 else
3352 {
3353 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3354
3355 if (!texture)
3356 {
3357 return error(GL_INVALID_OPERATION);
3358 }
3359
3360 switch (target)
3361 {
3362 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003363 texture->setImagePosX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003364 break;
3365 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003366 texture->setImageNegX(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003367 break;
3368 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003369 texture->setImagePosY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003370 break;
3371 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003372 texture->setImageNegY(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003373 break;
3374 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003375 texture->setImagePosZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003376 break;
3377 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003378 texture->setImageNegZ(level, internalformat, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003379 break;
3380 default: UNREACHABLE();
3381 }
3382 }
3383 }
3384 }
3385 catch(std::bad_alloc&)
3386 {
3387 return error(GL_OUT_OF_MEMORY);
3388 }
3389}
3390
3391void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
3392{
3393 glTexParameteri(target, pname, (GLint)param);
3394}
3395
3396void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
3397{
3398 glTexParameteri(target, pname, (GLint)*params);
3399}
3400
3401void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
3402{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003403 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003404
3405 try
3406 {
3407 gl::Context *context = gl::getContext();
3408
3409 if (context)
3410 {
3411 gl::Texture *texture;
3412
3413 switch (target)
3414 {
3415 case GL_TEXTURE_2D:
3416 texture = context->getTexture2D();
3417 break;
3418 case GL_TEXTURE_CUBE_MAP:
3419 texture = context->getTextureCubeMap();
3420 break;
3421 default:
3422 return error(GL_INVALID_ENUM);
3423 }
3424
3425 switch (pname)
3426 {
3427 case GL_TEXTURE_WRAP_S:
3428 if (!texture->setWrapS((GLenum)param))
3429 {
3430 return error(GL_INVALID_ENUM);
3431 }
3432 break;
3433 case GL_TEXTURE_WRAP_T:
3434 if (!texture->setWrapT((GLenum)param))
3435 {
3436 return error(GL_INVALID_ENUM);
3437 }
3438 break;
3439 case GL_TEXTURE_MIN_FILTER:
3440 if (!texture->setMinFilter((GLenum)param))
3441 {
3442 return error(GL_INVALID_ENUM);
3443 }
3444 break;
3445 case GL_TEXTURE_MAG_FILTER:
3446 if (!texture->setMagFilter((GLenum)param))
3447 {
3448 return error(GL_INVALID_ENUM);
3449 }
3450 break;
3451 default:
3452 return error(GL_INVALID_ENUM);
3453 }
3454 }
3455 }
3456 catch(std::bad_alloc&)
3457 {
3458 return error(GL_OUT_OF_MEMORY);
3459 }
3460}
3461
3462void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
3463{
3464 glTexParameteri(target, pname, *params);
3465}
3466
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003467void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
3468 GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003469{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003470 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
3471 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00003472 "const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003473 target, level, xoffset, yoffset, width, height, format, type, pixels);
3474
3475 try
3476 {
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003477 if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
3478 {
3479 return error(GL_INVALID_ENUM);
3480 }
3481
3482 if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003483 {
3484 return error(GL_INVALID_VALUE);
3485 }
3486
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003487 if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
3488 {
3489 return error(GL_INVALID_VALUE);
3490 }
3491
3492 if (!es2dx::CheckTextureFormatType(format, type))
3493 {
3494 return error(GL_INVALID_ENUM);
3495 }
3496
3497 if (width == 0 || height == 0 || pixels == NULL)
3498 {
3499 return;
3500 }
3501
3502 gl::Context *context = gl::getContext();
3503
3504 if (context)
3505 {
3506 if (target == GL_TEXTURE_2D)
3507 {
3508 gl::Texture2D *texture = context->getTexture2D();
3509
3510 if (!texture)
3511 {
3512 return error(GL_INVALID_OPERATION);
3513 }
3514
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003515 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003516 }
3517 else if (es2dx::IsCubemapTextureTarget(target))
3518 {
3519 gl::TextureCubeMap *texture = context->getTextureCubeMap();
3520
3521 if (!texture)
3522 {
3523 return error(GL_INVALID_OPERATION);
3524 }
3525
daniel@transgaming.com3489e3a2010-03-21 04:31:11 +00003526 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->unpackAlignment, pixels);
daniel@transgaming.com00c75962010-03-11 20:36:15 +00003527 }
3528 else
3529 {
3530 UNREACHABLE();
3531 }
3532 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003533 }
3534 catch(std::bad_alloc&)
3535 {
3536 return error(GL_OUT_OF_MEMORY);
3537 }
3538}
3539
3540void __stdcall glUniform1f(GLint location, GLfloat x)
3541{
3542 glUniform1fv(location, 1, &x);
3543}
3544
3545void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
3546{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003547 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003548
3549 try
3550 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003551 if (count < 0)
3552 {
3553 return error(GL_INVALID_VALUE);
3554 }
3555
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003556 if (location == -1)
3557 {
3558 return;
3559 }
3560
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003561 gl::Context *context = gl::getContext();
3562
3563 if (context)
3564 {
3565 gl::Program *program = context->getCurrentProgram();
3566
3567 if (!program)
3568 {
3569 return error(GL_INVALID_OPERATION);
3570 }
3571
3572 if (!program->setUniform1fv(location, count, v))
3573 {
3574 return error(GL_INVALID_OPERATION);
3575 }
3576 }
3577 }
3578 catch(std::bad_alloc&)
3579 {
3580 return error(GL_OUT_OF_MEMORY);
3581 }
3582}
3583
3584void __stdcall glUniform1i(GLint location, GLint x)
3585{
3586 glUniform1iv(location, 1, &x);
3587}
3588
3589void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
3590{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003591 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003592
3593 try
3594 {
3595 if (count < 0)
3596 {
3597 return error(GL_INVALID_VALUE);
3598 }
3599
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003600 if (location == -1)
3601 {
3602 return;
3603 }
3604
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003605 gl::Context *context = gl::getContext();
3606
3607 if (context)
3608 {
3609 gl::Program *program = context->getCurrentProgram();
3610
3611 if (!program)
3612 {
3613 return error(GL_INVALID_OPERATION);
3614 }
3615
3616 if (!program->setUniform1iv(location, count, v))
3617 {
3618 return error(GL_INVALID_OPERATION);
3619 }
3620 }
3621 }
3622 catch(std::bad_alloc&)
3623 {
3624 return error(GL_OUT_OF_MEMORY);
3625 }
3626}
3627
3628void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
3629{
3630 GLfloat xy[2] = {x, y};
3631
3632 glUniform2fv(location, 1, (GLfloat*)&xy);
3633}
3634
3635void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
3636{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003637 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003638
3639 try
3640 {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003641 if (count < 0)
3642 {
3643 return error(GL_INVALID_VALUE);
3644 }
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003645
3646 if (location == -1)
3647 {
3648 return;
3649 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003650
3651 gl::Context *context = gl::getContext();
3652
3653 if (context)
3654 {
3655 gl::Program *program = context->getCurrentProgram();
3656
3657 if (!program)
3658 {
3659 return error(GL_INVALID_OPERATION);
3660 }
3661
3662 if (!program->setUniform2fv(location, count, v))
3663 {
3664 return error(GL_INVALID_OPERATION);
3665 }
3666 }
3667 }
3668 catch(std::bad_alloc&)
3669 {
3670 return error(GL_OUT_OF_MEMORY);
3671 }
3672}
3673
3674void __stdcall glUniform2i(GLint location, GLint x, GLint y)
3675{
3676 GLint xy[4] = {x, y};
3677
3678 glUniform2iv(location, 1, (GLint*)&xy);
3679}
3680
3681void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
3682{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003683 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003684
3685 try
3686 {
3687 if (count < 0)
3688 {
3689 return error(GL_INVALID_VALUE);
3690 }
3691
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003692 if (location == -1)
3693 {
3694 return;
3695 }
3696
3697 gl::Context *context = gl::getContext();
3698
3699 if (context)
3700 {
3701 gl::Program *program = context->getCurrentProgram();
3702
3703 if (!program)
3704 {
3705 return error(GL_INVALID_OPERATION);
3706 }
3707
3708 if (!program->setUniform2iv(location, count, v))
3709 {
3710 return error(GL_INVALID_OPERATION);
3711 }
3712 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003713 }
3714 catch(std::bad_alloc&)
3715 {
3716 return error(GL_OUT_OF_MEMORY);
3717 }
3718}
3719
3720void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
3721{
3722 GLfloat xyz[3] = {x, y, z};
3723
3724 glUniform3fv(location, 1, (GLfloat*)&xyz);
3725}
3726
3727void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
3728{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003729 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003730
3731 try
3732 {
3733 if (count < 0)
3734 {
3735 return error(GL_INVALID_VALUE);
3736 }
3737
3738 if (location == -1)
3739 {
3740 return;
3741 }
3742
3743 gl::Context *context = gl::getContext();
3744
3745 if (context)
3746 {
3747 gl::Program *program = context->getCurrentProgram();
3748
3749 if (!program)
3750 {
3751 return error(GL_INVALID_OPERATION);
3752 }
3753
3754 if (!program->setUniform3fv(location, count, v))
3755 {
3756 return error(GL_INVALID_OPERATION);
3757 }
3758 }
3759 }
3760 catch(std::bad_alloc&)
3761 {
3762 return error(GL_OUT_OF_MEMORY);
3763 }
3764}
3765
3766void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
3767{
3768 GLint xyz[3] = {x, y, z};
3769
3770 glUniform3iv(location, 1, (GLint*)&xyz);
3771}
3772
3773void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
3774{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003775 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003776
3777 try
3778 {
3779 if (count < 0)
3780 {
3781 return error(GL_INVALID_VALUE);
3782 }
3783
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003784 if (location == -1)
3785 {
3786 return;
3787 }
3788
3789 gl::Context *context = gl::getContext();
3790
3791 if (context)
3792 {
3793 gl::Program *program = context->getCurrentProgram();
3794
3795 if (!program)
3796 {
3797 return error(GL_INVALID_OPERATION);
3798 }
3799
3800 if (!program->setUniform3iv(location, count, v))
3801 {
3802 return error(GL_INVALID_OPERATION);
3803 }
3804 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003805 }
3806 catch(std::bad_alloc&)
3807 {
3808 return error(GL_OUT_OF_MEMORY);
3809 }
3810}
3811
3812void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
3813{
3814 GLfloat xyzw[4] = {x, y, z, w};
3815
3816 glUniform4fv(location, 1, (GLfloat*)&xyzw);
3817}
3818
3819void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
3820{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003821 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003822
3823 try
3824 {
3825 if (count < 0)
3826 {
3827 return error(GL_INVALID_VALUE);
3828 }
3829
3830 if (location == -1)
3831 {
3832 return;
3833 }
3834
3835 gl::Context *context = gl::getContext();
3836
3837 if (context)
3838 {
3839 gl::Program *program = context->getCurrentProgram();
3840
3841 if (!program)
3842 {
3843 return error(GL_INVALID_OPERATION);
3844 }
3845
3846 if (!program->setUniform4fv(location, count, v))
3847 {
3848 return error(GL_INVALID_OPERATION);
3849 }
3850 }
3851 }
3852 catch(std::bad_alloc&)
3853 {
3854 return error(GL_OUT_OF_MEMORY);
3855 }
3856}
3857
3858void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
3859{
3860 GLint xyzw[4] = {x, y, z, w};
3861
3862 glUniform4iv(location, 1, (GLint*)&xyzw);
3863}
3864
3865void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
3866{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003867 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003868
3869 try
3870 {
3871 if (count < 0)
3872 {
3873 return error(GL_INVALID_VALUE);
3874 }
3875
daniel@transgaming.com9a95e2b2010-04-13 03:26:03 +00003876 if (location == -1)
3877 {
3878 return;
3879 }
3880
3881 gl::Context *context = gl::getContext();
3882
3883 if (context)
3884 {
3885 gl::Program *program = context->getCurrentProgram();
3886
3887 if (!program)
3888 {
3889 return error(GL_INVALID_OPERATION);
3890 }
3891
3892 if (!program->setUniform4iv(location, count, v))
3893 {
3894 return error(GL_INVALID_OPERATION);
3895 }
3896 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003897 }
3898 catch(std::bad_alloc&)
3899 {
3900 return error(GL_OUT_OF_MEMORY);
3901 }
3902}
3903
3904void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
3905{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003906 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
3907 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003908
3909 try
3910 {
3911 if (count < 0 || transpose != GL_FALSE)
3912 {
3913 return error(GL_INVALID_VALUE);
3914 }
3915
3916 if (location == -1)
3917 {
3918 return;
3919 }
3920
3921 gl::Context *context = gl::getContext();
3922
3923 if (context)
3924 {
3925 gl::Program *program = context->getCurrentProgram();
3926
3927 if (!program)
3928 {
3929 return error(GL_INVALID_OPERATION);
3930 }
3931
3932 if (!program->setUniformMatrix2fv(location, count, value))
3933 {
3934 return error(GL_INVALID_OPERATION);
3935 }
3936 }
3937 }
3938 catch(std::bad_alloc&)
3939 {
3940 return error(GL_OUT_OF_MEMORY);
3941 }
3942}
3943
3944void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
3945{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003946 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
3947 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003948
3949 try
3950 {
3951 if (count < 0 || transpose != GL_FALSE)
3952 {
3953 return error(GL_INVALID_VALUE);
3954 }
3955
3956 if (location == -1)
3957 {
3958 return;
3959 }
3960
3961 gl::Context *context = gl::getContext();
3962
3963 if (context)
3964 {
3965 gl::Program *program = context->getCurrentProgram();
3966
3967 if (!program)
3968 {
3969 return error(GL_INVALID_OPERATION);
3970 }
3971
3972 if (!program->setUniformMatrix3fv(location, count, value))
3973 {
3974 return error(GL_INVALID_OPERATION);
3975 }
3976 }
3977 }
3978 catch(std::bad_alloc&)
3979 {
3980 return error(GL_OUT_OF_MEMORY);
3981 }
3982}
3983
3984void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
3985{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00003986 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
3987 location, count, transpose, value);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003988
3989 try
3990 {
3991 if (count < 0 || transpose != GL_FALSE)
3992 {
3993 return error(GL_INVALID_VALUE);
3994 }
3995
3996 if (location == -1)
3997 {
3998 return;
3999 }
4000
4001 gl::Context *context = gl::getContext();
4002
4003 if (context)
4004 {
4005 gl::Program *program = context->getCurrentProgram();
4006
4007 if (!program)
4008 {
4009 return error(GL_INVALID_OPERATION);
4010 }
4011
4012 if (!program->setUniformMatrix4fv(location, count, value))
4013 {
4014 return error(GL_INVALID_OPERATION);
4015 }
4016 }
4017 }
4018 catch(std::bad_alloc&)
4019 {
4020 return error(GL_OUT_OF_MEMORY);
4021 }
4022}
4023
4024void __stdcall glUseProgram(GLuint program)
4025{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004026 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004027
4028 try
4029 {
4030 gl::Context *context = gl::getContext();
4031
4032 if (context)
4033 {
4034 gl::Program *programObject = context->getProgram(program);
4035
4036 if (programObject && !programObject->isLinked())
4037 {
4038 return error(GL_INVALID_OPERATION);
4039 }
4040
4041 context->useProgram(program);
4042 }
4043 }
4044 catch(std::bad_alloc&)
4045 {
4046 return error(GL_OUT_OF_MEMORY);
4047 }
4048}
4049
4050void __stdcall glValidateProgram(GLuint program)
4051{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004052 TRACE("(GLuint program = %d)", program);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004053
4054 try
4055 {
4056 UNIMPLEMENTED(); // FIXME
4057 }
4058 catch(std::bad_alloc&)
4059 {
4060 return error(GL_OUT_OF_MEMORY);
4061 }
4062}
4063
4064void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
4065{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004066 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004067
4068 try
4069 {
4070 if (index >= gl::MAX_VERTEX_ATTRIBS)
4071 {
4072 return error(GL_INVALID_VALUE);
4073 }
4074
4075 UNIMPLEMENTED(); // FIXME
4076 }
4077 catch(std::bad_alloc&)
4078 {
4079 return error(GL_OUT_OF_MEMORY);
4080 }
4081}
4082
4083void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
4084{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004085 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004086
4087 try
4088 {
4089 if (index >= gl::MAX_VERTEX_ATTRIBS)
4090 {
4091 return error(GL_INVALID_VALUE);
4092 }
4093
4094 UNIMPLEMENTED(); // FIXME
4095 }
4096 catch(std::bad_alloc&)
4097 {
4098 return error(GL_OUT_OF_MEMORY);
4099 }
4100}
4101
4102void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
4103{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004104 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004105
4106 try
4107 {
4108 if (index >= gl::MAX_VERTEX_ATTRIBS)
4109 {
4110 return error(GL_INVALID_VALUE);
4111 }
4112
4113 UNIMPLEMENTED(); // FIXME
4114 }
4115 catch(std::bad_alloc&)
4116 {
4117 return error(GL_OUT_OF_MEMORY);
4118 }
4119}
4120
4121void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
4122{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004123 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004124
4125 try
4126 {
4127 if (index >= gl::MAX_VERTEX_ATTRIBS)
4128 {
4129 return error(GL_INVALID_VALUE);
4130 }
4131
4132 UNIMPLEMENTED(); // FIXME
4133 }
4134 catch(std::bad_alloc&)
4135 {
4136 return error(GL_OUT_OF_MEMORY);
4137 }
4138}
4139
4140void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
4141{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004142 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 +00004143
4144 try
4145 {
4146 if (index >= gl::MAX_VERTEX_ATTRIBS)
4147 {
4148 return error(GL_INVALID_VALUE);
4149 }
4150
4151 UNIMPLEMENTED(); // FIXME
4152 }
4153 catch(std::bad_alloc&)
4154 {
4155 return error(GL_OUT_OF_MEMORY);
4156 }
4157}
4158
4159void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
4160{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004161 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004162
4163 try
4164 {
4165 if (index >= gl::MAX_VERTEX_ATTRIBS)
4166 {
4167 return error(GL_INVALID_VALUE);
4168 }
4169
4170 UNIMPLEMENTED(); // FIXME
4171 }
4172 catch(std::bad_alloc&)
4173 {
4174 return error(GL_OUT_OF_MEMORY);
4175 }
4176}
4177
4178void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
4179{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004180 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 +00004181
4182 try
4183 {
4184 if (index >= gl::MAX_VERTEX_ATTRIBS)
4185 {
4186 return error(GL_INVALID_VALUE);
4187 }
4188
4189 UNIMPLEMENTED(); // FIXME
4190 }
4191 catch(std::bad_alloc&)
4192 {
4193 return error(GL_OUT_OF_MEMORY);
4194 }
4195}
4196
4197void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
4198{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004199 TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004200
4201 try
4202 {
4203 if (index >= gl::MAX_VERTEX_ATTRIBS)
4204 {
4205 return error(GL_INVALID_VALUE);
4206 }
4207
4208 UNIMPLEMENTED(); // FIXME
4209 }
4210 catch(std::bad_alloc&)
4211 {
4212 return error(GL_OUT_OF_MEMORY);
4213 }
4214}
4215
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004216void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004217{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004218 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004219 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004220 index, size, type, normalized, stride, ptr);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004221
4222 try
4223 {
4224 if (index >= gl::MAX_VERTEX_ATTRIBS)
4225 {
4226 return error(GL_INVALID_VALUE);
4227 }
4228
4229 if (size < 1 || size > 4)
4230 {
4231 return error(GL_INVALID_VALUE);
4232 }
4233
4234 switch (type)
4235 {
4236 case GL_BYTE:
4237 case GL_UNSIGNED_BYTE:
4238 case GL_SHORT:
4239 case GL_UNSIGNED_SHORT:
4240 case GL_FIXED:
4241 case GL_FLOAT:
4242 break;
4243 default:
4244 return error(GL_INVALID_ENUM);
4245 }
4246
4247 if (stride < 0)
4248 {
4249 return error(GL_INVALID_VALUE);
4250 }
4251
4252 gl::Context *context = gl::getContext();
4253
4254 if (context)
4255 {
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004256 context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
4257 context->vertexAttribute[index].mSize = size;
4258 context->vertexAttribute[index].mType = type;
daniel@transgaming.comb994e3b2010-03-26 04:08:50 +00004259 context->vertexAttribute[index].mNormalized = (normalized == GL_TRUE);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00004260 context->vertexAttribute[index].mStride = stride;
4261 context->vertexAttribute[index].mPointer = ptr;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004262 }
4263 }
4264 catch(std::bad_alloc&)
4265 {
4266 return error(GL_OUT_OF_MEMORY);
4267 }
4268}
4269
4270void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
4271{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004272 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 +00004273
4274 try
4275 {
4276 if (width < 0 || height < 0)
4277 {
4278 return error(GL_INVALID_VALUE);
4279 }
4280
4281 gl::Context *context = gl::getContext();
4282
4283 if (context)
4284 {
4285 context->viewportX = x;
4286 context->viewportY = y;
4287 context->viewportWidth = width;
4288 context->viewportHeight = height;
4289 }
4290 }
4291 catch(std::bad_alloc&)
4292 {
4293 return error(GL_OUT_OF_MEMORY);
4294 }
4295}
4296
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004297void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
4298 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004299{
daniel@transgaming.comb5b06162010-03-21 04:31:32 +00004300 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
4301 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
daniel@transgaming.comfe4b8272010-04-08 03:51:20 +00004302 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00004303 target, level, internalformat, width, height, depth, border, format, type, pixels);
4304
4305 try
4306 {
4307 UNIMPLEMENTED(); // FIXME
4308 }
4309 catch(std::bad_alloc&)
4310 {
4311 return error(GL_OUT_OF_MEMORY);
4312 }
4313}
4314}