Explorar o código

GLES files updated and EGLContext implemented

mikymod %!s(int64=12) %!d(string=hai) anos
pai
achega
1cce99d1eb

+ 55 - 46
src/renderers/gles/GLESRenderer.cpp

@@ -47,7 +47,30 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 namespace crown
 {
+//-----------------------------------------------------------------------------
+static const char* gl_error_to_string(GLenum error)
+{
+	switch (error)
+	{
+		case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
+		case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
+		case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
+		case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
+		default: return "UNKNOWN_GL_ERROR";
+	}
+}
 
+//-----------------------------------------------------------------------------
+#ifdef CROWN_DEBUG
+	#define GL_CHECK(function)\
+		function;\
+		do { GLenum error; CE_ASSERT((error = glGetError()) == GL_NO_ERROR,\
+				"OpenGL error: %s", gl_error_to_string(error)); } while (0)
+#else
+	#define GL_CHECK(function)\
+		function;
+#endif
+		
 //-----------------------------------------------------------------------------
 GLESRenderer::GLESRenderer() :
 	m_max_texture_size(0),
@@ -205,7 +228,7 @@ VertexBufferId GLESRenderer::create_dynamic_vertex_buffer(size_t count, VertexFo
 //-----------------------------------------------------------------------------
 void GLESRenderer::update_vertex_buffer(VertexBufferId id, size_t offset, size_t count, const void* vertices)
 {
-	assert(m_vertex_buffers_id_table.has(id));
+	CE_ASSERT(m_vertex_buffers_id_table.has(id), "VertexBuffers table does not have vertex buffer %d", id);
 
 	VertexBuffer& buffer = m_vertex_buffers[id.index];
 
@@ -217,7 +240,7 @@ void GLESRenderer::update_vertex_buffer(VertexBufferId id, size_t offset, size_t
 //-----------------------------------------------------------------------------
 void GLESRenderer::destroy_vertex_buffer(VertexBufferId id)
 {
-	assert(m_vertex_buffers_id_table.has(id));
+	CE_ASSERT(m_vertex_buffers_id_table.has(id), "VertexBuffers table does not have vertex buffer %d", id);
 
 	VertexBuffer& buffer = m_vertex_buffers[id.index];
 
@@ -246,7 +269,7 @@ IndexBufferId GLESRenderer::create_index_buffer(size_t count, const void* indice
 //-----------------------------------------------------------------------------
 void GLESRenderer::destroy_index_buffer(IndexBufferId id)
 {
-	assert(m_index_buffers_id_table.has(id));
+	CE_ASSERT(m_index_buffers_id_table.has(id), "IndexBuffers table does not have index buffer %d", id);
 
 	IndexBuffer& buffer = m_index_buffers[id.index];
 
@@ -280,7 +303,7 @@ TextureId GLESRenderer::create_texture(uint32_t width, uint32_t height, PixelFor
 //-----------------------------------------------------------------------------
 void GLESRenderer::update_texture(TextureId id, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const void* data)
 {
-	assert(m_textures_id_table.has(id));
+	CE_ASSERT(m_textures_id_table.has(id), "Textures table does not have texture %d", id);
 
 	Texture& gl_texture = m_textures[id.index];
 
@@ -293,7 +316,7 @@ void GLESRenderer::update_texture(TextureId id, uint32_t x, uint32_t y, uint32_t
 //-----------------------------------------------------------------------------
 void GLESRenderer::destroy_texture(TextureId id)
 {
-	assert(m_textures_id_table.has(id));
+	CE_ASSERT(m_textures_id_table.has(id), "Textures table does not have texture %d", id);
 
 	Texture& gl_texture = m_textures[id.index];
 
@@ -303,7 +326,7 @@ void GLESRenderer::destroy_texture(TextureId id)
 //-----------------------------------------------------------------------------
 VertexShaderId GLESRenderer::create_vertex_shader(const char* program)
 {
-	assert(program != NULL);
+	CE_ASSERT(program != NULL, "Vertex shader can not be null");
 
 	const VertexShaderId& id = m_vertex_shaders_id_table.create();
 
@@ -326,7 +349,7 @@ VertexShaderId GLESRenderer::create_vertex_shader(const char* program)
 
 		Log::e("Vertex shader compilation failed.");
 		Log::e("Log: %s", info_log);
-		assert(0);
+		CE_ASSERT(0, "");
 	}
 
 	return id;
@@ -335,7 +358,7 @@ VertexShaderId GLESRenderer::create_vertex_shader(const char* program)
 //-----------------------------------------------------------------------------
 void GLESRenderer::destroy_vertex_shader(VertexShaderId id)
 {
-	assert(m_vertex_shaders_id_table.has(id));
+	CE_ASSERT(m_vertex_shaders_id_table.has(id), "Vertex shaders table does not have vertex shader %d", id);
 
 	VertexShader& gl_shader = m_vertex_shaders[id.index];
 
@@ -345,7 +368,7 @@ void GLESRenderer::destroy_vertex_shader(VertexShaderId id)
 //-----------------------------------------------------------------------------
 PixelShaderId GLESRenderer::create_pixel_shader(const char* program)
 {
-	assert(program != NULL);
+	CE_ASSERT(program != NULL, "Pixel Shader can not be null");
 
 	const PixelShaderId& id = m_pixel_shaders_id_table.create();
 
@@ -368,7 +391,7 @@ PixelShaderId GLESRenderer::create_pixel_shader(const char* program)
 
 		Log::e("Pixel shader compilation failed.");
 		Log::e("Log: %s", info_log);
-		assert(0);
+		CE_ASSERT(0, "");
 	}
 
 	return id;	
@@ -377,7 +400,7 @@ PixelShaderId GLESRenderer::create_pixel_shader(const char* program)
 //-----------------------------------------------------------------------------
 void GLESRenderer::destroy_pixel_shader(PixelShaderId id)
 {
-	assert(m_pixel_shaders_id_table.has(id));
+	CE_ASSERT(m_pixel_shaders_id_table.has(id),  "Pixel shaders table does not have pixel shader %d", id);
 
 	PixelShader& gl_shader = m_pixel_shaders[id.index];
 
@@ -387,8 +410,8 @@ void GLESRenderer::destroy_pixel_shader(PixelShaderId id)
 //-----------------------------------------------------------------------------
 GPUProgramId GLESRenderer::create_gpu_program(VertexShaderId vs, PixelShaderId ps)
 {
-	assert(m_vertex_shaders_id_table.has(vs));
-	assert(m_pixel_shaders_id_table.has(ps));
+	CE_ASSERT(m_vertex_shaders_id_table.has(vs), "Vertex shaders table does not have vertex shader %d", vs);
+	CE_ASSERT(m_pixel_shaders_id_table.has(ps), "Pixel shaders table does not have pixel shader %d", ps);
 
 	const GPUProgramId id = m_gpu_programs_id_table.create();
 
@@ -414,6 +437,7 @@ GPUProgramId GLESRenderer::create_gpu_program(VertexShaderId vs, PixelShaderId p
 		glGetProgramInfoLog(gl_program.gl_object, 256, NULL, info_log);
 		Log::e("GPU program compilation failed.\n");
 		Log::e("Log: %s", info_log);
+		CE_ASSERT(0, "");
 	}
 
 	return id;
@@ -422,7 +446,7 @@ GPUProgramId GLESRenderer::create_gpu_program(VertexShaderId vs, PixelShaderId p
 //-----------------------------------------------------------------------------
 void GLESRenderer::destroy_gpu_program(GPUProgramId id)
 {
-	assert(m_gpu_programs_id_table.has(id));
+	CE_ASSERT(m_gpu_programs_id_table.has(id), "GPU programs table does not have gpu program %d", id);
 
 	GPUProgram& gl_program = m_gpu_programs[id.index];
 
@@ -432,7 +456,7 @@ void GLESRenderer::destroy_gpu_program(GPUProgramId id)
 //-----------------------------------------------------------------------------
 void GLESRenderer::set_gpu_program_bool_uniform(GPUProgramId id, const char* name, bool value)
 {
-	assert(m_gpu_programs_id_table.has(id));
+	CE_ASSERT(m_gpu_programs_id_table.has(id), "GPU programs table does not have gpu program %d", id);
 
 	const GLint uniform = find_gpu_program_uniform(m_gpu_programs[id.index].gl_object, name);
 
@@ -442,7 +466,7 @@ void GLESRenderer::set_gpu_program_bool_uniform(GPUProgramId id, const char* nam
 //-----------------------------------------------------------------------------
 void GLESRenderer::set_gpu_program_int_uniform(GPUProgramId id, const char* name, int value)
 {
-	assert(m_gpu_programs_id_table.has(id));
+	CE_ASSERT(m_gpu_programs_id_table.has(id), "GPU programs table does not have gpu program %d", id);
 
 	const GLint uniform = find_gpu_program_uniform(m_gpu_programs[id.index].gl_object, name);
 
@@ -452,7 +476,7 @@ void GLESRenderer::set_gpu_program_int_uniform(GPUProgramId id, const char* name
 //-----------------------------------------------------------------------------
 void GLESRenderer::set_gpu_program_vec2_uniform(GPUProgramId id, const char* name, const Vec2& value)
 {
-	assert(m_gpu_programs_id_table.has(id));
+	CE_ASSERT(m_gpu_programs_id_table.has(id), "GPU programs table does not have gpu program %d", id);
 
 	const GLint uniform = find_gpu_program_uniform(m_gpu_programs[id.index].gl_object, name);
 
@@ -462,7 +486,7 @@ void GLESRenderer::set_gpu_program_vec2_uniform(GPUProgramId id, const char* nam
 //-----------------------------------------------------------------------------
 void GLESRenderer::set_gpu_program_vec3_uniform(GPUProgramId id, const char* name, const Vec3& value)
 {
-	assert(m_gpu_programs_id_table.has(id));
+	CE_ASSERT(m_gpu_programs_id_table.has(id), "GPU programs table does not have gpu program %d", id);
 
 	const GLint uniform = find_gpu_program_uniform(m_gpu_programs[id.index].gl_object, name);
 
@@ -472,7 +496,7 @@ void GLESRenderer::set_gpu_program_vec3_uniform(GPUProgramId id, const char* nam
 //-----------------------------------------------------------------------------
 void GLESRenderer::set_gpu_program_vec4_uniform(GPUProgramId id, const char* name, const Vec4& value)
 {
-	assert(m_gpu_programs_id_table.has(id));
+	CE_ASSERT(m_gpu_programs_id_table.has(id), "GPU programs table does not have gpu program %d", id);
 
 	const GLint uniform = find_gpu_program_uniform(m_gpu_programs[id.index].gl_object, name);
 
@@ -482,7 +506,7 @@ void GLESRenderer::set_gpu_program_vec4_uniform(GPUProgramId id, const char* nam
 //-----------------------------------------------------------------------------
 void GLESRenderer::set_gpu_porgram_mat3_uniform(GPUProgramId id, const char* name, const Mat3& value)
 {
-	assert(m_gpu_programs_id_table.has(id));
+	CE_ASSERT(m_gpu_programs_id_table.has(id), "GPU programs table does not have gpu program %d", id);
 
 	const GLint uniform = find_gpu_program_uniform(m_gpu_programs[id.index].gl_object, name);
 
@@ -492,7 +516,7 @@ void GLESRenderer::set_gpu_porgram_mat3_uniform(GPUProgramId id, const char* nam
 //-----------------------------------------------------------------------------
 void GLESRenderer::set_gpu_program_mat4_uniform(GPUProgramId id, const char* name, const Mat4& value)
 {
-	assert(m_gpu_programs_id_table.has(id));
+	CE_ASSERT(m_gpu_programs_id_table.has(id), "GPU programs table does not have gpu program %d", id);
 
 	const GLint uniform = find_gpu_program_uniform(m_gpu_programs[id.index].gl_object, name);
 
@@ -502,7 +526,7 @@ void GLESRenderer::set_gpu_program_mat4_uniform(GPUProgramId id, const char* nam
 //-----------------------------------------------------------------------------
 void GLESRenderer::set_gpu_program_sampler_uniform(GPUProgramId id, const char* name, uint32_t value)
 {
-	assert(m_gpu_programs_id_table.has(id));
+	CE_ASSERT(m_gpu_programs_id_table.has(id), "GPU programs table does not have gpu program %d", id);
 
 	const GLint uniform = find_gpu_program_uniform(m_gpu_programs[id.index].gl_object, name);
 
@@ -512,7 +536,7 @@ void GLESRenderer::set_gpu_program_sampler_uniform(GPUProgramId id, const char*
 //-----------------------------------------------------------------------------
 void GLESRenderer::bind_gpu_program(GPUProgramId id) const
 {
-	assert(m_gpu_programs_id_table.has(id));
+	CE_ASSERT(m_gpu_programs_id_table.has(id), "GPU programs table does not have gpu program %d", id);
 
 	const GPUProgram& gl_program = m_gpu_programs[id.index];
 
@@ -573,7 +597,7 @@ void GLESRenderer::set_ambient_light(const Color4& color)
 //-----------------------------------------------------------------------------
 void GLESRenderer::bind_texture(uint32_t unit, TextureId texture)
 {
-	assert(m_textures_id_table.has(texture));
+	CE_ASSERT(m_textures_id_table.has(texture), "Textures table does not have texture %d", texture);
 
 	if (!activate_texture_unit(unit))
 	{
@@ -817,7 +841,7 @@ void GLESRenderer::set_matrix(MatrixType type, const Mat4& matrix)
 		default:
 		{
 			break;
-			assert(0);
+			CE_ASSERT(0, "");
 		}
 	}
 }
@@ -825,26 +849,11 @@ void GLESRenderer::set_matrix(MatrixType type, const Mat4& matrix)
 //-----------------------------------------------------------------------------
 void GLESRenderer::bind_vertex_buffer(VertexBufferId vb) const
 {
-<<<<<<< HEAD
-<<<<<<< HEAD
-	assert(m_vertex_buffers_id_table.has(vb));
-=======
-	ce_assert(vertices != NULL);
-	ce_assert(indices != NULL);
-=======
-	CE_ASSERT(vertices != NULL);
-	CE_ASSERT(indices != NULL);
->>>>>>> master
-
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_NORMAL_ARRAY);
-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-	glEnableClientState(GL_COLOR_ARRAY);
->>>>>>> master
+	CE_ASSERT(m_vertex_buffers_id_table.has(vb), "Vertex buffers table does not have vertex buffer %d", vb);
 
 	const VertexBuffer& vertex_buffer = m_vertex_buffers[vb.index];
 
-	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer.gl_object);
+	GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer.gl_object));
 
 	switch (vertex_buffer.format)
 	{
@@ -884,7 +893,7 @@ void GLESRenderer::bind_vertex_buffer(VertexBufferId vb) const
 		}
 		default:
 		{
-			assert(0);
+			CE_ASSERT(0, "");
 			break;
 		}
 	}
@@ -893,7 +902,7 @@ void GLESRenderer::bind_vertex_buffer(VertexBufferId vb) const
 //-----------------------------------------------------------------------------
 void GLESRenderer::draw_triangles(IndexBufferId id) const
 {
-	assert(m_index_buffers_id_table.has(id));
+	CE_ASSERT(m_index_buffers_id_table.has(id), "Index buffers table does not have index buffer %d", id);
 
 	const IndexBuffer& index_buffer = m_index_buffers[id.index];
 
@@ -905,7 +914,7 @@ void GLESRenderer::draw_triangles(IndexBufferId id) const
 //-----------------------------------------------------------------------------
 // void GLESRenderer::bind_render_buffer(RenderBufferId id) const
 // {
-// 	assert(m_render_buffers_id_table.has(id));
+// 	CE_ASSERT(m_render_buffers_id_table.has(id));
 
 // 	const GLRenderBuffer& render_buffer = m_render_buffers[id.index];
 // }
@@ -997,7 +1006,7 @@ GLint GLESRenderer::find_gpu_program_uniform(GLuint program, const char* name) c
 {
 	GLint uniform = glGetUniformLocation(program, name);
 
-	assert(uniform != -1);
+	CE_ASSERT(uniform != -1, "Uniform not found in GPU program %d", program);
 
 	return uniform;
 }

+ 2 - 2
src/renderers/gles/GLESRenderer.h

@@ -36,7 +36,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "VertexShader.h"
 #include "PixelShader.h"
 #include "IdTable.h"
-#include "MallocAllocator.h"
+#include "HeapAllocator.h"
 #include "Resource.h"
 
 namespace crown
@@ -208,7 +208,7 @@ private:
 
 private:
 
-	MallocAllocator		m_allocator;
+	HeapAllocator		m_allocator;
 
 	// Matrices
 	Mat4				m_matrix[MT_COUNT];

+ 6 - 30
src/renderers/gles/GLESUtils.h

@@ -26,14 +26,8 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
-<<<<<<< HEAD
 #include <GLES2/gl2.h>
-#include <cassert>
-
-=======
-#include <GLES/gl.h>
 #include "Assert.h"
->>>>>>> master
 #include "Texture.h"
 #include "Material.h"
 #include "PixelFormat.h"
@@ -70,7 +64,7 @@ private:
 //-----------------------------------------------------------------------------
 inline GLenum GLES::compare_function(CompareFunction function)
 {
-	CE_ASSERT(function < CF_COUNT);
+	CE_ASSERT(function < CF_COUNT, "Compare function not supported");
 
 	return COMPARE_FUNCTION_TABLE[function];
 }
@@ -78,7 +72,7 @@ inline GLenum GLES::compare_function(CompareFunction function)
 //-----------------------------------------------------------------------------
 inline GLenum GLES::blend_function(BlendFunction function)
 {
-	CE_ASSERT(function < BF_COUNT);
+	CE_ASSERT(function < BF_COUNT, "Blend function not supported");
 
 	return BLEND_FUNCTION_TABLE[function];
 }
@@ -86,15 +80,8 @@ inline GLenum GLES::blend_function(BlendFunction function)
 //-----------------------------------------------------------------------------
 inline GLenum GLES::blend_equation(BlendEquation equation)
 {
-<<<<<<< HEAD
-<<<<<<< HEAD
-	assert(equation < BE_COUNT);
-=======
-	ce_assert(mode < TM_COUNT);
->>>>>>> master
-=======
-	CE_ASSERT(mode < TM_COUNT);
->>>>>>> master
+
+	CE_ASSERT(equation < BE_COUNT, "Blend equation not supported");
 
 	return BLEND_EQUATION_TABLE[equation];
 }
@@ -102,7 +89,7 @@ inline GLenum GLES::blend_equation(BlendEquation equation)
 //-----------------------------------------------------------------------------
 inline GLenum GLES::texture_wrap(TextureWrap wrap)
 {
-	CE_ASSERT(wrap < TW_COUNT);
+	CE_ASSERT(wrap < TW_COUNT, "Texture wrapper not supported");
 
 	return TEXTURE_WRAP_TABLE[wrap];
 }
@@ -110,24 +97,13 @@ inline GLenum GLES::texture_wrap(TextureWrap wrap)
 //-----------------------------------------------------------------------------
 inline void GLES::texture_filter(TextureFilter filter, GLint& minFilter, GLint& magFilter)
 {
-	CE_ASSERT(filter < TF_COUNT);
+	CE_ASSERT(filter < TF_COUNT, "Texture filter not supported");
 
 	minFilter = TEXTURE_MIN_FILTER_TABLE[filter];
 	magFilter = TEXTURE_MAG_FILTER_TABLE[filter];
 }
 
 //-----------------------------------------------------------------------------
-<<<<<<< HEAD
-=======
-inline GLenum GLES::fog_mode(FogMode mode)
-{
-	CE_ASSERT(mode < FM_COUNT);
-
-	return FOG_MODE_TABLE[mode];
-}
-
-//-----------------------------------------------------------------------------
->>>>>>> master
 inline GLenum GLES::pixel_format(PixelFormat format)
 {
 	switch (format)

+ 97 - 0
src/renderers/gles/egl/GLContext.cpp

@@ -0,0 +1,97 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <GLES2/gl2.h>
+
+#include "GLContext.h"
+
+namespace crown
+{
+
+static ANativeWindow* awindow = NULL;
+
+//-----------------------------------------------------------------------------
+void set_android_window(ANativeWindow* window)
+{
+	awindow = window;
+}
+
+//-----------------------------------------------------------------------------
+GLContext::GLContext() :
+	num_configs(0)
+{
+}
+
+//-----------------------------------------------------------------------------
+void GLContext::create_context()
+{
+	EGLint format;
+
+	// Screen format rgbx8888 with no alpha channel,
+	// maybe it is wrong but is for testing
+	EGLint attrib_list[]= { EGL_RED_SIZE,        8,
+                            EGL_GREEN_SIZE,      8,
+                            EGL_BLUE_SIZE,       8,
+                            EGL_SURFACE_TYPE,    EGL_WINDOW_BIT,
+                            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                            EGL_NONE};
+
+    EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+
+    display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+    eglInitialize(display, NULL, NULL);
+
+    eglBindAPI(EGL_OPENGL_ES_API);
+
+    eglChooseConfig(display, attrib_list, &config, 1, &num_configs);
+
+	eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
+
+	ANativeWindow_setBuffersGeometry(awindow, 0, 0, format);
+
+    context = eglCreateContext(display, config, EGL_NO_CONTEXT, attributes);
+
+	surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)awindow, NULL);
+
+    eglMakeCurrent(display, surface, surface, context);
+}
+
+//-----------------------------------------------------------------------------
+void GLContext::destroy_context()
+{
+ 	eglDestroyContext(display, context);
+ 	eglDestroySurface(display, surface);
+ 	eglTerminate(display);
+}
+
+//-----------------------------------------------------------------------------
+void GLContext::swap_buffers()
+{
+   	eglSwapBuffers(display, surface);
+}
+
+}

+ 57 - 0
src/renderers/gles/egl/GLContext.h

@@ -0,0 +1,57 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include <EGL/egl.h>
+#include <android/native_window.h>
+
+namespace crown
+{
+
+void set_android_window(ANativeWindow* window);
+
+class GLContext
+{
+public:
+					GLContext();
+
+	void			create_context();
+	void			destroy_context();
+
+	void			swap_buffers();
+
+private:
+
+	EGLDisplay 		display;
+    EGLSurface 		surface;
+    EGLConfig 		config;
+    EGLContext 		context;
+
+    int32_t			num_configs;
+};
+
+} // namespace crown