// SwiftShader Software Renderer
//
// Copyright(c) 2005-2013 TransGaming Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//
// libGL.cpp: Implements the exported OpenGL functions.

#include "main.h"
#include "mathutil.h"
#include "utilities.h"
#include "Buffer.h"
#include "Context.h"
#include "Fence.h"
#include "Framebuffer.h"
#include "Program.h"
#include "Renderbuffer.h"
#include "Shader.h"
#include "Texture.h"
#include "Query.h"
#include "common/debug.h"
#include "Common/Version.h"
#include "Main/Register.hpp"

#define _GDI32_
#include <windows.h>
#include <GL/GL.h>
#include <GL/glext.h>

#include <limits>

static bool validImageSize(GLint level, GLsizei width, GLsizei height)
{
	if(level < 0 || level >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
	{
		return false;
	}

	return true;
}

static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, gl::Texture *texture)
{
	if(!texture)
	{
		return error(GL_INVALID_OPERATION, false);
	}

	if(compressed != texture->isCompressed(target, level))
	{
		return error(GL_INVALID_OPERATION, false);
	}

	if(format != GL_NONE && format != texture->getFormat(target, level))
	{
		return error(GL_INVALID_OPERATION, false);
	}

	if(compressed)
	{
		if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
		   (height % 4 != 0 && height != texture->getHeight(target, 0)))
		{
			return error(GL_INVALID_OPERATION, false);
		}
	}

	if(xoffset + width > texture->getWidth(target, level) ||
	   yoffset + height > texture->getHeight(target, level))
	{
		return error(GL_INVALID_VALUE, false);
	}

	return true;
}

// Check for combinations of format and type that are valid for ReadPixels
static bool validReadFormatType(GLenum format, GLenum type)
{
	switch(format)
	{
	case GL_RGBA:
		switch(type)
		{
		case GL_UNSIGNED_BYTE:
			break;
		default:
			return false;
		}
		break;
	case GL_BGRA_EXT:
		switch(type)
		{
		case GL_UNSIGNED_BYTE:
		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
			break;
		default:
			return false;
		}
		break;
	case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
		switch(type)
		{
		case gl::IMPLEMENTATION_COLOR_READ_TYPE:
			break;
		default:
			return false;
		}
		break;
	default:
		return false;
	}

	return true;
}

extern "C"
{

void APIENTRY glActiveTexture(GLenum texture)
{
	TRACE("(GLenum texture = 0x%X)", texture);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
		{
			return error(GL_INVALID_ENUM);
		}

		context->setActiveSampler(texture - GL_TEXTURE0);
	}
}

void APIENTRY glAttachShader(GLuint program, GLuint shader)
{
	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);
		gl::Shader *shaderObject = context->getShader(shader);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(!shaderObject)
		{
			if(context->getProgram(shader))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(!programObject->attachShader(shaderObject))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glBeginQueryEXT(GLenum target, GLuint name)
{
	TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);

	switch(target)
	{
	case GL_ANY_SAMPLES_PASSED:
	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(name == 0)
	{
		return error(GL_INVALID_OPERATION);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->beginQuery(target, name);
	}
}

void APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
{
	TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(strncmp(name, "gl_", 3) == 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		programObject->bindAttributeLocation(index, name);
	}
}

void APIENTRY glBindBuffer(GLenum target, GLuint buffer)
{
	TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);

	gl::Context *context = gl::getContext();

	if(context)
	{
		switch(target)
		{
		case GL_ARRAY_BUFFER:
			context->bindArrayBuffer(buffer);
			return;
		case GL_ELEMENT_ARRAY_BUFFER:
			context->bindElementArrayBuffer(buffer);
			return;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
{
	TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);

	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
	{
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(target == GL_READ_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
		{
			context->bindReadFramebuffer(framebuffer);
		}
			
		if(target == GL_DRAW_FRAMEBUFFER_EXT || target == GL_FRAMEBUFFER)
		{
			context->bindDrawFramebuffer(framebuffer);
		}
	}
}

void APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
{
	TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);

	if(target != GL_RENDERBUFFER)
	{
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->bindRenderbuffer(renderbuffer);
	}
}

void APIENTRY glBindTexture(GLenum target, GLuint texture)
{
	TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Texture *textureObject = context->getTexture(texture);

		if(textureObject && textureObject->getTarget() != target && texture != 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(target)
		{
		case GL_TEXTURE_2D:
			context->bindTexture2D(texture);
			return;
		case GL_TEXTURE_CUBE_MAP:
			context->bindTextureCubeMap(texture);
			return;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
		  red, green, blue, alpha);

	gl::Context* context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
	}
}

void APIENTRY glBlendEquation(GLenum mode)
{
	glBlendEquationSeparate(mode, mode);
}

void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
{
	TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);

	switch(modeRGB)
	{
	case GL_FUNC_ADD:
	case GL_FUNC_SUBTRACT:
	case GL_FUNC_REVERSE_SUBTRACT:
	case GL_MIN_EXT:
	case GL_MAX_EXT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(modeAlpha)
	{
	case GL_FUNC_ADD:
	case GL_FUNC_SUBTRACT:
	case GL_FUNC_REVERSE_SUBTRACT:
	case GL_MIN_EXT:
	case GL_MAX_EXT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setBlendEquation(modeRGB, modeAlpha);
	}
}

void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
{
	glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
}

void APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
	TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
	      srcRGB, dstRGB, srcAlpha, dstAlpha);

	switch(srcRGB)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
	case GL_CONSTANT_COLOR:
	case GL_ONE_MINUS_CONSTANT_COLOR:
	case GL_CONSTANT_ALPHA:
	case GL_ONE_MINUS_CONSTANT_ALPHA:
	case GL_SRC_ALPHA_SATURATE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(dstRGB)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
	case GL_CONSTANT_COLOR:
	case GL_ONE_MINUS_CONSTANT_COLOR:
	case GL_CONSTANT_ALPHA:
	case GL_ONE_MINUS_CONSTANT_ALPHA:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(srcAlpha)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
	case GL_CONSTANT_COLOR:
	case GL_ONE_MINUS_CONSTANT_COLOR:
	case GL_CONSTANT_ALPHA:
	case GL_ONE_MINUS_CONSTANT_ALPHA:
	case GL_SRC_ALPHA_SATURATE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(dstAlpha)
	{
	case GL_ZERO:
	case GL_ONE:
	case GL_SRC_COLOR:
	case GL_ONE_MINUS_SRC_COLOR:
	case GL_DST_COLOR:
	case GL_ONE_MINUS_DST_COLOR:
	case GL_SRC_ALPHA:
	case GL_ONE_MINUS_SRC_ALPHA:
	case GL_DST_ALPHA:
	case GL_ONE_MINUS_DST_ALPHA:
	case GL_CONSTANT_COLOR:
	case GL_ONE_MINUS_CONSTANT_COLOR:
	case GL_CONSTANT_ALPHA:
	case GL_ONE_MINUS_CONSTANT_ALPHA:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
	}
}

void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
	TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
	      target, size, data, usage);

	if(size < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	switch(usage)
	{
	case GL_STREAM_DRAW:
	case GL_STATIC_DRAW:
	case GL_DYNAMIC_DRAW:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Buffer *buffer;

		switch(target)
		{
		case GL_ARRAY_BUFFER:
			buffer = context->getArrayBuffer();
			break;
		case GL_ELEMENT_ARRAY_BUFFER:
			buffer = context->getElementArrayBuffer();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(!buffer)
		{
			return error(GL_INVALID_OPERATION);
		}

		buffer->bufferData(data, size, usage);
	}
}

void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
{
	TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
	      target, offset, size, data);

	if(size < 0 || offset < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(data == NULL)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Buffer *buffer;

		switch(target)
		{
		case GL_ARRAY_BUFFER:
			buffer = context->getArrayBuffer();
			break;
		case GL_ELEMENT_ARRAY_BUFFER:
			buffer = context->getElementArrayBuffer();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(!buffer)
		{
			return error(GL_INVALID_OPERATION);
		}

		if((size_t)size + offset > buffer->size())
		{
			return error(GL_INVALID_VALUE);
		}

		buffer->bufferSubData(data, size, offset);
	}
}

GLenum APIENTRY glCheckFramebufferStatus(GLenum target)
{
	TRACE("(GLenum target = 0x%X)", target);

	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
	{
		return error(GL_INVALID_ENUM, 0);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Framebuffer *framebuffer = NULL;
		if(target == GL_READ_FRAMEBUFFER_EXT)
		{
			framebuffer = context->getReadFramebuffer();
		}
		else
		{
			framebuffer = context->getDrawFramebuffer();
		}

		return framebuffer->completeness();
	}

	return 0;
}

void APIENTRY glClear(GLbitfield mask)
{
	TRACE("(GLbitfield mask = %X)", mask);

	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			return context->listCommand(gl::newCommand(glClear, mask));
		}

		context->clear(mask);
	}
}

void APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
	TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
	      red, green, blue, alpha);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setClearColor(red, green, blue, alpha);
	}
}

void APIENTRY glClearDepthf(GLclampf depth)
{
	TRACE("(GLclampf depth = %f)", depth);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setClearDepth(depth);
	}
}

void APIENTRY glClearStencil(GLint s)
{
	TRACE("(GLint s = %d)", s);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setClearStencil(s);
	}
}

void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
{
	TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
	      red, green, blue, alpha);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
	}
}

void APIENTRY glCompileShader(GLuint shader)
{
	TRACE("(GLuint shader = %d)", shader);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Shader *shaderObject = context->getShader(shader);

		if(!shaderObject)
		{
			if(context->getProgram(shader))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		shaderObject->compile();
	}
}

void APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
                                        GLint border, GLsizei imageSize, const GLvoid* data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
	      "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
	      target, level, internalformat, width, height, border, imageSize, data);

	if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	switch(internalformat)
	{
	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
		if(!S3TC_SUPPORT)
		{
			return error(GL_INVALID_ENUM);
		}
		break;
	case GL_DEPTH_COMPONENT:
	case GL_DEPTH_COMPONENT16:
	case GL_DEPTH_COMPONENT32:
	case GL_DEPTH_STENCIL_EXT:
	case GL_DEPTH24_STENCIL8_EXT:
		return error(GL_INVALID_OPERATION);
	default:
		return error(GL_INVALID_ENUM);
	}

	if(border != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
		{
			return error(GL_INVALID_VALUE);
		}

		switch(target)
		{
		case GL_TEXTURE_2D:
			if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
			   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
			if(width != height)
			{
				return error(GL_INVALID_VALUE);
			}

			if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
			   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))
		{
			return error(GL_INVALID_VALUE);
		}

		if(target == GL_TEXTURE_2D)
		{
			gl::Texture2D *texture = context->getTexture2D(target);

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
		}
		else
		{
			gl::TextureCubeMap *texture = context->getTextureCubeMap();

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			switch(target)
			{
			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
				texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
				break;
			default: UNREACHABLE(target);
			}
		}
	}
}

void APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                                           GLenum format, GLsizei imageSize, const GLvoid* data)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
	      "GLsizei imageSize = %d, const GLvoid* data = %p)",
	      target, level, xoffset, yoffset, width, height, format, imageSize, data);

	if(!gl::IsTextureTarget(target))
	{
		return error(GL_INVALID_ENUM);
	}

	if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	switch(format)
	{
	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
		if(!S3TC_SUPPORT)
		{
			return error(GL_INVALID_ENUM);
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(width == 0 || height == 0 || data == NULL)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
		{
			return error(GL_INVALID_VALUE);
		}

		if(imageSize != gl::ComputeCompressedSize(width, height, format))
		{
			return error(GL_INVALID_VALUE);
		}

		if(xoffset % 4 != 0 || yoffset % 4 != 0)
		{
			// We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
			return error(GL_INVALID_OPERATION);
		}

		if(target == GL_TEXTURE_2D)
		{
			gl::Texture2D *texture = context->getTexture2D(target);

			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
			{
				texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
			}
		}
		else if(gl::IsCubemapTextureTarget(target))
		{
			gl::TextureCubeMap *texture = context->getTextureCubeMap();

			if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))
			{
				texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
			}
		}
		else UNREACHABLE(target);
	}
}

void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
	      target, level, internalformat, x, y, width, height, border);

	if(!validImageSize(level, width, height))
	{
		return error(GL_INVALID_VALUE);
	}

	if(border != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		switch(target)
		{
		case GL_TEXTURE_2D:
			if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
			   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
			if(width != height)
			{
				return error(GL_INVALID_VALUE);
			}

			if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
			   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		gl::Framebuffer *framebuffer = context->getReadFramebuffer();

		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
		{
			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
		}

		if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
		{
			return error(GL_INVALID_OPERATION);
		}

		gl::Renderbuffer *source = framebuffer->getColorbuffer();
		GLenum colorbufferFormat = source->getFormat();

		switch(internalformat)
		{
		case GL_ALPHA:
			if(colorbufferFormat != GL_ALPHA &&
			   colorbufferFormat != GL_RGBA &&
			   colorbufferFormat != GL_RGBA4 &&
			   colorbufferFormat != GL_RGB5_A1 &&
			   colorbufferFormat != GL_RGBA8_EXT)
			{
				return error(GL_INVALID_OPERATION);
			}
			break;
		case GL_LUMINANCE:
		case GL_RGB:
			if(colorbufferFormat != GL_RGB &&
			   colorbufferFormat != GL_RGB565 &&
			   colorbufferFormat != GL_RGB8_EXT &&
			   colorbufferFormat != GL_RGBA &&
			   colorbufferFormat != GL_RGBA4 &&
			   colorbufferFormat != GL_RGB5_A1 &&
			   colorbufferFormat != GL_RGBA8_EXT)
			{
				return error(GL_INVALID_OPERATION);
			}
			break;
		case GL_LUMINANCE_ALPHA:
		case GL_RGBA:
			if(colorbufferFormat != GL_RGBA &&
			   colorbufferFormat != GL_RGBA4 &&
			   colorbufferFormat != GL_RGB5_A1 &&
			   colorbufferFormat != GL_RGBA8_EXT)
			{
				return error(GL_INVALID_OPERATION);
			}
			break;
		case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
		case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
		case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
			if(S3TC_SUPPORT)
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_ENUM);
			}
		default:
			return error(GL_INVALID_ENUM);
		}

		if(target == GL_TEXTURE_2D)
		{
			gl::Texture2D *texture = context->getTexture2D(target);

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
		}
		else if(gl::IsCubemapTextureTarget(target))
		{
			gl::TextureCubeMap *texture = context->getTextureCubeMap();

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
		}
		else UNREACHABLE(target);
	}
}

void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
	      target, level, xoffset, yoffset, x, y, width, height);

	if(!gl::IsTextureTarget(target))
	{
		return error(GL_INVALID_ENUM);
	}

	if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
	{
		return error(GL_INVALID_VALUE);
	}

	if(width == 0 || height == 0)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
		{
			return error(GL_INVALID_VALUE);
		}

		gl::Framebuffer *framebuffer = context->getReadFramebuffer();

		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
		{
			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
		}

		if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
		{
			return error(GL_INVALID_OPERATION);
		}

		gl::Texture *texture = NULL;

		if(target == GL_TEXTURE_2D)
		{
			texture = context->getTexture2D(target);
		}
		else if(gl::IsCubemapTextureTarget(target))
		{
			texture = context->getTextureCubeMap();
		}
		else UNREACHABLE(target);

		if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))
		{
			return;
		}

		texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
	}
}

GLuint APIENTRY glCreateProgram(void)
{
	TRACE("()");

	gl::Context *context = gl::getContext();

	if(context)
	{
		return context->createProgram();
	}

	return 0;
}

GLuint APIENTRY glCreateShader(GLenum type)
{
	TRACE("(GLenum type = 0x%X)", type);

	gl::Context *context = gl::getContext();

	if(context)
	{
		switch(type)
		{
		case GL_FRAGMENT_SHADER:
		case GL_VERTEX_SHADER:
			return context->createShader(type);
		default:
			return error(GL_INVALID_ENUM, 0);
		}
	}

	return 0;
}

void APIENTRY glCullFace(GLenum mode)
{
	TRACE("(GLenum mode = 0x%X)", mode);

	switch(mode)
	{
	case GL_FRONT:
	case GL_BACK:
	case GL_FRONT_AND_BACK:
		{
			gl::Context *context = gl::getContext();

			if(context)
			{
				context->setCullMode(mode);
			}
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}
}

void APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
{
	TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			context->deleteBuffer(buffers[i]);
		}
	}
}

void APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences)
{
	TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		for(int i = 0; i < n; i++)
		{
			context->deleteFence(fences[i]);
		}
	}
}

void APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
{
	TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		for(int i = 0; i < n; i++)
		{
			if(framebuffers[i] != 0)
			{
				context->deleteFramebuffer(framebuffers[i]);
			}
		}
	}
}

void APIENTRY glDeleteProgram(GLuint program)
{
	TRACE("(GLuint program = %d)", program);

	if(program == 0)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(!context->getProgram(program))
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		context->deleteProgram(program);
	}
}

void APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
{
	TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			context->deleteQuery(ids[i]);
		}
	}
}

void APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
{
	TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		for(int i = 0; i < n; i++)
		{
			context->deleteRenderbuffer(renderbuffers[i]);
		}
	}
}

void APIENTRY glDeleteShader(GLuint shader)
{
	TRACE("(GLuint shader = %d)", shader);

	if(shader == 0)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(!context->getShader(shader))
		{
			if(context->getProgram(shader))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		context->deleteShader(shader);
	}
}

void APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
{
	TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			if(textures[i] != 0)
			{
				context->deleteTexture(textures[i]);
			}
		}
	}
}

void APIENTRY glDepthFunc(GLenum func)
{
	TRACE("(GLenum func = 0x%X)", func);

	switch(func)
	{
	case GL_NEVER:
	case GL_ALWAYS:
	case GL_LESS:
	case GL_LEQUAL:
	case GL_EQUAL:
	case GL_GREATER:
	case GL_GEQUAL:
	case GL_NOTEQUAL:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setDepthFunc(func);
	}
}

void APIENTRY glDepthMask(GLboolean flag)
{
	TRACE("(GLboolean flag = %d)", flag);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setDepthMask(flag != GL_FALSE);
	}
}

void APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
{
	TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setDepthRange(zNear, zFar);
	}
}

void APIENTRY glDetachShader(GLuint program, GLuint shader)
{
	TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);
		gl::Shader *shaderObject = context->getShader(shader);

		if(!programObject)
		{
			gl::Shader *shaderByProgramHandle;
			shaderByProgramHandle = context->getShader(program);
			if(!shaderByProgramHandle)
			{
				return error(GL_INVALID_VALUE);
			}
			else
			{
				return error(GL_INVALID_OPERATION);
			}
		}

		if(!shaderObject)
		{
			gl::Program *programByShaderHandle = context->getProgram(shader);
			if(!programByShaderHandle)
			{
				return error(GL_INVALID_VALUE);
			}
			else
			{
				return error(GL_INVALID_OPERATION);
			}
		}

		if(!programObject->detachShader(shaderObject))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glDisable(GLenum cap)
{
	TRACE("(GLenum cap = 0x%X)", cap);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		switch(cap)
		{
		case GL_CULL_FACE:                context->setCullFaceEnabled(false);              break;
		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(false);     break;
		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break;
		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(false);        break;
		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(false);           break;
		case GL_STENCIL_TEST:             context->setStencilTestEnabled(false);           break;
		case GL_DEPTH_TEST:               context->setDepthTestEnabled(false);             break;
		case GL_BLEND:                    context->setBlendEnabled(false);                 break;
		case GL_DITHER:                   context->setDitherEnabled(false);                break;
		case GL_LIGHTING:                 context->setLightingEnabled(false);              break;
		case GL_FOG:                      context->setFogEnabled(false);                   break;
		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(false);             break;
		case GL_TEXTURE_2D:               context->setTexture2DEnabled(false);             break;
		case GL_LIGHT0:                   context->setLightEnabled(0, false);              break;
		case GL_LIGHT1:                   context->setLightEnabled(1, false);              break;
		case GL_LIGHT2:                   context->setLightEnabled(2, false);              break;
		case GL_LIGHT3:                   context->setLightEnabled(3, false);              break;
		case GL_LIGHT4:                   context->setLightEnabled(4, false);              break;
		case GL_LIGHT5:                   context->setLightEnabled(5, false);              break;
		case GL_LIGHT6:                   context->setLightEnabled(6, false);              break;
		case GL_LIGHT7:                   context->setLightEnabled(7, false);              break;
		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(false);         break;
		case GL_RESCALE_NORMAL:           context->setNormalizeNormalsEnabled(false);      break;
		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(false);          break;
		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glDisableVertexAttribArray(GLuint index)
{
	TRACE("(GLuint index = %d)", index);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		context->setVertexAttribArrayEnabled(index, false);
	}
}

void APIENTRY glCaptureAttribs()
{
	TRACE("()");

	gl::Context *context = gl::getContext();

	if(context)
	{
		context->captureAttribs();
	}
}

void APIENTRY glRestoreAttribs()
{
	TRACE("()");

	gl::Context *context = gl::getContext();

	if(context)
	{
		context->restoreAttribs();
	}
}

void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
{
	TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);

	if(count < 0 || first < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			ASSERT(context->getListMode() != GL_COMPILE_AND_EXECUTE);   // UNIMPLEMENTED!

			context->listCommand(gl::newCommand(glCaptureAttribs));
			context->captureDrawArrays(mode, first, count);
			context->listCommand(gl::newCommand(glDrawArrays, mode, first, count));
			context->listCommand(gl::newCommand(glRestoreAttribs));

			return;
		}

		context->drawArrays(mode, first, count);
	}
}

void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
{
	TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
	      mode, count, type, indices);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		switch(type)
		{
		case GL_UNSIGNED_BYTE:
		case GL_UNSIGNED_SHORT:
		case GL_UNSIGNED_INT:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		context->drawElements(mode, count, type, indices);
	}
}

void APIENTRY glEnable(GLenum cap)
{
	TRACE("(GLenum cap = 0x%X)", cap);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		switch(cap)
		{
		case GL_CULL_FACE:                context->setCullFaceEnabled(true);              break;
		case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFillEnabled(true);     break;
		case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break;
		case GL_SAMPLE_COVERAGE:          context->setSampleCoverageEnabled(true);        break;
		case GL_SCISSOR_TEST:             context->setScissorTestEnabled(true);           break;
		case GL_STENCIL_TEST:             context->setStencilTestEnabled(true);           break;
		case GL_DEPTH_TEST:               context->setDepthTestEnabled(true);             break;
		case GL_BLEND:                    context->setBlendEnabled(true);                 break;
		case GL_DITHER:                   context->setDitherEnabled(true);                break;
		case GL_TEXTURE_2D:               context->setTexture2DEnabled(true);             break;
		case GL_ALPHA_TEST:               context->setAlphaTestEnabled(true);             break;
		case GL_COLOR_MATERIAL:           context->setColorMaterialEnabled(true);         break;
		case GL_FOG:                      context->setFogEnabled(true);                   break;
		case GL_LIGHTING:                 context->setLightingEnabled(true);              break;
		case GL_LIGHT0:                   context->setLightEnabled(0, true);              break;
		case GL_LIGHT1:                   context->setLightEnabled(1, true);              break;
		case GL_LIGHT2:                   context->setLightEnabled(2, true);              break;
		case GL_LIGHT3:                   context->setLightEnabled(3, true);              break;
		case GL_LIGHT4:                   context->setLightEnabled(4, true);              break;
		case GL_LIGHT5:                   context->setLightEnabled(5, true);              break;
		case GL_LIGHT6:                   context->setLightEnabled(6, true);              break;
		case GL_LIGHT7:                   context->setLightEnabled(7, true);              break;
		case GL_RESCALE_NORMAL:           context->setNormalizeNormalsEnabled(true);      break;
		case GL_COLOR_LOGIC_OP:           context->setColorLogicOpEnabled(true);          break;
		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glEnableVertexAttribArray(GLuint index)
{
	TRACE("(GLuint index = %d)", index);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		context->setVertexAttribArrayEnabled(index, true);
	}
}

void APIENTRY glEndQueryEXT(GLenum target)
{
	TRACE("GLenum target = 0x%X)", target);

	switch(target)
	{
	case GL_ANY_SAMPLES_PASSED:
	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->endQuery(target);
	}
}

void APIENTRY glFinishFenceNV(GLuint fence)
{
	TRACE("(GLuint fence = %d)", fence);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Fence* fenceObject = context->getFence(fence);

		if(fenceObject == NULL)
		{
			return error(GL_INVALID_OPERATION);
		}

		fenceObject->finishFence();
	}
}

void APIENTRY glFinish(void)
{
	TRACE("()");

	gl::Context *context = gl::getContext();

	if(context)
	{
		context->finish();
	}
}

void APIENTRY glFlush(void)
{
	TRACE("()");

	gl::Context *context = gl::getContext();

	if(context)
	{
		context->flush();
	}
}

void APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
	      "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);

	if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT) ||
	   (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
	{
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Framebuffer *framebuffer = NULL;
		GLuint framebufferName = 0;
		if(target == GL_READ_FRAMEBUFFER_EXT)
		{
			framebuffer = context->getReadFramebuffer();
			framebufferName = context->getReadFramebufferName();
		}
		else
		{
			framebuffer = context->getDrawFramebuffer();
			framebufferName = context->getDrawFramebufferName();
		}

		if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(attachment)
		{
		case GL_COLOR_ATTACHMENT0:
			framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
			break;
		case GL_DEPTH_ATTACHMENT:
			framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
			break;
		case GL_STENCIL_ATTACHMENT:
			framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
	UNIMPLEMENTED();
}

void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
	      "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);

	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
	{
		return error(GL_INVALID_ENUM);
	}

	switch(attachment)
	{
	case GL_COLOR_ATTACHMENT0:
	case GL_DEPTH_ATTACHMENT:
	case GL_STENCIL_ATTACHMENT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(texture == 0)
		{
			textarget = GL_NONE;
		}
		else
		{
			gl::Texture *tex = context->getTexture(texture);

			if(tex == NULL)
			{
				return error(GL_INVALID_OPERATION);
			}

			if(tex->isCompressed(textarget, level))
			{
				return error(GL_INVALID_OPERATION);
			}

			switch(textarget)
			{
			case GL_TEXTURE_2D:
				if(tex->getTarget() != GL_TEXTURE_2D)
				{
					return error(GL_INVALID_OPERATION);
				}
				break;
			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
				if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
				{
					return error(GL_INVALID_OPERATION);
				}
				break;
			default:
				return error(GL_INVALID_ENUM);
			}

			if(level != 0)
			{
				return error(GL_INVALID_VALUE);
			}
		}

		gl::Framebuffer *framebuffer = NULL;
		GLuint framebufferName = 0;
		if(target == GL_READ_FRAMEBUFFER_EXT)
		{
			framebuffer = context->getReadFramebuffer();
			framebufferName = context->getReadFramebufferName();
		}
		else
		{
			framebuffer = context->getDrawFramebuffer();
			framebufferName = context->getDrawFramebufferName();
		}

		if(framebufferName == 0 || !framebuffer)
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(attachment)
		{
		case GL_COLOR_ATTACHMENT0:  framebuffer->setColorbuffer(textarget, texture);   break;
		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;
		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
		}
	}
}

void APIENTRY glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
{
	UNIMPLEMENTED();
}

void APIENTRY glFrontFace(GLenum mode)
{
	TRACE("(GLenum mode = 0x%X)", mode);

	switch(mode)
	{
	case GL_CW:
	case GL_CCW:
		{
			gl::Context *context = gl::getContext();

			if(context)
			{
				context->setFrontFace(mode);
			}
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}
}

void APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
{
	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			buffers[i] = context->createBuffer();
		}
	}
}

void APIENTRY glGenerateMipmap(GLenum target)
{
	TRACE("(GLenum target = 0x%X)", target);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D(target);
			break;
		case GL_TEXTURE_CUBE_MAP:
			texture = context->getTextureCubeMap();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
		{
			return error(GL_INVALID_OPERATION);
		}

		texture->generateMipmaps();
	}
}

void APIENTRY glGenFencesNV(GLsizei n, GLuint* fences)
{
	TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		for(int i = 0; i < n; i++)
		{
			fences[i] = context->createFence();
		}
	}
}

void APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
{
	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		for(int i = 0; i < n; i++)
		{
			framebuffers[i] = context->createFramebuffer();
		}
	}
}

void APIENTRY glGenQueriesEXT(GLsizei n, GLuint* ids)
{
	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			ids[i] = context->createQuery();
		}
	}
}

void APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
{
	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		for(int i = 0; i < n; i++)
		{
			renderbuffers[i] = context->createRenderbuffer();
		}
	}
}

void APIENTRY glGenTextures(GLsizei n, GLuint* textures)
{
	TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);

	if(n < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		for(int i = 0; i < n; i++)
		{
			textures[i] = context->createTexture();
		}
	}
}

void APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
	      "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
	      program, index, bufsize, length, size, type, name);

	if(bufsize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(index >= programObject->getActiveAttributeCount())
		{
			return error(GL_INVALID_VALUE);
		}

		programObject->getActiveAttribute(index, bufsize, length, size, type, name);
	}
}

void APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
{
	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
	      "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
	      program, index, bufsize, length, size, type, name);

	if(bufsize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(index >= programObject->getActiveUniformCount())
		{
			return error(GL_INVALID_VALUE);
		}

		programObject->getActiveUniform(index, bufsize, length, size, type, name);
	}
}

void APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
{
	TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
	      program, maxcount, count, shaders);

	if(maxcount < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		return programObject->getAttachedShaders(maxcount, count, shaders);
	}
}

int APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
{
	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION, -1);
			}
			else
			{
				return error(GL_INVALID_VALUE, -1);
			}
		}

		if(!programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION, -1);
		}

		return programObject->getAttributeLocation(name);
	}

	return -1;
}

void APIENTRY glGetBooleanv(GLenum pname, GLboolean* params)
{
	TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)",  pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(!(context->getBooleanv(pname, params)))
		{
			GLenum nativeType;
			unsigned int numParams = 0;
			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
				return error(GL_INVALID_ENUM);

			if(numParams == 0)
				return; // it is known that the pname is valid, but there are no parameters to return

			if(nativeType == GL_FLOAT)
			{
				GLfloat *floatParams = NULL;
				floatParams = new GLfloat[numParams];

				context->getFloatv(pname, floatParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					if(floatParams[i] == 0.0f)
						params[i] = GL_FALSE;
					else
						params[i] = GL_TRUE;
				}

				delete [] floatParams;
			}
			else if(nativeType == GL_INT)
			{
				GLint *intParams = NULL;
				intParams = new GLint[numParams];

				context->getIntegerv(pname, intParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					if(intParams[i] == 0)
						params[i] = GL_FALSE;
					else
						params[i] = GL_TRUE;
				}

				delete [] intParams;
			}
		}
	}
}

void APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Buffer *buffer;

		switch(target)
		{
		case GL_ARRAY_BUFFER:
			buffer = context->getArrayBuffer();
			break;
		case GL_ELEMENT_ARRAY_BUFFER:
			buffer = context->getElementArrayBuffer();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		if(!buffer)
		{
			// A null buffer means that "0" is bound to the requested buffer target
			return error(GL_INVALID_OPERATION);
		}

		switch(pname)
		{
		case GL_BUFFER_USAGE:
			*params = buffer->usage();
			break;
		case GL_BUFFER_SIZE:
			*params = buffer->size();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

GLenum APIENTRY glGetError(void)
{
	TRACE("()");

	gl::Context *context = gl::getContext();

	if(context)
	{
		return context->getError();
	}

	return GL_NO_ERROR;
}

void APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
{
	TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Fence *fenceObject = context->getFence(fence);

		if(fenceObject == NULL)
		{
			return error(GL_INVALID_OPERATION);
		}

		fenceObject->getFenceiv(pname, params);
	}
}

void APIENTRY glGetFloatv(GLenum pname, GLfloat* params)
{
	TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(!(context->getFloatv(pname, params)))
		{
			GLenum nativeType;
			unsigned int numParams = 0;
			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
				return error(GL_INVALID_ENUM);

			if(numParams == 0)
				return; // it is known that the pname is valid, but that there are no parameters to return.

			if(nativeType == GL_BOOL)
			{
				GLboolean *boolParams = NULL;
				boolParams = new GLboolean[numParams];

				context->getBooleanv(pname, boolParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					if(boolParams[i] == GL_FALSE)
						params[i] = 0.0f;
					else
						params[i] = 1.0f;
				}

				delete [] boolParams;
			}
			else if(nativeType == GL_INT)
			{
				GLint *intParams = NULL;
				intParams = new GLint[numParams];

				context->getIntegerv(pname, intParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					params[i] = (GLfloat)intParams[i];
				}

				delete [] intParams;
			}
		}
	}
}

void APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
	      target, attachment, pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_EXT && target != GL_READ_FRAMEBUFFER_EXT)
		{
			return error(GL_INVALID_ENUM);
		}

		gl::Framebuffer *framebuffer = NULL;
		if(target == GL_READ_FRAMEBUFFER_EXT)
		{
			if(context->getReadFramebufferName() == 0)
			{
				return error(GL_INVALID_OPERATION);
			}

			framebuffer = context->getReadFramebuffer();
		}
		else
		{
			if(context->getDrawFramebufferName() == 0)
			{
				return error(GL_INVALID_OPERATION);
			}

			framebuffer = context->getDrawFramebuffer();
		}

		GLenum attachmentType;
		GLuint attachmentHandle;
		switch(attachment)
		{
		case GL_COLOR_ATTACHMENT0:
			attachmentType = framebuffer->getColorbufferType();
			attachmentHandle = framebuffer->getColorbufferName();
			break;
		case GL_DEPTH_ATTACHMENT:
			attachmentType = framebuffer->getDepthbufferType();
			attachmentHandle = framebuffer->getDepthbufferName();
			break;
		case GL_STENCIL_ATTACHMENT:
			attachmentType = framebuffer->getStencilbufferType();
			attachmentHandle = framebuffer->getStencilbufferName();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		GLenum attachmentObjectType;   // Type category
		if(attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
		{
			attachmentObjectType = attachmentType;
		}
		else if(gl::IsTextureTarget(attachmentType))
		{
			attachmentObjectType = GL_TEXTURE;
		}
		else UNREACHABLE(attachmentType);

		switch(pname)
		{
		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
			*params = attachmentObjectType;
			break;
		case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
			if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
			{
				*params = attachmentHandle;
			}
			else
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
			if(attachmentObjectType == GL_TEXTURE)
			{
				*params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
			}
			else
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
			if(attachmentObjectType == GL_TEXTURE)
			{
				if(gl::IsCubemapTextureTarget(attachmentType))
				{
					*params = attachmentType;
				}
				else
				{
					*params = 0;
				}
			}
			else
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

GLenum APIENTRY glGetGraphicsResetStatusEXT(void)
{
	TRACE("()");

	return GL_NO_ERROR;
}

void APIENTRY glGetIntegerv(GLenum pname, GLint* params)
{
	TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(!(context->getIntegerv(pname, params)))
		{
			GLenum nativeType;
			unsigned int numParams = 0;
			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
				return error(GL_INVALID_ENUM);

			if(numParams == 0)
				return; // it is known that pname is valid, but there are no parameters to return

			if(nativeType == GL_BOOL)
			{
				GLboolean *boolParams = NULL;
				boolParams = new GLboolean[numParams];

				context->getBooleanv(pname, boolParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					if(boolParams[i] == GL_FALSE)
						params[i] = 0;
					else
						params[i] = 1;
				}

				delete [] boolParams;
			}
			else if(nativeType == GL_FLOAT)
			{
				GLfloat *floatParams = NULL;
				floatParams = new GLfloat[numParams];

				context->getFloatv(pname, floatParams);

				for(unsigned int i = 0; i < numParams; ++i)
				{
					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
					{
						params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
					}
					else
					{
						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
					}
				}

				delete [] floatParams;
			}
		}
	}
}

void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
{
	TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			return error(GL_INVALID_VALUE);
		}

		switch(pname)
		{
		case GL_DELETE_STATUS:
			*params = programObject->isFlaggedForDeletion();
			return;
		case GL_LINK_STATUS:
			*params = programObject->isLinked();
			return;
		case GL_VALIDATE_STATUS:
			*params = programObject->isValidated();
			return;
		case GL_INFO_LOG_LENGTH:
			*params = programObject->getInfoLogLength();
			return;
		case GL_ATTACHED_SHADERS:
			*params = programObject->getAttachedShadersCount();
			return;
		case GL_ACTIVE_ATTRIBUTES:
			*params = programObject->getActiveAttributeCount();
			return;
		case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
			*params = programObject->getActiveAttributeMaxLength();
			return;
		case GL_ACTIVE_UNIFORMS:
			*params = programObject->getActiveUniformCount();
			return;
		case GL_ACTIVE_UNIFORM_MAX_LENGTH:
			*params = programObject->getActiveUniformMaxLength();
			return;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
	TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
	      program, bufsize, length, infolog);

	if(bufsize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			return error(GL_INVALID_VALUE);
		}

		programObject->getInfoLog(bufsize, length, infolog);
	}
}

void APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
{
	TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);

	switch(pname)
	{
	case GL_CURRENT_QUERY:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		params[0] = context->getActiveQuery(target);
	}
}

void APIENTRY glGetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
{
	TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);

	switch(pname)
	{
	case GL_QUERY_RESULT:
	case GL_QUERY_RESULT_AVAILABLE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Query *queryObject = context->getQuery(name, false, GL_NONE);

		if(!queryObject)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(context->getActiveQuery(queryObject->getType()) == name)
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(pname)
		{
		case GL_QUERY_RESULT:
			params[0] = queryObject->getResult();
			break;
		case GL_QUERY_RESULT_AVAILABLE:
			params[0] = queryObject->isResultAvailable();
			break;
		default:
			ASSERT(false);
		}
	}
}

void APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(target != GL_RENDERBUFFER)
		{
			return error(GL_INVALID_ENUM);
		}

		if(context->getRenderbufferName() == 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());

		switch(pname)
		{
		case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;
		case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;
		case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;
		case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;
		case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;
		case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;
		case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;
		case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;
		case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;
		case GL_RENDERBUFFER_SAMPLES_EXT:     *params = renderbuffer->getSamples();     break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
{
	TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Shader *shaderObject = context->getShader(shader);

		if(!shaderObject)
		{
			return error(GL_INVALID_VALUE);
		}

		switch(pname)
		{
		case GL_SHADER_TYPE:
			*params = shaderObject->getType();
			return;
		case GL_DELETE_STATUS:
			*params = shaderObject->isFlaggedForDeletion();
			return;
		case GL_COMPILE_STATUS:
			*params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
			return;
		case GL_INFO_LOG_LENGTH:
			*params = shaderObject->getInfoLogLength();
			return;
		case GL_SHADER_SOURCE_LENGTH:
			*params = shaderObject->getSourceLength();
			return;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
	      shader, bufsize, length, infolog);

	if(bufsize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Shader *shaderObject = context->getShader(shader);

		if(!shaderObject)
		{
			return error(GL_INVALID_VALUE);
		}

		shaderObject->getInfoLog(bufsize, length, infolog);
	}
}

void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
{
	TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
	      shadertype, precisiontype, range, precision);

	switch(shadertype)
	{
	case GL_VERTEX_SHADER:
	case GL_FRAGMENT_SHADER:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(precisiontype)
	{
	case GL_LOW_FLOAT:
	case GL_MEDIUM_FLOAT:
	case GL_HIGH_FLOAT:
		// IEEE 754 single-precision
		range[0] = 127;
		range[1] = 127;
		*precision = 23;
		break;
	case GL_LOW_INT:
	case GL_MEDIUM_INT:
	case GL_HIGH_INT:
		// Full integer precision is supported
		range[0] = 31;
		range[1] = 30;
		*precision = 0;
		break;
	default:
		return error(GL_INVALID_ENUM);
	}
}

void APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
{
	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
	      shader, bufsize, length, source);

	if(bufsize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Shader *shaderObject = context->getShader(shader);

		if(!shaderObject)
		{
			return error(GL_INVALID_OPERATION);
		}

		shaderObject->getSource(bufsize, length, source);
	}
}

const GLubyte* APIENTRY glGetString(GLenum name)
{
	TRACE("(GLenum name = 0x%X)", name);

	switch(name)
	{
	case GL_VENDOR:
		return (GLubyte*)"TransGaming Inc.";
	case GL_RENDERER:
		return (GLubyte*)"SwiftShader";
	case GL_VERSION:
		return (GLubyte*)"2.1 SwiftShader "VERSION_STRING;
	case GL_SHADING_LANGUAGE_VERSION:
		return (GLubyte*)"3.30 SwiftShader "VERSION_STRING;
	case GL_EXTENSIONS:
		// Keep list sorted in following order:
		// OES extensions
		// EXT extensions
		// Vendor extensions
		return (GLubyte*)
			"GL_ARB_framebuffer_object "
			"GL_EXT_blend_minmax "
			"GL_EXT_depth_texture "
			"GL_EXT_depth_texture_cube_map "
			"GL_EXT_element_index_uint "
			"GL_EXT_packed_depth_stencil "
			"GL_EXT_rgb8_rgba8 "
			"GL_EXT_standard_derivatives "
			"GL_EXT_texture_float "
			"GL_EXT_texture_float_linear "
			"GL_EXT_texture_half_float "
			"GL_EXT_texture_half_float_linear "
			"GL_EXT_texture_npot "
			"GL_EXT_occlusion_query_boolean "
			"GL_EXT_read_format_bgra "
			#if (S3TC_SUPPORT)
			"GL_EXT_texture_compression_dxt1 "
			#endif
			"GL_EXT_blend_func_separate "
			"GL_EXT_secondary_color "
			"GL_EXT_texture_filter_anisotropic "
			"GL_EXT_texture_format_BGRA8888 "
			"GL_EXT_framebuffer_blit "
			"GL_EXT_framebuffer_multisample "
			#if (S3TC_SUPPORT)
			"GL_EXT_texture_compression_dxt3 "
			"GL_EXT_texture_compression_dxt5 "
			#endif
			"GL_NV_fence";
	default:
		return error(GL_INVALID_ENUM, (GLubyte*)NULL);
	}

	return NULL;
}

void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D(target);
			break;
		case GL_TEXTURE_CUBE_MAP:
			texture = context->getTextureCubeMap();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_MAG_FILTER:
			*params = (GLfloat)texture->getMagFilter();
			break;
		case GL_TEXTURE_MIN_FILTER:
			*params = (GLfloat)texture->getMinFilter();
			break;
		case GL_TEXTURE_WRAP_S:
			*params = (GLfloat)texture->getWrapS();
			break;
		case GL_TEXTURE_WRAP_T:
			*params = (GLfloat)texture->getWrapT();
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			*params = texture->getMaxAnisotropy();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D(target);
			break;
		case GL_TEXTURE_CUBE_MAP:
			texture = context->getTextureCubeMap();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_MAG_FILTER:
			*params = texture->getMagFilter();
			break;
		case GL_TEXTURE_MIN_FILTER:
			*params = texture->getMinFilter();
			break;
		case GL_TEXTURE_WRAP_S:
			*params = texture->getWrapS();
			break;
		case GL_TEXTURE_WRAP_T:
			*params = texture->getWrapT();
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			*params = (GLint)texture->getMaxAnisotropy();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
{
	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
	      program, location, bufSize, params);

	if(bufSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(program == 0)
		{
			return error(GL_INVALID_VALUE);
		}

		gl::Program *programObject = context->getProgram(program);

		if(!programObject || !programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!programObject->getUniformfv(location, &bufSize, params))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
{
	TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(program == 0)
		{
			return error(GL_INVALID_VALUE);
		}

		gl::Program *programObject = context->getProgram(program);

		if(!programObject || !programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!programObject->getUniformfv(location, NULL, params))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
{
	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
	      program, location, bufSize, params);

	if(bufSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(program == 0)
		{
			return error(GL_INVALID_VALUE);
		}

		gl::Program *programObject = context->getProgram(program);

		if(!programObject || !programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!programObject)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!programObject->getUniformiv(location, &bufSize, params))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
{
	TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(program == 0)
		{
			return error(GL_INVALID_VALUE);
		}

		gl::Program *programObject = context->getProgram(program);

		if(!programObject || !programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!programObject)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!programObject->getUniformiv(location, NULL, params))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

int APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
{
	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);

	gl::Context *context = gl::getContext();

	if(strstr(name, "gl_") == name)
	{
		return -1;
	}

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION, -1);
			}
			else
			{
				return error(GL_INVALID_VALUE, -1);
			}
		}

		if(!programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION, -1);
		}

		return programObject->getUniformLocation(name);
	}

	return -1;
}

void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
{
	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(index >= gl::MAX_VERTEX_ATTRIBS)
		{
			return error(GL_INVALID_VALUE);
		}

		const gl::VertexAttribute &attribState = context->getVertexAttribState(index);

		switch(pname)
		{
		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
			*params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
			break;
		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
			*params = (GLfloat)attribState.mSize;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
			*params = (GLfloat)attribState.mStride;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
			*params = (GLfloat)attribState.mType;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
			*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
			break;
		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
			*params = (GLfloat)attribState.mBoundBuffer.name();
			break;
		case GL_CURRENT_VERTEX_ATTRIB:
			for(int i = 0; i < 4; ++i)
			{
				params[i] = attribState.mCurrentValue[i];
			}
			break;
		default: return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
{
	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(index >= gl::MAX_VERTEX_ATTRIBS)
		{
			return error(GL_INVALID_VALUE);
		}

		const gl::VertexAttribute &attribState = context->getVertexAttribState(index);

		switch(pname)
		{
		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
			break;
		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
			*params = attribState.mSize;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
			*params = attribState.mStride;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
			*params = attribState.mType;
			break;
		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
			break;
		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
			*params = attribState.mBoundBuffer.name();
			break;
		case GL_CURRENT_VERTEX_ATTRIB:
			for(int i = 0; i < 4; ++i)
			{
				float currentValue = attribState.mCurrentValue[i];
				params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
			}
			break;
		default: return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
{
	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(index >= gl::MAX_VERTEX_ATTRIBS)
		{
			return error(GL_INVALID_VALUE);
		}

		if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
		{
			return error(GL_INVALID_ENUM);
		}

		*pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
	}
}

void APIENTRY glHint(GLenum target, GLenum mode)
{
	TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);

	switch(mode)
	{
	case GL_FASTEST:
	case GL_NICEST:
	case GL_DONT_CARE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();
	switch(target)
	{
	case GL_GENERATE_MIPMAP_HINT:
		if(context) context->setGenerateMipmapHint(mode);
		break;
	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
		if(context) context->setFragmentShaderDerivativeHint(mode);
		break;
	default:
		return error(GL_INVALID_ENUM);
	}
}

GLboolean APIENTRY glIsBuffer(GLuint buffer)
{
	TRACE("(GLuint buffer = %d)", buffer);

	gl::Context *context = gl::getContext();

	if(context && buffer)
	{
		gl::Buffer *bufferObject = context->getBuffer(buffer);

		if(bufferObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean APIENTRY glIsEnabled(GLenum cap)
{
	TRACE("(GLenum cap = 0x%X)", cap);

	gl::Context *context = gl::getContext();

	if(context)
	{
		switch(cap)
		{
		case GL_CULL_FACE:                return context->isCullFaceEnabled();
		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();
		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();
		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();
		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();
		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();
		case GL_BLEND:                    return context->isBlendEnabled();
		case GL_DITHER:                   return context->isDitherEnabled();
		case GL_COLOR_LOGIC_OP:           return context->isColorLogicOpEnabled();
		case GL_INDEX_LOGIC_OP:           UNIMPLEMENTED();
		default:
			return error(GL_INVALID_ENUM, false);
		}
	}

	return false;
}

GLboolean APIENTRY glIsFenceNV(GLuint fence)
{
	TRACE("(GLuint fence = %d)", fence);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Fence *fenceObject = context->getFence(fence);

		if(fenceObject == NULL)
		{
			return GL_FALSE;
		}

		return fenceObject->isFence();
	}

	return GL_FALSE;
}

GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)
{
	TRACE("(GLuint framebuffer = %d)", framebuffer);

	gl::Context *context = gl::getContext();

	if(context && framebuffer)
	{
		gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);

		if(framebufferObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean APIENTRY glIsProgram(GLuint program)
{
	TRACE("(GLuint program = %d)", program);

	gl::Context *context = gl::getContext();

	if(context && program)
	{
		gl::Program *programObject = context->getProgram(program);

		if(programObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean APIENTRY glIsQueryEXT(GLuint name)
{
	TRACE("(GLuint name = %d)", name);

	if(name == 0)
	{
		return GL_FALSE;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Query *queryObject = context->getQuery(name, false, GL_NONE);

		if(queryObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)
{
	TRACE("(GLuint renderbuffer = %d)", renderbuffer);

	gl::Context *context = gl::getContext();

	if(context && renderbuffer)
	{
		gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);

		if(renderbufferObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean APIENTRY glIsShader(GLuint shader)
{
	TRACE("(GLuint shader = %d)", shader);

	gl::Context *context = gl::getContext();

	if(context && shader)
	{
		gl::Shader *shaderObject = context->getShader(shader);

		if(shaderObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

GLboolean APIENTRY glIsTexture(GLuint texture)
{
	TRACE("(GLuint texture = %d)", texture);

	gl::Context *context = gl::getContext();

	if(context && texture)
	{
		gl::Texture *textureObject = context->getTexture(texture);

		if(textureObject)
		{
			return GL_TRUE;
		}
	}

	return GL_FALSE;
}

void APIENTRY glLineWidth(GLfloat width)
{
	TRACE("(GLfloat width = %f)", width);

	if(width <= 0.0f)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setLineWidth(width);
	}
}

void APIENTRY glLinkProgram(GLuint program)
{
	TRACE("(GLuint program = %d)", program);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		programObject->link();
	}
}

void APIENTRY glPixelStorei(GLenum pname, GLint param)
{
	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);

	gl::Context *context = gl::getContext();

	if(context)
	{
		switch(pname)
		{
		case GL_UNPACK_ALIGNMENT:
			if(param != 1 && param != 2 && param != 4 && param != 8)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setUnpackAlignment(param);
			break;
		case GL_PACK_ALIGNMENT:
			if(param != 1 && param != 2 && param != 4 && param != 8)
			{
				return error(GL_INVALID_VALUE);
			}
			context->setPackAlignment(param);
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
{
	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setPolygonOffsetParams(factor, units);
	}
}

void APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
                                  GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
{
	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
	      "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
	      x, y, width, height, format, type, bufSize, data);

	if(width < 0 || height < 0 || bufSize < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(!validReadFormatType(format, type))
	{
		return error(GL_INVALID_OPERATION);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->readPixels(x, y, width, height, format, type, &bufSize, data);
	}
}

void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
{
	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
	      "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
	      x, y, width, height, format, type,  pixels);

	if(width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(!validReadFormatType(format, type))
	{
		return error(GL_INVALID_OPERATION);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		context->readPixels(x, y, width, height, format, type, NULL, pixels);
	}
}

void APIENTRY glReleaseShaderCompiler(void)
{
	TRACE("()");

	gl::Shader::releaseCompiler();
}

void APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
	TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
	      target, samples, internalformat, width, height);

	switch(target)
	{
	case GL_RENDERBUFFER:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
	{
		return error(GL_INVALID_ENUM);
	}

	if(width < 0 || height < 0 || samples < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(width > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE || 
		   height > gl::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
		   samples > gl::IMPLEMENTATION_MAX_SAMPLES)
		{
			return error(GL_INVALID_VALUE);
		}

		GLuint handle = context->getRenderbufferName();
		if(handle == 0)
		{
			return error(GL_INVALID_OPERATION);
		}

		switch(internalformat)
		{
		case GL_DEPTH_COMPONENT16:
		case GL_DEPTH_COMPONENT24:
			context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
			break;
		case GL_RGBA4:
		case GL_RGB5_A1:
		case GL_RGB565:
		case GL_RGB8_EXT:
		case GL_RGBA8_EXT:
			context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
			break;
		case GL_STENCIL_INDEX8:
			context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
			break;
		case GL_DEPTH24_STENCIL8_EXT:
			context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
	glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
}

void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
{
	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);

	gl::Context* context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
	}
}

void APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
{
	TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);

	if(condition != GL_ALL_COMPLETED_NV)
	{
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Fence *fenceObject = context->getFence(fence);

		if(fenceObject == NULL)
		{
			return error(GL_INVALID_OPERATION);
		}

		fenceObject->setFence(condition);
	}
}

void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

	if(width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context* context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setScissorParams(x, y, width, height);
	}
}

void APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
{
	TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
	      "const GLvoid* binary = %p, GLsizei length = %d)",
	      n, shaders, binaryformat, binary, length);

	// No binary shader formats are supported.
	return error(GL_INVALID_ENUM);
}

void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
{
	TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
	      shader, count, string, length);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Shader *shaderObject = context->getShader(shader);

		if(!shaderObject)
		{
			if(context->getProgram(shader))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		shaderObject->setSource(count, string, length);
	}
}

void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
{
	glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
}

void APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
{
	TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);

	switch(face)
	{
	case GL_FRONT:
	case GL_BACK:
	case GL_FRONT_AND_BACK:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(func)
	{
	case GL_NEVER:
	case GL_ALWAYS:
	case GL_LESS:
	case GL_LEQUAL:
	case GL_EQUAL:
	case GL_GEQUAL:
	case GL_GREATER:
	case GL_NOTEQUAL:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
		{
			context->setStencilParams(func, ref, mask);
		}

		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
		{
			context->setStencilBackParams(func, ref, mask);
		}
	}
}

void APIENTRY glStencilMask(GLuint mask)
{
	glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
}

void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
{
	TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);

	switch(face)
	{
	case GL_FRONT:
	case GL_BACK:
	case GL_FRONT_AND_BACK:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
		{
			context->setStencilWritemask(mask);
		}

		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
		{
			context->setStencilBackWritemask(mask);
		}
	}
}

void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
{
	glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
}

void APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
{
	TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
	      face, fail, zfail, zpass);

	switch(face)
	{
	case GL_FRONT:
	case GL_BACK:
	case GL_FRONT_AND_BACK:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(fail)
	{
	case GL_ZERO:
	case GL_KEEP:
	case GL_REPLACE:
	case GL_INCR:
	case GL_DECR:
	case GL_INVERT:
	case GL_INCR_WRAP:
	case GL_DECR_WRAP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(zfail)
	{
	case GL_ZERO:
	case GL_KEEP:
	case GL_REPLACE:
	case GL_INCR:
	case GL_DECR:
	case GL_INVERT:
	case GL_INCR_WRAP:
	case GL_DECR_WRAP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	switch(zpass)
	{
	case GL_ZERO:
	case GL_KEEP:
	case GL_REPLACE:
	case GL_INCR:
	case GL_DECR:
	case GL_INVERT:
	case GL_INCR_WRAP:
	case GL_DECR_WRAP:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
		{
			context->setStencilOperations(fail, zfail, zpass);
		}

		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
		{
			context->setStencilBackOperations(fail, zfail, zpass);
		}
	}
}

GLboolean APIENTRY glTestFenceNV(GLuint fence)
{
	TRACE("(GLuint fence = %d)", fence);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Fence *fenceObject = context->getFence(fence);

		if(fenceObject == NULL)
		{
			return error(GL_INVALID_OPERATION, GL_TRUE);
		}

		return fenceObject->testFence();
	}

	return GL_TRUE;
}

void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
                              GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
	      "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",
	      target, level, internalformat, width, height, border, format, type, pixels);

	if(!validImageSize(level, width, height))
	{
		return error(GL_INVALID_VALUE);
	}

	if(internalformat != format)
	{
		//TRACE("UNIMPLEMENTED!!");
		//return error(GL_INVALID_OPERATION);
	}

	switch(format)
	{
	case GL_ALPHA:
	case GL_LUMINANCE:
	case GL_LUMINANCE_ALPHA:
		switch(type)
		{
		case GL_UNSIGNED_BYTE:
		case GL_FLOAT:
		case GL_HALF_FLOAT:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
		break;
	case GL_RGB:
		switch(type)
		{
		case GL_UNSIGNED_BYTE:
		case GL_UNSIGNED_SHORT_5_6_5:
		case GL_FLOAT:
		case GL_HALF_FLOAT:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
		break;
	case GL_RGBA:
		switch(type)
		{
		case GL_UNSIGNED_BYTE:
		case GL_UNSIGNED_SHORT_4_4_4_4:
		case GL_UNSIGNED_SHORT_5_5_5_1:
		case GL_FLOAT:
		case GL_HALF_FLOAT:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
		break;
	case GL_BGRA_EXT:
		switch(type)
		{
		case GL_UNSIGNED_BYTE:
		case GL_UNSIGNED_SHORT_5_6_5:
		case GL_UNSIGNED_INT_8_8_8_8_REV:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
		break;
	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:  // error cases for compressed textures are handled below
	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
		break;
	case GL_DEPTH_COMPONENT:
		switch(type)
		{
		case GL_UNSIGNED_SHORT:
		case GL_UNSIGNED_INT:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
		break;
	case GL_DEPTH_STENCIL_EXT:
		switch(type)
		{
		case GL_UNSIGNED_INT_24_8_EXT:
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
		break;
	default:
		return error(GL_INVALID_VALUE);
	}

	if(border != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	switch(target)
	{
	case GL_TEXTURE_2D:
		if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
		   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
		{
			return error(GL_INVALID_VALUE);
		}
		break;
	case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
	case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
	case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
	case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
		if(width != height)
		{
			return error(GL_INVALID_VALUE);
		}

		if(width > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
		   height > (gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
		{
			return error(GL_INVALID_VALUE);
		}
		break;
	case GL_PROXY_TEXTURE_2D:
		pixels = 0;

		if(width > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
		   height > (gl::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
		{
			//UNIMPLEMENTED();
			width = 0;
			height = 0;
			internalformat = GL_NONE;
			format = GL_NONE;
			type = GL_NONE;

			//return;// error(GL_INVALID_VALUE);
		}
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
	   format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
	   format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
	   format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
	{
		if(S3TC_SUPPORT)
		{
			return error(GL_INVALID_OPERATION);
		}
		else
		{
			return error(GL_INVALID_ENUM);
		}
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D)
		{
			gl::Texture2D *texture = context->getTexture2D(target);

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
		}
		else
		{
			gl::TextureCubeMap *texture = context->getTextureCubeMap();

			if(!texture)
			{
				return error(GL_INVALID_OPERATION);
			}

			texture->setImage(target, level, width, height, format, type, context->getUnpackAlignment(), pixels);
		}
	}
}

void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D(target);
			break;
		case GL_TEXTURE_CUBE_MAP:
			texture = context->getTextureCubeMap();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_WRAP_S:
			if(!texture->setWrapS((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_WRAP_T:
			if(!texture->setWrapT((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MIN_FILTER:
			if(!texture->setMinFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAG_FILTER:
			if(!texture->setMagFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			if(!texture->setMaxAnisotropy(param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_MIN_LOD:
			//TRACE("() UNIMPLEMENTED!!");   // FIXME
			//UNIMPLEMENTED();
			break;
		case GL_TEXTURE_MAX_LOD:
			//TRACE("() UNIMPLEMENTED!!");   // FIXME
			//UNIMPLEMENTED();
			break;
		case GL_TEXTURE_LOD_BIAS:
			if(param != 0.0f)
			{
				UNIMPLEMENTED();
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
{
	glTexParameterf(target, pname, *params);
}

void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
{
	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D(target);
			break;
		case GL_TEXTURE_CUBE_MAP:
			texture = context->getTextureCubeMap();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_WRAP_S:
			if(!texture->setWrapS((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_WRAP_T:
			if(!texture->setWrapT((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MIN_FILTER:
			if(!texture->setMinFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAG_FILTER:
			if(!texture->setMagFilter((GLenum)param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			if(!texture->setMaxAnisotropy((GLfloat)param))
			{
				return error(GL_INVALID_VALUE);
			}
			break;
		case GL_TEXTURE_MAX_LEVEL:
			if(!texture->setMaxLevel(param))
			{
				return error(GL_INVALID_ENUM);
			}
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
{
	glTexParameteri(target, pname, *params);
}

void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
                              GLenum format, GLenum type, const GLvoid* pixels)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
	      "const GLvoid* pixels = %p)",
	      target, level, xoffset, yoffset, width, height, format, type, pixels);

	if(!gl::IsTextureTarget(target))
	{
		return error(GL_INVALID_ENUM);
	}

	if(level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
	{
		return error(GL_INVALID_VALUE);
	}

	if(!gl::CheckTextureFormatType(format, type))
	{
		return error(GL_INVALID_ENUM);
	}

	if(width == 0 || height == 0 || pixels == NULL)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(level > gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
		{
			return error(GL_INVALID_VALUE);
		}

		if(target == GL_TEXTURE_2D)
		{
			gl::Texture2D *texture = context->getTexture2D(target);

			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
			{
				texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
			}
		}
		else if(gl::IsCubemapTextureTarget(target))
		{
			gl::TextureCubeMap *texture = context->getTextureCubeMap();

			if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))
			{
				texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
			}
		}
		else UNREACHABLE(target);
	}
}

void APIENTRY glUniform1f(GLint location, GLfloat x)
{
	glUniform1fv(location, 1, &x);
}

void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(location == -1)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!program->setUniform1fv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glUniform1i(GLint location, GLint x)
{
	glUniform1iv(location, 1, &x);
}

void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(location == -1)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!program->setUniform1iv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
{
	GLfloat xy[2] = {x, y};

	glUniform2fv(location, 1, (GLfloat*)&xy);
}

void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(location == -1)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!program->setUniform2fv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glUniform2i(GLint location, GLint x, GLint y)
{
	GLint xy[4] = {x, y};

	glUniform2iv(location, 1, (GLint*)&xy);
}

void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(location == -1)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!program->setUniform2iv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
{
	GLfloat xyz[3] = {x, y, z};

	glUniform3fv(location, 1, (GLfloat*)&xyz);
}

void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(location == -1)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!program->setUniform3fv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
{
	GLint xyz[3] = {x, y, z};

	glUniform3iv(location, 1, (GLint*)&xyz);
}

void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(location == -1)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!program->setUniform3iv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
	GLfloat xyzw[4] = {x, y, z, w};

	glUniform4fv(location, 1, (GLfloat*)&xyzw);
}

void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(location == -1)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!program->setUniform4fv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
{
	GLint xyzw[4] = {x, y, z, w};

	glUniform4iv(location, 1, (GLint*)&xyzw);
}

void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
{
	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);

	if(count < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(location == -1)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!program->setUniform4iv(location, count, v))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
	      location, count, transpose, value);

	if(count < 0 || transpose != GL_FALSE)
	{
		return error(GL_INVALID_VALUE);
	}

	if(location == -1)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!program->setUniformMatrix2fv(location, count, value))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
	      location, count, transpose, value);

	if(count < 0 || transpose != GL_FALSE)
	{
		return error(GL_INVALID_VALUE);
	}

	if(location == -1)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!program->setUniformMatrix3fv(location, count, value))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
	      location, count, transpose, value);

	if(count < 0 || transpose != GL_FALSE)
	{
		return error(GL_INVALID_VALUE);
	}

	if(location == -1)
	{
		return;
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *program = context->getCurrentProgram();

		if(!program)
		{
			return error(GL_INVALID_OPERATION);
		}

		if(!program->setUniformMatrix4fv(location, count, value))
		{
			return error(GL_INVALID_OPERATION);
		}
	}
}

void APIENTRY glUseProgram(GLuint program)
{
	TRACE("(GLuint program = %d)", program);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Program *programObject = context->getProgram(program);

		if(!programObject && program != 0)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		if(program != 0 && !programObject->isLinked())
		{
			return error(GL_INVALID_OPERATION);
		}

		context->useProgram(program);
	}
}

void APIENTRY glValidateProgram(GLuint program)
{
	TRACE("(GLuint program = %d)", program);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Program *programObject = context->getProgram(program);

		if(!programObject)
		{
			if(context->getShader(program))
			{
				return error(GL_INVALID_OPERATION);
			}
			else
			{
				return error(GL_INVALID_VALUE);
			}
		}

		programObject->validate();
	}
}

void APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
{
	TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//GLfloat vals[4] = { x, 0, 0, 1 };
		context->setVertexAttrib(index, x, 0, 0, 1);
	}
}

void APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat* values)
{
	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//GLfloat vals[4] = { values[0], 0, 0, 1 };
		context->setVertexAttrib(index, values[0], 0, 0, 1);
	}
}

void APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
{
	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//GLfloat vals[4] = { x, y, 0, 1 };
		context->setVertexAttrib(index, x, y, 0, 1);
	}
}

void APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat* values)
{
	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//GLfloat vals[4] = {  };
		context->setVertexAttrib(index, values[0], values[1], 0, 1);
	}
}

void APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
{
	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//GLfloat vals[4] = { x, y, z, 1 };
		context->setVertexAttrib(index, x, y, z, 1);
	}
}

void APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat* values)
{
	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//GLfloat vals[4] = { values[0], values[1], values[2], 1 };
		context->setVertexAttrib(index, values[0], values[1], values[2], 1);
	}
}

void APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//GLfloat vals[4] = { x, y, z, w };
		context->setVertexAttrib(index, x, y, z, w);
	}
}

void APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat* values)
{
	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setVertexAttrib(index, values[0], values[1], values[2], values[3]);
	}
}

void APIENTRY glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
{
	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
	      index, size, type, normalized, stride, ptr);

	if(index >= gl::MAX_VERTEX_ATTRIBS)
	{
		return error(GL_INVALID_VALUE);
	}

	if(size < 1 || size > 4)
	{
		return error(GL_INVALID_VALUE);
	}

	switch(type)
	{
	case GL_BYTE:
	case GL_UNSIGNED_BYTE:
	case GL_SHORT:
	case GL_UNSIGNED_SHORT:
	case GL_FIXED:
	case GL_FLOAT:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if(stride < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
	}
}

void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);

	if(width < 0 || height < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setViewportParams(x, y, width, height);
	}
}

void APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                                        GLbitfield mask, GLenum filter)
{
	TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
	      "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
	      "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
	      srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);

	switch(filter)
	{
	case GL_NEAREST:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
	{
		return error(GL_INVALID_VALUE);
	}

	if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
	{
		ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
		return error(GL_INVALID_OPERATION);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		if(context->getReadFramebufferName() == context->getDrawFramebufferName())
		{
			ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
			return error(GL_INVALID_OPERATION);
		}

		context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
	}
}

void APIENTRY glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
                                 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
	      "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
	      target, level, internalformat, width, height, depth, border, format, type, pixels);

	UNIMPLEMENTED();   // FIXME
}

void WINAPI GlmfBeginGlsBlock()
{
	UNIMPLEMENTED();
}

void WINAPI GlmfCloseMetaFile()
{
	UNIMPLEMENTED();
}

void WINAPI GlmfEndGlsBlock()
{
	UNIMPLEMENTED();
}

void WINAPI GlmfEndPlayback()
{
	UNIMPLEMENTED();
}

void WINAPI GlmfInitPlayback()
{
	UNIMPLEMENTED();
}

void WINAPI GlmfPlayGlsRecord()
{
	UNIMPLEMENTED();
}

void APIENTRY glAccum(GLenum op, GLfloat value)
{
	UNIMPLEMENTED();
}

void APIENTRY glAlphaFunc(GLenum func, GLclampf ref)
{
	TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->alphaFunc(func, ref);
	}
}

GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
{
	UNIMPLEMENTED();
	return GL_FALSE;
}

void APIENTRY glArrayElement(GLint i)
{
	UNIMPLEMENTED();
}

void APIENTRY glBegin(GLenum mode)
{
	TRACE("(GLenum mode = 0x%X)", mode);
	
	switch(mode)
	{
	case GL_POINTS:
	case GL_LINES:
	case GL_LINE_STRIP:
	case GL_LINE_LOOP:
	case GL_TRIANGLES:
	case GL_TRIANGLE_STRIP:
	case GL_TRIANGLE_FAN:
	case GL_QUADS:
	case GL_QUAD_STRIP:
	case GL_POLYGON:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->begin(mode);
	}
}

void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
{
	UNIMPLEMENTED();
}

void APIENTRY glCallList(GLuint list)
{
	TRACE("(GLuint list = %d)", list);

	if(list == 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->callList(list);
	}
}

void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists)
{
	TRACE("(GLsizei n = %d, GLenum type = 0x%X, const GLvoid *lists)", n, type);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		for(int i = 0; i < n; i++)
		{
			switch(type)
			{
			case GL_UNSIGNED_INT: context->callList(((unsigned int*)lists)[i]); break;
			default:
				UNIMPLEMENTED();
				UNREACHABLE(type);
			}
		}
	}
}

void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
	UNIMPLEMENTED();
}

void APIENTRY glClearDepth(GLclampd depth)
{
	TRACE("(GLclampd depth = %d)", depth);
	
	glClearDepthf((float)depth);   // FIXME
}

void APIENTRY glClearIndex(GLfloat c)
{
	UNIMPLEMENTED();
}

void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3bv(const GLbyte *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)
{
	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f)", red, green, blue);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//context->color(red, green, blue, 1.0f);
		//GLfloat vals[4] = {};
		context->setVertexAttrib(sw::Color0, red, green, blue, 1);
	}
}

void APIENTRY glColor3fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3i(GLint red, GLint green, GLint blue)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3ubv(const GLubyte *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3uiv(const GLuint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor3usv(const GLushort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4bv(const GLbyte *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
	TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//context->color(red, green, blue, alpha);
		//GLfloat vals[4] = {red, green, blue, alpha};
		context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
	}
}

void APIENTRY glColor4fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4ubv(const GLubyte *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4uiv(const GLuint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
{
	UNIMPLEMENTED();
}

void APIENTRY glColor4usv(const GLushort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glColorMaterial(GLenum face, GLenum mode)
{
	TRACE("(GLenum face = 0x%X, GLenum mode = 0x%X)", face, mode);

	// FIXME: Validate enums

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		switch(face)
		{
		case GL_FRONT:
			context->setColorMaterialMode(mode);   // FIXME: Front only
			break;
		case GL_FRONT_AND_BACK:
			context->setColorMaterialMode(mode);
			break;
		default:
			UNIMPLEMENTED();
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
	TRACE("(*)");

	glVertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
}

void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
{
	UNIMPLEMENTED();
}

void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)
{
	UNIMPLEMENTED();
}

void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
{
	UNIMPLEMENTED();
}

void APIENTRY glDebugEntry()
{
	UNIMPLEMENTED();
}

void APIENTRY glDeleteLists(GLuint list, GLsizei range)
{
	TRACE("(GLuint list = %d, GLsizei range = %d)", list, range);

	if(range < 0)
	{
		return error(GL_INVALID_VALUE);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		for(GLuint i = list; i < list + range; i++)
		{
			context->deleteList(i);
		}
	}
}

void APIENTRY glDepthRange(GLclampd zNear, GLclampd zFar)
{
	UNIMPLEMENTED();
}

void APIENTRY glDisableClientState(GLenum array)
{
	TRACE("(GLenum array = 0x%X)", array);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		GLenum texture = context->getClientActiveTexture();

		switch(array)
		{
		case GL_VERTEX_ARRAY:        context->setVertexAttribArrayEnabled(sw::Position, false);                            break;
		case GL_COLOR_ARRAY:         context->setVertexAttribArrayEnabled(sw::Color0, false);                              break;
		case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
		case GL_NORMAL_ARRAY:        context->setVertexAttribArrayEnabled(sw::Normal, false);                              break;
		default:                     UNIMPLEMENTED();
		}
	}
}

void APIENTRY glDrawBuffer(GLenum mode)
{
	UNIMPLEMENTED();
}

void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
{
	UNIMPLEMENTED();
}

void APIENTRY glEdgeFlag(GLboolean flag)
{
	UNIMPLEMENTED();
}

void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
{
	UNIMPLEMENTED();
}

void APIENTRY glEdgeFlagv(const GLboolean *flag)
{
	UNIMPLEMENTED();
}

void APIENTRY glEnableClientState(GLenum array)
{
	TRACE("(GLenum array = 0x%X)", array);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		GLenum texture = context->getClientActiveTexture();

		switch(array)
		{
		case GL_VERTEX_ARRAY:        context->setVertexAttribArrayEnabled(sw::Position, true);                            break;
		case GL_COLOR_ARRAY:         context->setVertexAttribArrayEnabled(sw::Color0, true);                              break;
		case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
		case GL_NORMAL_ARRAY:        context->setVertexAttribArrayEnabled(sw::Normal, true);                              break;
		default:                     UNIMPLEMENTED();
		}
	}
}

void APIENTRY glEnd()
{
	TRACE("()");
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->end();
	}
}

void APIENTRY glEndList()
{
	TRACE("()");
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		context->endList();
	}
}

void APIENTRY glEvalCoord1d(GLdouble u)
{
	UNIMPLEMENTED();
}

void APIENTRY glEvalCoord1dv(const GLdouble *u)
{
	UNIMPLEMENTED();
}

void APIENTRY glEvalCoord1f(GLfloat u)
{
	UNIMPLEMENTED();
}

void APIENTRY glEvalCoord1fv(const GLfloat *u)
{
	UNIMPLEMENTED();
}

void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)
{
	UNIMPLEMENTED();
}

void APIENTRY glEvalCoord2dv(const GLdouble *u)
{
	UNIMPLEMENTED();
}

void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)
{
	UNIMPLEMENTED();
}

void APIENTRY glEvalCoord2fv(const GLfloat *u)
{
	UNIMPLEMENTED();
}

void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)
{
	UNIMPLEMENTED();
}

void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
{
	UNIMPLEMENTED();
}

void APIENTRY glEvalPoint1(GLint i)
{
	UNIMPLEMENTED();
}

void APIENTRY glEvalPoint2(GLint i, GLint j)
{
	UNIMPLEMENTED();
}

void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
{
	UNIMPLEMENTED();
}

void APIENTRY glFogf(GLenum pname, GLfloat param)
{
	TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Device *device = gl::getDevice();   // FIXME

		switch(pname)
		{
		case GL_FOG_START: device->setFogStart(param); break;
		case GL_FOG_END:   device->setFogEnd(param);   break;
		default:
			UNIMPLEMENTED();
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glFogfv(GLenum pname, const GLfloat *params)
{
	TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		switch(pname)
		{
		case GL_FOG_COLOR:
			{
				gl::Device *device = gl::getDevice();   // FIXME
				device->setFogColor(sw::Color<float>(params[0], params[1], params[2], params[3]));
			}
			break;
		default:
			UNIMPLEMENTED();
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glFogi(GLenum pname, GLint param)
{
	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		switch(pname)
		{
		case GL_FOG_MODE:
			{
				gl::Device *device = gl::getDevice();   // FIXME
				switch(param)
				{
				case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
				default:
					UNIMPLEMENTED();
					return error(GL_INVALID_ENUM);
				}
			}
			break;
		default:
			UNIMPLEMENTED();
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glFogiv(GLenum pname, const GLint *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
{
	TRACE("(GLdouble left = %f, GLdouble right = %f, GLdouble bottom = %f, GLdouble top = %f, GLdouble zNear = %f, GLdouble zFar = %f)", left, right, bottom, top, zNear, zFar);

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->frustum(left, right, bottom, top, zNear, zFar);
	}
}

GLuint APIENTRY glGenLists(GLsizei range)
{
	TRACE("(GLsizei range = %d)", range);

	if(range < 0)
	{
		return error(GL_INVALID_VALUE, 0);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		return context->genLists(range);
	}

	return 0;
}

void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetDoublev(GLenum pname, GLdouble *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetPolygonStipple(GLubyte *mask)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum format = 0x%X, GLenum type = 0x%X, GLint *pixels%p)", target, level, format, type, pixels);

	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
			texture = context->getTexture2D(target);
			break;
		case GL_TEXTURE_CUBE_MAP:
			texture = context->getTextureCubeMap();
			break;
		default:
			UNIMPLEMENTED();
			return error(GL_INVALID_ENUM);
		}

		if(format == texture->getFormat(target, level) && type == texture->getType(target, level))
		{
			gl::Image *image = texture->getRenderTarget(target, level);
			void *source = image->lock(0, 0, sw::LOCK_READONLY);
			memcpy(pixels, source, image->getPitch() * image->getHeight());
			image->unlock();
		}
		else 
		{
			UNIMPLEMENTED();
		}
	}
}

void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
{
	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLint *params = %p)", target, level, pname, params);
 
	gl::Context *context = gl::getContext();

	if(context)
	{
		gl::Texture *texture;

		switch(target)
		{
		case GL_TEXTURE_2D:
		case GL_PROXY_TEXTURE_2D:
			texture = context->getTexture2D(target);
			break;
		case GL_TEXTURE_CUBE_MAP:
			texture = context->getTextureCubeMap();
			break;
		default:
			UNIMPLEMENTED();
			return error(GL_INVALID_ENUM);
		}

		switch(pname)
		{
		case GL_TEXTURE_MAG_FILTER:
			*params = texture->getMagFilter();
			break;
		case GL_TEXTURE_MIN_FILTER:
			*params = texture->getMinFilter();
			break;
		case GL_TEXTURE_WRAP_S:
			*params = texture->getWrapS();
			break;
		case GL_TEXTURE_WRAP_T:
			*params = texture->getWrapT();
			break;
		case GL_TEXTURE_WIDTH:
			*params = texture->getWidth(target, level);
			break;
		case GL_TEXTURE_HEIGHT:
			*params = texture->getHeight(target, level);
			break;
		case GL_TEXTURE_INTERNAL_FORMAT:
				*params = texture->getInternalFormat(target, level);
			break;
		case GL_TEXTURE_BORDER_COLOR:
			UNIMPLEMENTED();
			break;
		case GL_TEXTURE_BORDER:
			UNIMPLEMENTED();
			break;
		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
			*params = (GLint)texture->getMaxAnisotropy();
			break;
		default:
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glIndexMask(GLuint mask)
{
	UNIMPLEMENTED();
}

void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
{
	UNIMPLEMENTED();
}

void APIENTRY glIndexd(GLdouble c)
{
	UNIMPLEMENTED();
}

void APIENTRY glIndexdv(const GLdouble *c)
{
	UNIMPLEMENTED();
}

void APIENTRY glIndexf(GLfloat c)
{
	UNIMPLEMENTED();
}

void APIENTRY glIndexfv(const GLfloat *c)
{
	UNIMPLEMENTED();
}

void APIENTRY glIndexi(GLint c)
{
	UNIMPLEMENTED();
}

void APIENTRY glIndexiv(const GLint *c)
{
	UNIMPLEMENTED();
}

void APIENTRY glIndexs(GLshort c)
{
	UNIMPLEMENTED();
}

void APIENTRY glIndexsv(const GLshort *c)
{
	UNIMPLEMENTED();
}

void APIENTRY glIndexub(GLubyte c)
{
	UNIMPLEMENTED();
}

void APIENTRY glIndexubv(const GLubyte *c)
{
	UNIMPLEMENTED();
}

void APIENTRY glInitNames(void)
{
	UNIMPLEMENTED();
}

void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
{
	UNIMPLEMENTED();
}

GLboolean APIENTRY glIsList(GLuint list)
{
	UNIMPLEMENTED();
	return GL_FALSE;
}

void APIENTRY glLightModelf(GLenum pname, GLfloat param)
{
	UNIMPLEMENTED();
}

void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
{
	TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Device *device = gl::getDevice();   // FIXME

		switch(pname)
		{
		case GL_LIGHT_MODEL_AMBIENT:
			device->setGlobalAmbient(sw::Color<float>(params[0], params[1], params[2], params[3]));
			break;
		default:
			UNIMPLEMENTED();
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glLightModeli(GLenum pname, GLint param)
{
	UNIMPLEMENTED();
}

void APIENTRY glLightModeliv(GLenum pname, const GLint *params)
{
	TRACE("(GLenum pname = 0x%X, const GLint *params)", pname);
	UNIMPLEMENTED();
}

void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
{
	UNIMPLEMENTED();
}

void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
{
	TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		gl::Device *device = gl::getDevice();   // FIXME

		switch(pname)
		{
		case GL_AMBIENT:  device->setLightAmbient(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3]));  break;
		case GL_DIFFUSE:  device->setLightDiffuse(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3]));  break;
		case GL_SPECULAR: device->setLightSpecular(light - GL_LIGHT0, sw::Color<float>(params[0], params[1], params[2], params[3])); break;
		case GL_POSITION:
			if(params[3] == 0.0f)   // Directional light
			{
				// Create a very far out point light
				float max = std::max(std::max(abs(params[0]), abs(params[1])), abs(params[2]));
				device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / max * 1e10f, params[1] / max * 1e10f, params[2] / max * 1e10f));
			}
			else
			{
				device->setLightPosition(light - GL_LIGHT0, sw::Point(params[0] / params[3], params[1] / params[3], params[2] / params[3]));
			}
			break;
		default:
			UNIMPLEMENTED();
			return error(GL_INVALID_ENUM);
		}
	}
}

void APIENTRY glLighti(GLenum light, GLenum pname, GLint param)
{
	UNIMPLEMENTED();
}

void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glLineStipple(GLint factor, GLushort pattern)
{
	UNIMPLEMENTED();
}

void APIENTRY glListBase(GLuint base)
{
	UNIMPLEMENTED();
}

void APIENTRY glLoadIdentity()
{
	TRACE("()");

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->loadIdentity();
	}
}

void APIENTRY glLoadMatrixd(const GLdouble *m)
{
	UNIMPLEMENTED();
}

void APIENTRY glLoadMatrixf(const GLfloat *m)
{
	UNIMPLEMENTED();
}

void APIENTRY glLoadName(GLuint name)
{
	UNIMPLEMENTED();
}

void APIENTRY glLogicOp(GLenum opcode)
{
	TRACE("(GLenum opcode = 0x%X)", opcode);

	switch(opcode)
	{
	case GL_CLEAR:
	case GL_SET:
	case GL_COPY:
	case GL_COPY_INVERTED:
	case GL_NOOP:
	case GL_INVERT:
	case GL_AND:
	case GL_NAND:
	case GL_OR:
	case GL_NOR:
	case GL_XOR:
	case GL_EQUIV:
	case GL_AND_REVERSE:
	case GL_AND_INVERTED:
	case GL_OR_REVERSE:
	case GL_OR_INVERTED:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setLogicalOperation(opcode);
	}
}

void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
{
	UNIMPLEMENTED();
}

void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
{
	UNIMPLEMENTED();
}

void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
{
	UNIMPLEMENTED();
}

void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
{
	UNIMPLEMENTED();
}

void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
{
	UNIMPLEMENTED();
}

void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
{
	UNIMPLEMENTED();
}

void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
{
	UNIMPLEMENTED();
}

void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
{
	UNIMPLEMENTED();
}

void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
{
	UNIMPLEMENTED();
}

void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)
{
	UNIMPLEMENTED();
}

void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glMatrixMode(GLenum mode)
{
	TRACE("(*)");

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setMatrixMode(mode);
	}
}

void APIENTRY glMultMatrixd(const GLdouble *m)
{
	TRACE("(*)");

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->multiply(m);
	}
}

void APIENTRY glMultMatrixm(sw::Matrix m)
{
	gl::Context *context = gl::getContext();

	if(context)
	{
		context->multiply((GLfloat*)m.m);
	}
}

void APIENTRY glMultMatrixf(const GLfloat *m)
{
	TRACE("(*)");

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			return context->listCommand(gl::newCommand(glMultMatrixm, sw::Matrix(m)));
		}

		context->multiply(m);
	}
}

void APIENTRY glNewList(GLuint list, GLenum mode)
{
	TRACE("(GLuint list = %d, GLenum mode = 0x%X)", list, mode);

	if(list == 0)
	{
		return error(GL_INVALID_VALUE);
	}

	switch(mode)
	{
	case GL_COMPILE:
	case GL_COMPILE_AND_EXECUTE:
		break;
	default:
		return error(GL_INVALID_ENUM);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->newList(list, mode);
	}
}

void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
{
	UNIMPLEMENTED();
}

void APIENTRY glNormal3bv(const GLbyte *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
{
	UNIMPLEMENTED();
}

void APIENTRY glNormal3dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
{
	TRACE("(GLfloat nx = %f, GLfloat ny = %f, GLfloat nz = %f)", nx, ny, nz);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//context->normal(nx, ny, nz);
		context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
	}
}

void APIENTRY glNormal3fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)
{
	UNIMPLEMENTED();
}

void APIENTRY glNormal3iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)
{
	UNIMPLEMENTED();
}

void APIENTRY glNormal3sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
{
	TRACE("(*)");

	glVertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
}

void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
{
	TRACE("(*)");

	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->ortho(left, right, bottom, top, zNear, zFar);
	}
}

void APIENTRY glPassThrough(GLfloat token)
{
	UNIMPLEMENTED();
}

void APIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
{
	UNIMPLEMENTED();
}

void APIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
{
	UNIMPLEMENTED();
}

void APIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
{
	UNIMPLEMENTED();
}

void APIENTRY glPixelStoref(GLenum pname, GLfloat param)
{
	UNIMPLEMENTED();
}

void APIENTRY glPixelTransferf(GLenum pname, GLfloat param)
{
	UNIMPLEMENTED();
}

void APIENTRY glPixelTransferi(GLenum pname, GLint param)
{
	UNIMPLEMENTED();
}

void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
{
	UNIMPLEMENTED();
}

void APIENTRY glPointSize(GLfloat size)
{
	UNIMPLEMENTED();
}

void APIENTRY glPolygonMode(GLenum face, GLenum mode)
{
	UNIMPLEMENTED();
}

void APIENTRY glPolygonStipple(const GLubyte *mask)
{
	UNIMPLEMENTED();
}

void APIENTRY glPopAttrib(void)
{
	UNIMPLEMENTED();
}

void APIENTRY glPopClientAttrib(void)
{
	UNIMPLEMENTED();
}

void APIENTRY glPopMatrix(void)
{
	TRACE("()");
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			return context->listCommand(gl::newCommand(glPopMatrix));
		}

		context->popMatrix();
	}
}

void APIENTRY glPopName(void)
{
	UNIMPLEMENTED();
}

void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities)
{
	UNIMPLEMENTED();
}

void APIENTRY glPushAttrib(GLbitfield mask)
{
	UNIMPLEMENTED();
}

void APIENTRY glPushClientAttrib(GLbitfield mask)
{
	UNIMPLEMENTED();
}

void APIENTRY glPushMatrix(void)
{
	TRACE("()");
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			return context->listCommand(gl::newCommand(glPushMatrix));
		}

		context->pushMatrix();
	}
}

void APIENTRY glPushName(GLuint name)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos2d(GLdouble x, GLdouble y)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos2dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos2f(GLfloat x, GLfloat y)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos2fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos2i(GLint x, GLint y)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos2iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos2s(GLshort x, GLshort y)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos2sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos3dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos3fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos3iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos3sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos4dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos4fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos4iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
{
	UNIMPLEMENTED();
}

void APIENTRY glRasterPos4sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glReadBuffer(GLenum mode)
{
	UNIMPLEMENTED();
}

void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
{
	UNIMPLEMENTED();
}

void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)
{
	UNIMPLEMENTED();
}

void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
{
	UNIMPLEMENTED();
}

void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)
{
	UNIMPLEMENTED();
}

void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)
{
	UNIMPLEMENTED();
}

void APIENTRY glRectiv(const GLint *v1, const GLint *v2)
{
	UNIMPLEMENTED();
}

void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
{
	UNIMPLEMENTED();
}

void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)
{
	UNIMPLEMENTED();
}

GLint APIENTRY glRenderMode(GLenum mode)
{
	UNIMPLEMENTED();
	return 0;
}

void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
{
	UNIMPLEMENTED();
}

void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
	TRACE("(*)");
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->rotate(angle, x, y, z);
	}
}

void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
{
	UNIMPLEMENTED();
}

void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
{
	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			return context->listCommand(gl::newCommand(glScalef, x, y, z));
		}

		context->scale(x, y, z);
	}
}

void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)
{
	UNIMPLEMENTED();
}

void APIENTRY glShadeModel(GLenum mode)
{
	TRACE("(*)");
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->setShadeModel(mode);
	}
}

void APIENTRY glTexCoord1d(GLdouble s)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord1dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord1f(GLfloat s)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord1fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord1i(GLint s)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord1iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord1s(GLshort s)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord1sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord2d(GLdouble s, GLdouble t)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord2dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
{
	TRACE("(GLfloat s = %f, GLfloat t = %f)", s, t);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//context->texCoord(s, t, 0.0f, 1.0f);
		unsigned int texture = context->getActiveTexture();
		context->setVertexAttrib(sw::TexCoord0/* + texture*/, s, t, 0.0f, 1.0f);
	}
}

void APIENTRY glTexCoord2fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord2i(GLint s, GLint t)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord2iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord2s(GLshort s, GLshort t)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord2sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord3dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord3fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord3iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord3sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord4dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord4fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord4iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoord4sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
	TRACE("(*)");

	gl::Context *context = gl::getContext();

	if(context)
	{
		GLenum texture = context->getClientActiveTexture();

		glVertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
	}
}

void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
	UNIMPLEMENTED();
}

void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
{
	UNIMPLEMENTED();
}

void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
{
	TRACE("(*)");
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			return context->listCommand(gl::newCommand(glTranslated, x, y, z));
		}

		context->translate(x, y, z);   // FIXME
	}
}

void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
{
	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			return context->listCommand(gl::newCommand(glTranslatef, x, y, z));
		}

		context->translate(x, y, z);
	}
}

void APIENTRY glVertex2d(GLdouble x, GLdouble y)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex2dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex2f(GLfloat x, GLfloat y)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex2fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex2i(GLint x, GLint y)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex2iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex2s(GLshort x, GLshort y)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex2sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex3dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
{
	TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		context->position(x, y, z, 1.0f);
	}
}

void APIENTRY glVertex3fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex3i(GLint x, GLint y, GLint z)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex3iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex3sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex4dv(const GLdouble *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex4fv(const GLfloat *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex4iv(const GLint *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertex4sv(const GLshort *v)
{
	UNIMPLEMENTED();
}

void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
	TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);

	glVertexAttribPointer(sw::Position, size, type, false, stride, pointer);
}

void APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) {UNIMPLEMENTED();}
void APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
void APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) {UNIMPLEMENTED();}
void APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {UNIMPLEMENTED();}

void APIENTRY glClientActiveTexture(GLenum texture)
{
	TRACE("(GLenum texture = 0x%X)", texture);
	
	switch(texture)
	{
	case GL_TEXTURE0:
	case GL_TEXTURE1:
		break;
	default:
		UNIMPLEMENTED();
		UNREACHABLE(texture);
	}

	gl::Context *context = gl::getContext();

	if(context)
	{
		context->clientActiveTexture(texture);
	}
}

void APIENTRY glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
void APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
void APIENTRY glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
void APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data) {UNIMPLEMENTED();}
void APIENTRY glGetCompressedTexImage(GLenum target, GLint level, void *img) {UNIMPLEMENTED();}
void APIENTRY glMultiTexCoord1f(GLenum target, GLfloat s) {UNIMPLEMENTED();}
void APIENTRY glMultiTexCoord1d(GLenum target, GLdouble s) {UNIMPLEMENTED();}

void APIENTRY glMultiTexCoord2f(GLenum texture, GLfloat s, GLfloat t)
{
	TRACE("(GLenum texture = 0x%X, GLfloat s = %f, GLfloat t = %f)", texture, s, t);
	
	gl::Context *context = gl::getContext();

	if(context)
	{
		if(context->getListIndex() != 0)
		{
			UNIMPLEMENTED();
		}

		//context->texCoord(s, t, 0.0f, 1.0f);
		context->setVertexAttrib(sw::TexCoord0 + (texture - GL_TEXTURE0), s, t, 0.0f, 1.0f);
	}
}

void APIENTRY glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t) {UNIMPLEMENTED();}
void APIENTRY glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r) {UNIMPLEMENTED();}
void APIENTRY glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r) {UNIMPLEMENTED();}
void APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {UNIMPLEMENTED();}
void APIENTRY glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) {UNIMPLEMENTED();}
void APIENTRY glLoadTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
void APIENTRY glLoadTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
void APIENTRY glMultTransposeMatrixf(const GLfloat *m) {UNIMPLEMENTED();}
void APIENTRY glMultTransposeMatrixd(const GLdouble *m) {UNIMPLEMENTED();}
void APIENTRY glFogCoordf(GLfloat coord) {UNIMPLEMENTED();}
void APIENTRY glFogCoordd(GLdouble coord) {UNIMPLEMENTED();}
void APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
void APIENTRY glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) {UNIMPLEMENTED();}
void APIENTRY glPointParameteri(GLenum pname, GLint param) {UNIMPLEMENTED();}
void APIENTRY glPointParameterf(GLenum pname, GLfloat param) {UNIMPLEMENTED();}
void APIENTRY glPointParameteriv(GLenum pname, const GLint *params) {UNIMPLEMENTED();}
void APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params) {UNIMPLEMENTED();}
void APIENTRY glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue) {UNIMPLEMENTED();}
void APIENTRY glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue) {UNIMPLEMENTED();}
void APIENTRY glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue) {UNIMPLEMENTED();}
void APIENTRY glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue) {UNIMPLEMENTED();}
void APIENTRY glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) {UNIMPLEMENTED();}
void APIENTRY glWindowPos2f(GLfloat x, GLfloat y) {UNIMPLEMENTED();}
void APIENTRY glWindowPos2d(GLdouble x, GLdouble y) {UNIMPLEMENTED();}
void APIENTRY glWindowPos2i(GLint x, GLint y) {UNIMPLEMENTED();}
void APIENTRY glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) {UNIMPLEMENTED();}
void APIENTRY glWindowPos3d(GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
void APIENTRY glWindowPos3i(GLint x, GLint y, GLint z) {UNIMPLEMENTED();}
void APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data) {UNIMPLEMENTED();}
void *APIENTRY glMapBuffer(GLenum target, GLenum access) {UNIMPLEMENTED(); return 0;}
GLboolean APIENTRY glUnmapBuffer(GLenum target) {UNIMPLEMENTED(); return GL_FALSE;}
void APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params) {UNIMPLEMENTED();}
void APIENTRY glGenQueries(GLsizei n, GLuint *ids) {UNIMPLEMENTED();}
void APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids) {UNIMPLEMENTED();}
GLboolean APIENTRY glIsQuery(GLuint id) {UNIMPLEMENTED(); return 0;}
void APIENTRY glBeginQuery(GLenum target, GLuint id) {UNIMPLEMENTED();}
void APIENTRY glEndQuery(GLenum target) {UNIMPLEMENTED();}
void APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params) {UNIMPLEMENTED();}
void APIENTRY glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) {UNIMPLEMENTED();}
void APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) {UNIMPLEMENTED();}
void APIENTRY glVertexAttrib1s(GLuint index, GLshort x) {UNIMPLEMENTED();}
void APIENTRY glVertexAttrib1d(GLuint index, GLdouble x) {UNIMPLEMENTED();}
void APIENTRY glVertexAttrib2s(GLuint index, GLshort x, GLshort y) {UNIMPLEMENTED();}
void APIENTRY glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y) {UNIMPLEMENTED();}
void APIENTRY glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z) {UNIMPLEMENTED();}
void APIENTRY glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z) {UNIMPLEMENTED();}
void APIENTRY glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) {UNIMPLEMENTED();}
void APIENTRY glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) {UNIMPLEMENTED();}
void APIENTRY glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) {UNIMPLEMENTED();}
void APIENTRY glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) {UNIMPLEMENTED();}
void APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs) {UNIMPLEMENTED();}
void APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
void APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
void APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
void APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
void APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}
void APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {UNIMPLEMENTED();}

void APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {UNIMPLEMENTED();}
void APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {UNIMPLEMENTED();}
void APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {UNIMPLEMENTED();}

BOOL WINAPI wglSwapIntervalEXT(int interval)
{
	gl::Surface *drawSurface = static_cast<gl::Surface*>(gl::getCurrentDrawSurface());

	if(drawSurface)
	{
		drawSurface->setSwapInterval(interval);
		return TRUE;
	}
	
	SetLastError(ERROR_DC_NOT_FOUND);
	return FALSE;
}

int WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd)
{
	TRACE("(*)");

	return 1;
}

BOOL WINAPI wglCopyContext(HGLRC, HGLRC, UINT)
{
	UNIMPLEMENTED();
	return FALSE;
}

HGLRC WINAPI wglCreateContext(HDC hdc)
{
	TRACE("(*)");

	gl::Display *display = gl::Display::getDisplay(hdc);
	display->initialize();

	gl::Context *context = display->createContext(nullptr);

	return (HGLRC)context;
}

HGLRC WINAPI wglCreateLayerContext(HDC, int)
{
	UNIMPLEMENTED();
	return 0;
}

BOOL WINAPI wglDeleteContext(HGLRC context)
{
	gl::Display *display = gl::getDisplay();

	if(display && context)
	{
		display->destroyContext(reinterpret_cast<gl::Context*>(context));

		return TRUE;
	}

	return FALSE;
}

BOOL WINAPI wglDescribeLayerPlane(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR)
{
	UNIMPLEMENTED();
	return FALSE;
}

int WINAPI wglDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR ppfd)
{
	TRACE("(*)");

	ASSERT(nBytes == sizeof(PIXELFORMATDESCRIPTOR));   // FIXME

	ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
	ppfd->nVersion = 1;
	ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
	ppfd->iPixelType = PFD_TYPE_RGBA;
	ppfd->cColorBits = 32;
	ppfd->cRedBits = 8;
	ppfd->cRedShift = 16;
	ppfd->cGreenBits = 8;
	ppfd->cGreenShift = 8;
	ppfd->cBlueBits = 8;
	ppfd->cBlueShift = 0;
	ppfd->cAlphaBits = 0;
	ppfd->cAlphaShift = 24;
	ppfd->cAccumBits = 0;
	ppfd->cAccumRedBits = 0;
	ppfd->cAccumGreenBits = 0;
	ppfd->cAccumBlueBits = 0;
	ppfd->cAccumAlphaBits = 0;
	ppfd->cDepthBits = 24;
	ppfd->cStencilBits = 0;
	ppfd->cAuxBuffers = 0;
	ppfd->iLayerType = 0;
	ppfd->bReserved = 0;
	ppfd->dwLayerMask = 0;
	ppfd->dwVisibleMask = 0;
	ppfd->dwDamageMask = 0;

	return 1;
}

HGLRC WINAPI wglGetCurrentContext(VOID)
{
	TRACE("(*)");
	return (HGLRC)gl::getContext();
}

HDC WINAPI wglGetCurrentDC(VOID)
{
	TRACE("(*)");
	gl::Display *display = gl::getDisplay();
	return display ? display->getNativeDisplay() : 0;
}

void WINAPI wglGetDefaultProcAddress()
{
	UNIMPLEMENTED();
}

int WINAPI wglGetLayerPaletteEntries(HDC, int, int, int, COLORREF*)
{
	UNIMPLEMENTED();
	return 0;
}

void WINAPI wglGetPixelFormat()
{
	UNIMPLEMENTED();
}

const char *WINAPI wglGetExtensionsStringARB(HDC hdc)
{
	TRACE("(*)");

	return "GL_ARB_framebuffer_object "
		   "WGL_EXT_extensions_string "
		   "WGL_EXT_swap_control";
}

const char *WINAPI wglGetExtensionsStringEXT()
{
	TRACE("(*)");
	return wglGetExtensionsStringARB(0);
}

PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)
{
	TRACE("(LPCSTR lpszProc = \"%s\")", lpszProc);

	struct Extension
	{
		const char *name;
		PROC address;
	};

	static const Extension glExtensions[] =
	{
		#define EXT(function) {#function, (PROC)function}
		
		// Core 2.1
		EXT(glDrawRangeElements),
		EXT(glTexImage3D),
		EXT(glTexSubImage3D),
		EXT(glCopyTexSubImage3D),
		EXT(glActiveTexture),
		EXT(glClientActiveTexture),
		EXT(glCompressedTexImage1D),
		EXT(glCompressedTexImage2D),
		EXT(glCompressedTexImage3D),
		EXT(glCompressedTexSubImage1D),
		EXT(glCompressedTexSubImage2D),
		EXT(glCompressedTexSubImage3D),
		EXT(glGetCompressedTexImage),
		EXT(glMultiTexCoord1f),
		EXT(glMultiTexCoord1d),
		EXT(glMultiTexCoord2f),
		EXT(glMultiTexCoord2d),
		EXT(glMultiTexCoord3f),
		EXT(glMultiTexCoord3d),
		EXT(glMultiTexCoord4f),
		EXT(glMultiTexCoord4d),
		EXT(glLoadTransposeMatrixf),
		EXT(glLoadTransposeMatrixd),
		EXT(glMultTransposeMatrixf),
		EXT(glMultTransposeMatrixd),
		EXT(glSampleCoverage),
		EXT(glBlendEquation),
		EXT(glBlendColor),
		EXT(glFogCoordf),
		EXT(glFogCoordd),
		EXT(glFogCoordPointer),
		EXT(glMultiDrawArrays),
		EXT(glPointParameteri),
		EXT(glPointParameterf),
		EXT(glPointParameteriv),
		EXT(glPointParameterfv),
		EXT(glSecondaryColor3b),
		EXT(glSecondaryColor3f),
		EXT(glSecondaryColor3d),
		EXT(glSecondaryColor3ub),
		EXT(glSecondaryColorPointer),
		EXT(glBlendFuncSeparate),
		EXT(glWindowPos2f),
		EXT(glWindowPos2d),
		EXT(glWindowPos2i),
		EXT(glWindowPos3f),
		EXT(glWindowPos3d),
		EXT(glWindowPos3i),
		EXT(glBindBuffer),
		EXT(glDeleteBuffers),
		EXT(glGenBuffers),
		EXT(glIsBuffer),
		EXT(glBufferData),
		EXT(glBufferSubData),
		EXT(glGetBufferSubData),
		EXT(glMapBuffer),
		EXT(glUnmapBuffer),
		EXT(glGetBufferParameteriv),
		EXT(glGetBufferPointerv),
		EXT(glGenQueries),
		EXT(glDeleteQueries),
		EXT(glIsQuery),
		EXT(glBeginQuery),
		EXT(glEndQuery),
		EXT(glGetQueryiv),
		EXT(glGetQueryObjectiv),
		EXT(glGetQueryObjectuiv),
		EXT(glShaderSource),
		EXT(glCreateShader),
		EXT(glIsShader),
		EXT(glCompileShader),
		EXT(glDeleteShader),
		EXT(glCreateProgram),
		EXT(glIsProgram),
		EXT(glAttachShader),
		EXT(glDetachShader),
		EXT(glLinkProgram),
		EXT(glUseProgram),
		EXT(glValidateProgram),
		EXT(glDeleteProgram),
		EXT(glUniform1f),
		EXT(glUniform2f),
		EXT(glUniform3f),
		EXT(glUniform4f),
		EXT(glUniform1i),
		EXT(glUniform2i),
		EXT(glUniform3i),
		EXT(glUniform4i),
		EXT(glUniform1fv),
		EXT(glUniform2fv),
		EXT(glUniform3fv),
		EXT(glUniform4fv),
		EXT(glUniform1iv),
		EXT(glUniform2iv),
		EXT(glUniform3iv),
		EXT(glUniform4iv),
		EXT(glUniformMatrix2fv),
		EXT(glUniformMatrix3fv),
		EXT(glUniformMatrix4fv),
		EXT(glGetShaderiv),
		EXT(glGetProgramiv),
		EXT(glGetShaderInfoLog),
		EXT(glGetProgramInfoLog),
		EXT(glGetAttachedShaders),
		EXT(glGetUniformLocation),
		EXT(glGetActiveUniform),
		EXT(glGetUniformfv),
		EXT(glGetUniformiv),
		EXT(glGetShaderSource),
		EXT(glVertexAttrib1s),
		EXT(glVertexAttrib1f),
		EXT(glVertexAttrib1d),
		EXT(glVertexAttrib2s),
		EXT(glVertexAttrib2f),
		EXT(glVertexAttrib2d),
		EXT(glVertexAttrib3s),
		EXT(glVertexAttrib3f),
		EXT(glVertexAttrib3d),
		EXT(glVertexAttrib4s),
		EXT(glVertexAttrib4f),
		EXT(glVertexAttrib4d),
		EXT(glVertexAttrib4Nub),
		EXT(glVertexAttribPointer),
		EXT(glEnableVertexAttribArray),
		EXT(glDisableVertexAttribArray),
		EXT(glGetVertexAttribfv),
		EXT(glGetVertexAttribdv),
		EXT(glGetVertexAttribiv),
		EXT(glGetVertexAttribPointerv),
		EXT(glBindAttribLocation),
		EXT(glGetActiveAttrib),
		EXT(glGetAttribLocation),
		EXT(glDrawBuffers),
		EXT(glStencilOpSeparate),
		EXT(glStencilFuncSeparate),
		EXT(glStencilMaskSeparate),
		EXT(glBlendEquationSeparate),
		EXT(glUniformMatrix2x3fv),
		EXT(glUniformMatrix3x2fv),
		EXT(glUniformMatrix2x4fv),
		EXT(glUniformMatrix4x2fv),
		EXT(glUniformMatrix3x4fv),
		EXT(glUniformMatrix4x3fv),
		EXT(glGenFencesNV),
		EXT(glDeleteFencesNV),
		EXT(glSetFenceNV),
		EXT(glTestFenceNV),
		EXT(glFinishFenceNV),
		EXT(glIsFenceNV),
		EXT(glGetFenceivNV),
	
		EXT(glIsRenderbuffer),
		EXT(glBindRenderbuffer),
		EXT(glDeleteRenderbuffers),
		EXT(glGenRenderbuffers),
		EXT(glRenderbufferStorage),
		EXT(glGetRenderbufferParameteriv),
		EXT(glIsFramebuffer),
		EXT(glBindFramebuffer),
		EXT(glDeleteFramebuffers),
		EXT(glGenFramebuffers),
		EXT(glCheckFramebufferStatus),
		EXT(glFramebufferTexture1D),
		EXT(glFramebufferTexture2D),
		EXT(glFramebufferTexture3D),
		EXT(glFramebufferRenderbuffer),
		EXT(glGetFramebufferAttachmentParameteriv),
		EXT(glGenerateMipmap),
		EXT(glReleaseShaderCompiler),
		EXT(glShaderBinary),
		EXT(glGetShaderPrecisionFormat),
		EXT(glDepthRangef),
		EXT(glClearDepthf),

		// ARB
		EXT(wglGetExtensionsStringARB),
		EXT(glIsRenderbuffer),
		EXT(glBindRenderbuffer),
		EXT(glDeleteRenderbuffers),
		EXT(glGenRenderbuffers),
		EXT(glRenderbufferStorage),
		EXT(glRenderbufferStorageMultisample),
		EXT(glGetRenderbufferParameteriv),
		EXT(glIsFramebuffer),
		EXT(glBindFramebuffer),
		EXT(glDeleteFramebuffers),
		EXT(glGenFramebuffers),
		EXT(glCheckFramebufferStatus),
		EXT(glFramebufferTexture1D),
		EXT(glFramebufferTexture2D),
		EXT(glFramebufferTexture3D),
		EXT(glFramebufferTextureLayer),
		EXT(glFramebufferRenderbuffer),
		EXT(glGetFramebufferAttachmentParameteriv),
		EXT(glBlitFramebuffer),
		EXT(glGenerateMipmap),

		// EXT
		EXT(wglSwapIntervalEXT),
		EXT(wglGetExtensionsStringEXT),
		#undef EXT
	};

	for(int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
	{
		if(strcmp(lpszProc, glExtensions[ext].name) == 0)
		{
			return (PROC)glExtensions[ext].address;
		}
	}

	FARPROC proc = GetProcAddress(GetModuleHandle("opengl32.dll"), lpszProc);  // FIXME?

	if(proc)
	{
		return proc;
	}

	TRACE("(LPCSTR lpszProc = \"%s\") NOT FOUND!!!", lpszProc);

	return 0;
}

BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
{
	TRACE("(*)");

	if(hdc && hglrc)
	{
		gl::Display *display = (gl::Display*)gl::Display::getDisplay(hdc);
		gl::makeCurrent((gl::Context*)hglrc, display, display->getPrimarySurface());
		gl::setCurrentDrawSurface(display->getPrimarySurface());
		gl::setCurrentDisplay(display);
	}
	else
	{
		gl::makeCurrent(0, 0, 0);
	}

	return TRUE;
}

BOOL WINAPI wglRealizeLayerPalette(HDC, int, BOOL)
{
	UNIMPLEMENTED();
	return FALSE;
}

int WINAPI wglSetLayerPaletteEntries(HDC, int, int, int, CONST COLORREF*)
{
	UNIMPLEMENTED();
	return 0;
}

BOOL WINAPI wglSetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd)
{
	TRACE("(*)");
	//UNIMPLEMENTED();

	return TRUE;
}

BOOL WINAPI wglShareLists(HGLRC, HGLRC)
{
	UNIMPLEMENTED();
	return FALSE;
}

BOOL WINAPI wglSwapBuffers(HDC hdc)
{
	TRACE("(*)");
	
	gl::Display *display = gl::getDisplay();
	
	if(display)
	{
		display->getPrimarySurface()->swap();
		return TRUE;
	}

	return FALSE;
}

BOOL WINAPI wglSwapLayerBuffers(HDC, UINT)
{
	UNIMPLEMENTED();
	return FALSE;
}

DWORD WINAPI wglSwapMultipleBuffers(UINT, CONST WGLSWAP*)
{
	UNIMPLEMENTED();
	return 0;
}

BOOL WINAPI wglUseFontBitmapsA(HDC, DWORD, DWORD, DWORD)
{
	UNIMPLEMENTED();
	return FALSE;
}

BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD)
{
	UNIMPLEMENTED();
	return FALSE;
}

BOOL WINAPI wglUseFontOutlinesA(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
{
	UNIMPLEMENTED();
	return FALSE;
}

BOOL WINAPI wglUseFontOutlinesW(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)
{
	UNIMPLEMENTED();
	return FALSE;
}

void APIENTRY Register(const char *licenseKey)
{
	RegisterLicenseKey(licenseKey);
}

}
