diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index 6b59825a82..80d6c3d864 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -7,7 +7,7 @@
android:sharedUserId="com.mapswithme"
android:sharedUserLabel="@string/app_name">
-
+
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
index 091259ec19..05c0a15cd9 100644
--- a/android/jni/Android.mk
+++ b/android/jni/Android.mk
@@ -45,7 +45,7 @@ LOCAL_SRC_FILES := \
nv_event/nv_event.cpp \
nv_time/nv_time.cpp
-LOCAL_LDLIBS := -llog -lGLESv1_CM \
+LOCAL_LDLIBS := -llog -lGLESv2 \
-lmap -lversion -lsearch -lstorage -lindexer -lyg -lplatform \
-lgeometry -lcoding -lbase -lexpat -lfreetype -lfribidi -lzlib -lbzip2 \
-ljansson -ltomcrypt -lprotobuf ./obj/local/$(TARGET_ARCH_ABI)/libgnustl_static.a
diff --git a/android/jni/com/mapswithme/platform/Platform.cpp b/android/jni/com/mapswithme/platform/Platform.cpp
index 08c3c4cb78..8c978c6f64 100644
--- a/android/jni/com/mapswithme/platform/Platform.cpp
+++ b/android/jni/com/mapswithme/platform/Platform.cpp
@@ -28,12 +28,8 @@ public:
m_tileSize = min(max(ceiledScreenSize / 2, (size_t)128), (size_t)512);
- double k = (256.0 / m_tileSize) * (256.0 / m_tileSize);
-
LOG(LINFO, ("tileSize=", m_tileSize));
- /// calculating how much tiles we need for the screen of such size
-
m_preCachingDepth = 3;
switch (densityDpi)
diff --git a/android/src/com/nvidia/devtech/NvEventQueueActivity.java b/android/src/com/nvidia/devtech/NvEventQueueActivity.java
index 6aa760ff63..d620797d62 100644
--- a/android/src/com/nvidia/devtech/NvEventQueueActivity.java
+++ b/android/src/com/nvidia/devtech/NvEventQueueActivity.java
@@ -24,6 +24,8 @@ import android.view.SurfaceHolder.Callback;
public abstract class NvEventQueueActivity extends Activity
{
private static final String TAG = "NvEventQueueActivity";
+ private static final int EGL_RENDERABLE_TYPE = 0x3040;
+ private static final int EGL_OPENGL_ES2_BIT = 0x0004;
private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
private EGL10 m_egl = (EGL10) EGLContext.getEGL();
@@ -414,6 +416,7 @@ public abstract class NvEventQueueActivity extends Activity
EGL11.EGL_ALPHA_SIZE, alphaSize,
EGL11.EGL_STENCIL_SIZE, stencilSize,
EGL11.EGL_DEPTH_SIZE, depthSize,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL11.EGL_NONE };
m_eglDisplay = m_egl.eglGetDisplay(EGL11.EGL_DEFAULT_DISPLAY);
@@ -446,19 +449,30 @@ public abstract class NvEventQueueActivity extends Activity
m_choosenConfigIndex = 0;
- m_eglConfig = m_configs[m_choosenConfigIndex];
-
- // Debug print
- Log.d(TAG, "Matched egl configs:");
- for (int i = 0; i < m_actualConfigsNumber[0]; ++i)
- Log.d(TAG, (i == m_choosenConfigIndex ? "*" : " ") + i + ": " + eglConfigToString(m_configs[i]));
-
- final int[] contextAttrs = new int[] { EGL_CONTEXT_CLIENT_VERSION, 1, EGL11.EGL_NONE };
- m_eglContext = m_egl.eglCreateContext(m_eglDisplay, m_eglConfig, EGL11.EGL_NO_CONTEXT, contextAttrs);
- if (m_eglContext == EGL11.EGL_NO_CONTEXT)
+ while (true)
{
- Log.d(TAG, "eglCreateContext failed with error " + m_egl.eglGetError());
- return false;
+ m_eglConfig = m_configs[m_choosenConfigIndex];
+
+ // Debug print
+ Log.d(TAG, "Matched egl configs:");
+ for (int i = 0; i < m_actualConfigsNumber[0]; ++i)
+ Log.d(TAG, (i == m_choosenConfigIndex ? "*" : " ") + i + ": " + eglConfigToString(m_configs[i]));
+
+ final int[] contextAttrs = new int[] { EGL_CONTEXT_CLIENT_VERSION, 2, EGL11.EGL_NONE };
+ m_eglContext = m_egl.eglCreateContext(m_eglDisplay, m_eglConfig, EGL11.EGL_NO_CONTEXT, contextAttrs);
+ if (m_eglContext == EGL11.EGL_NO_CONTEXT)
+ {
+ Log.d(TAG, "eglCreateContext failed with error " + m_egl.eglGetError());
+ m_choosenConfigIndex++;
+ }
+ else
+ break;
+
+ if (m_choosenConfigIndex == m_configs.length)
+ {
+ Log.d(TAG, "No more configs left to choose");
+ return false;
+ }
}
m_eglInitialized = true;
@@ -570,7 +584,7 @@ public abstract class NvEventQueueActivity extends Activity
m_egl.eglDestroyContext(m_eglDisplay, m_eglContext);
// recreating context with same eglConfig as eglWindowSurface has
- final int[] contextAttrs = new int[] { EGL_CONTEXT_CLIENT_VERSION, 1, EGL11.EGL_NONE };
+ final int[] contextAttrs = new int[] { EGL_CONTEXT_CLIENT_VERSION, 2, EGL11.EGL_NONE };
m_eglContext = m_egl.eglCreateContext(m_eglDisplay, m_configs[choosenSurfaceConfigIndex], EGL11.EGL_NO_CONTEXT, contextAttrs);
if (m_eglContext == EGL11.EGL_NO_CONTEXT)
{
diff --git a/iphone/Maps/Classes/RenderContext.mm b/iphone/Maps/Classes/RenderContext.mm
index b29a47e5e1..6677de0a41 100644
--- a/iphone/Maps/Classes/RenderContext.mm
+++ b/iphone/Maps/Classes/RenderContext.mm
@@ -13,12 +13,12 @@ namespace iphone
{
RenderContext::RenderContext()
{
- m_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
+ m_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
}
RenderContext::RenderContext(RenderContext * renderContext)
{
- m_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1 sharegroup:renderContext->m_context.sharegroup];
+ m_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:renderContext->m_context.sharegroup];
}
RenderContext::~RenderContext()
diff --git a/map/coverage_generator.cpp b/map/coverage_generator.cpp
index 60a7a900d5..a11637231a 100644
--- a/map/coverage_generator.cpp
+++ b/map/coverage_generator.cpp
@@ -28,7 +28,8 @@ CoverageGenerator::CoverageGenerator(
g_coverageGeneratorDestroyed = false;
m_resourceManager = rm;
- m_renderContext = primaryRC->createShared();
+ if (!glQueue)
+ m_renderContext = primaryRC->createShared();
m_currentStylesCache.reset(new yg::ResourceStyleCache(rm,
rm->cacheThreadGlyphCacheID(),
@@ -46,12 +47,14 @@ CoverageGenerator::CoverageGenerator(
void CoverageGenerator::InitializeThreadGL()
{
- m_renderContext->makeCurrent();
+ if (m_renderContext)
+ m_renderContext->makeCurrent();
}
void CoverageGenerator::FinalizeThreadGL()
{
- m_renderContext->endThreadDrawing();
+ if (m_renderContext)
+ m_renderContext->endThreadDrawing();
}
CoverageGenerator::~CoverageGenerator()
diff --git a/map/qgl_render_context.cpp b/map/qgl_render_context.cpp
index cca74bcff3..d465c0b53c 100644
--- a/map/qgl_render_context.cpp
+++ b/map/qgl_render_context.cpp
@@ -40,6 +40,7 @@ namespace qt
void RenderContext::endThreadDrawing()
{
m_context.reset();
+ yg::gl::RenderContext::endThreadDrawing();
}
RenderContext::RenderContext(RenderContext * renderContext)
diff --git a/map/render_policy.cpp b/map/render_policy.cpp
index 44ca09b31a..2bec92ecc9 100644
--- a/map/render_policy.cpp
+++ b/map/render_policy.cpp
@@ -7,6 +7,7 @@
#include "window_handle.hpp"
#include "test_render_policy.hpp"
#include "basic_render_policy.hpp"
+#include "simple_render_policy.hpp"
#include "render_policy_st.hpp"
#include "render_policy_mt.hpp"
#include "tiling_render_policy_st.hpp"
@@ -26,6 +27,7 @@ RenderPolicy::~RenderPolicy()
{
LOG(LDEBUG, ("clearing cached drawing rules"));
drule::rules().ClearCaches();
+ yg::gl::FinalizeThread();
}
RenderPolicy::RenderPolicy(shared_ptr const & primaryRC, bool doSupportRotation, size_t idCacheSize)
@@ -37,6 +39,7 @@ RenderPolicy::RenderPolicy(shared_ptr const & primaryRC,
LOG(LDEBUG, ("each BaseRule will hold up to", idCacheSize, "cached values"));
drule::rules().ResizeCaches(idCacheSize);
yg::gl::InitExtensions();
+ yg::gl::InitializeThread();
yg::gl::CheckExtensionSupport();
}
diff --git a/yg/base_texture.cpp b/yg/base_texture.cpp
index 63bcff9d7e..59e1f7c786 100644
--- a/yg/base_texture.cpp
+++ b/yg/base_texture.cpp
@@ -16,10 +16,10 @@ namespace yg
OGLCHECK(glBindTexture(GL_TEXTURE_2D, m_id));
- OGLCHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
- OGLCHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
- OGLCHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- OGLCHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ OGLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
+ OGLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
+ OGLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ OGLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
}
BaseTexture::BaseTexture(m2::PointU const & size)
diff --git a/yg/blitter.cpp b/yg/blitter.cpp
index 295bfc0921..8d63d04979 100644
--- a/yg/blitter.cpp
+++ b/yg/blitter.cpp
@@ -148,10 +148,13 @@ namespace yg
storage.m_indices->unlock();
storage.m_indices->makeCurrent();
+#ifndef USING_GLSL
OGLCHECK(glEnable(GL_TEXTURE_2D));
+#endif
- OGLCHECK(glDisable(GL_BLEND));
- OGLCHECK(glDisable(GL_DEPTH_TEST));
+ OGLCHECK(glDisableFn(GL_ALPHA_TEST_MWM));
+ OGLCHECK(glDisableFn(GL_BLEND));
+ OGLCHECK(glDisableFn(GL_DEPTH_TEST));
OGLCHECK(glDepthMask(GL_FALSE));
for (unsigned i = 0; i < s; ++i)
@@ -159,11 +162,12 @@ namespace yg
if (blitInfo[i].m_srcSurface)
blitInfo[i].m_srcSurface->makeCurrent();
- OGLCHECK(glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, (unsigned short *)storage.m_indices->glPtr() + i * 4));
+ OGLCHECK(glDrawElementsFn(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, (unsigned short *)storage.m_indices->glPtr() + i * 4));
}
- OGLCHECK(glEnable(GL_DEPTH_TEST));
- OGLCHECK(glEnable(GL_BLEND));
+ OGLCHECK(glEnableFn(GL_ALPHA_TEST_MWM));
+ OGLCHECK(glEnableFn(GL_DEPTH_TEST));
+ OGLCHECK(glEnableFn(GL_BLEND));
OGLCHECK(glDepthMask(GL_TRUE));
// /// This call is necessary to avoid parasite blitting in updateActualTarget() on IPhone.
// OGLCHECK(glFinish());
@@ -345,7 +349,9 @@ namespace yg
if (m_texture)
{
+#ifndef USING_GLSL
OGLCHECK(glEnable(GL_TEXTURE_2D));
+#endif
m_texture->makeCurrent();
}
@@ -354,15 +360,15 @@ namespace yg
blitStorage.m_indices->unlock();
blitStorage.m_indices->makeCurrent();
- OGLCHECK(glDisable(GL_ALPHA_TEST));
- OGLCHECK(glDisable(GL_BLEND));
- OGLCHECK(glDisable(GL_DEPTH_TEST));
+ OGLCHECK(glDisableFn(GL_ALPHA_TEST_MWM));
+ OGLCHECK(glDisableFn(GL_BLEND));
+ OGLCHECK(glDisableFn(GL_DEPTH_TEST));
OGLCHECK(glDepthMask(GL_FALSE));
- OGLCHECK(glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, blitStorage.m_indices->glPtr()));
+ OGLCHECK(glDrawElementsFn(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, blitStorage.m_indices->glPtr()));
OGLCHECK(glDepthMask(GL_TRUE));
- OGLCHECK(glEnable(GL_DEPTH_TEST));
- OGLCHECK(glEnable(GL_BLEND));
- OGLCHECK(glEnable(GL_ALPHA_TEST));
+ OGLCHECK(glEnableFn(GL_DEPTH_TEST));
+ OGLCHECK(glEnableFn(GL_BLEND));
+ OGLCHECK(glEnableFn(GL_ALPHA_TEST_MWM));
blitStorage.m_vertices->discard();
blitStorage.m_indices->discard();
diff --git a/yg/clipper.cpp b/yg/clipper.cpp
index 42f30a48c9..9fbac42638 100644
--- a/yg/clipper.cpp
+++ b/yg/clipper.cpp
@@ -40,14 +40,14 @@ namespace yg
{
if (isDebugging())
LOG(LINFO, ("enabling scissor test"));
- OGLCHECK(glEnable(GL_SCISSOR_TEST));
+ OGLCHECK(glEnableFn(GL_SCISSOR_TEST));
}
else
{
if (isDebugging())
{
LOG(LINFO, ("disabling scissor test"));
- OGLCHECK(glDisable(GL_SCISSOR_TEST));
+ OGLCHECK(glDisableFn(GL_SCISSOR_TEST));
}
}
}
diff --git a/yg/geometry_renderer.cpp b/yg/geometry_renderer.cpp
index de4e1da09f..efac87be8e 100644
--- a/yg/geometry_renderer.cpp
+++ b/yg/geometry_renderer.cpp
@@ -36,7 +36,7 @@ namespace yg
// OGLCHECK(glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ));
- OGLCHECK(glDrawElements(
+ OGLCHECK(glDrawElementsFn(
GL_TRIANGLES,
m_indicesCount,
GL_UNSIGNED_SHORT,
@@ -64,18 +64,22 @@ namespace yg
if (renderQueue())
return;
- OGLCHECK(glEnable(GL_TEXTURE_2D));
+ OGLCHECK(glActiveTexture(GL_TEXTURE0));
+
+#ifndef USING_GLSL
+ OGLCHECK(glEnableFn(GL_TEXTURE_2D));
+#endif
OGLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
OGLCHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- OGLCHECK(glEnable(GL_DEPTH_TEST));
+ OGLCHECK(glEnableFn(GL_DEPTH_TEST));
OGLCHECK(glDepthFunc(GL_LEQUAL));
- OGLCHECK(glEnable(GL_ALPHA_TEST));
- OGLCHECK(glAlphaFunc(GL_GREATER, 0.0));
+ OGLCHECK(glEnableFn(GL_ALPHA_TEST_MWM));
+ OGLCHECK(glAlphaFuncFn(GL_NOTEQUAL, 0.0));
- OGLCHECK(glEnable(GL_BLEND));
+ OGLCHECK(glEnableFn(GL_BLEND));
if (yg::gl::g_isSeparateBlendFuncSupported)
OGLCHECK(glBlendFuncSeparateFn(GL_SRC_ALPHA,
@@ -86,7 +90,9 @@ namespace yg
OGLCHECK(glBlendFunc(GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA));
+#ifndef USING_GLSL
OGLCHECK(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
+#endif
}
}
}
diff --git a/yg/internal/opengl.cpp b/yg/internal/opengl.cpp
index a9fbf08079..134301b076 100644
--- a/yg/internal/opengl.cpp
+++ b/yg/internal/opengl.cpp
@@ -56,6 +56,20 @@ namespace yg
LOG(LINFO, ("--------------------------------------------"));
}
+ // basic opengl functions and constants
+ void (OPENGL_CALLING_CONVENTION * glEnableFn)(GLenum cap);
+ void (OPENGL_CALLING_CONVENTION * glDisableFn)(GLenum cap);
+ void (OPENGL_CALLING_CONVENTION * glAlphaFuncFn)(GLenum func, GLclampf ref);
+
+ void (OPENGL_CALLING_CONVENTION * glEnableClientStateFn) (GLenum array);
+ void (OPENGL_CALLING_CONVENTION * glVertexPointerFn) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+ void (OPENGL_CALLING_CONVENTION * glTexCoordPointerFn) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+
+ void (OPENGL_CALLING_CONVENTION * glMatrixModeFn) (GLenum mode);
+ void (OPENGL_CALLING_CONVENTION * glLoadIdentityFn)();
+ void (OPENGL_CALLING_CONVENTION * glOrthoFn) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+ void (OPENGL_CALLING_CONVENTION * glDrawElementsFn) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+
bool g_isBufferObjectsSupported = true;
bool g_isFramebufferSupported = true;
bool g_isRenderbufferSupported = true;
@@ -113,8 +127,8 @@ namespace yg
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_STACK_OVERFLOW: return "GL_STACK_OVERFLOW";
- case GL_STACK_UNDERFLOW: return "GL_STACK_UNDERFLOW";
+// case GL_STACK_OVERFLOW: return "GL_STACK_OVERFLOW"; //< not supported in OpenGL ES2.0
+// case GL_STACK_UNDERFLOW: return "GL_STACK_UNDERFLOW"; //< not supported in OpenGL ES2.0
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
#ifdef OMIM_OS_BADA /* Errors / GetError return values */
case EGL_SUCCESS : return 0;
diff --git a/yg/internal/opengl.hpp b/yg/internal/opengl.hpp
index 9fd3ad86b9..19d816ff6a 100644
--- a/yg/internal/opengl.hpp
+++ b/yg/internal/opengl.hpp
@@ -4,6 +4,9 @@
#include "../../base/logging.hpp"
+// This define is set in yg.pro
+// #define USING_GLSL
+
#if defined(OMIM_OS_WINDOWS)
#include "../../std/windows.hpp"
#include
@@ -19,16 +22,28 @@
#include
#ifdef OMIM_OS_IPHONE
- #define USE_OPENGLES20_IF_AVAILABLE 0
- #include
- #define OMIM_GL_ES
+ #ifdef USING_GLSL
+ #define USE_OPENGLES20_IF_AVAILABLE 1
+ #include
+ #define OMIM_GL_ES
+ #else
+ #define USE_OPENGLES20_IF_AVAILABLE 0
+ #include
+ #define OMIM_GL_ES
+ #endif
#else
#include
#include
#endif
#elif defined(OMIM_OS_ANDROID)
- #include
+
+ #ifdef USING_GLSL
+ #include
+ #else
+ #include
+ #endif
+
#define OMIM_GL_ES
#else
@@ -53,6 +68,29 @@ namespace yg
{
namespace gl
{
+ // basic opengl functions and constants
+ extern void (OPENGL_CALLING_CONVENTION * glEnableFn)(GLenum cap);
+ extern void (OPENGL_CALLING_CONVENTION * glDisableFn)(GLenum cap);
+ extern void (OPENGL_CALLING_CONVENTION * glAlphaFuncFn)(GLenum func, GLclampf ref);
+ extern void (OPENGL_CALLING_CONVENTION * glEnableClientStateFn) (GLenum array);
+ extern void (OPENGL_CALLING_CONVENTION * glVertexPointerFn) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+ extern void (OPENGL_CALLING_CONVENTION * glTexCoordPointerFn) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+
+ extern const GLenum GL_VERTEX_ARRAY_MWM;
+ extern const GLenum GL_TEXTURE_COORD_ARRAY_MWM;
+
+ extern void (OPENGL_CALLING_CONVENTION * glMatrixModeFn) (GLenum mode);
+ extern void (OPENGL_CALLING_CONVENTION * glLoadIdentityFn)();
+ extern void (OPENGL_CALLING_CONVENTION * glOrthoFn) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+ extern void (OPENGL_CALLING_CONVENTION * glDrawElementsFn) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+
+ extern const GLenum GL_MODELVIEW_MWM;
+ extern const GLenum GL_PROJECTION_MWM;
+
+ extern const GLenum GL_ALPHA_TEST_MWM;
+
+ /// information about supported extensions
+
extern bool g_isFramebufferSupported;
extern bool g_isBufferObjectsSupported;
extern bool g_isRenderbufferSupported;
@@ -122,6 +160,12 @@ namespace yg
/// to check extensions support and initialize function pointers.
void InitExtensions();
+ /// Initialize per-thread OpenGL
+ void InitializeThread();
+
+ /// Finalize per-thread OpenGL
+ void FinalizeThread();
+
/// Does we have an extension with the specified name?
bool HasExtension(char const * name);
diff --git a/yg/internal/opengl_es.cpp b/yg/internal/opengl_es.cpp
index 3ee987ace5..66ebb579e8 100644
--- a/yg/internal/opengl_es.cpp
+++ b/yg/internal/opengl_es.cpp
@@ -32,10 +32,36 @@ namespace yg
const int GL_WRITE_ONLY_MWM = GL_WRITE_ONLY_OES;
+ const GLenum GL_MODELVIEW_MWM = GL_MODELVIEW;
+ const GLenum GL_PROJECTION_MWM = GL_PROJECTION;
+ const GLenum GL_ALPHA_TEST_MWM = GL_ALPHA_TEST;
+
+ const GLenum GL_VERTEX_ARRAY_MWM = GL_VERTEX_ARRAY;
+ const GLenum GL_TEXTURE_COORD_ARRAY_MWM = GL_TEXTURE_COORD_ARRAY;
+
+ void InitializeThread()
+ {}
+
+ void FinalizeThread()
+ {}
+
void InitExtensions()
{
DumpGLInformation();
+ glEnableFn = &glEnable;
+ glDisableFn = &glDisable;
+ glAlphaFuncFn = &glAlphaFunc;
+
+ glVertexPointerFn = &glVertexPointer;
+ glTexCoordPointerFn = &glTexCoordPointer;
+ glEnableClientStateFn = &glEnableClientState;
+
+ glMatrixModeFn = &glMatrixMode;
+ glLoadIdentityFn = &glLoadIdentity;
+ glOrthoFn = &glOrthof;
+ glDrawElementsFn = &glDrawElements;
+
g_isBufferObjectsSupported = HasExtension("GL_OES_mapbuffer");
glBindBufferFn = &glBindBuffer;
diff --git a/yg/internal/opengl_ext.cpp b/yg/internal/opengl_ext.cpp
index 80d7afc12a..0db8543f8b 100644
--- a/yg/internal/opengl_ext.cpp
+++ b/yg/internal/opengl_ext.cpp
@@ -23,10 +23,41 @@ namespace yg
const int GL_WRITE_ONLY_MWM = GL_WRITE_ONLY;
+ const GLenum GL_MODELVIEW_MWM = GL_MODELVIEW;
+ const GLenum GL_PROJECTION_MWM = GL_PROJECTION;
+ const GLenum GL_ALPHA_TEST_MWM = GL_ALPHA_TEST;
+
+ const GLenum GL_VERTEX_ARRAY_MWM = GL_VERTEX_ARRAY;
+ const GLenum GL_TEXTURE_COORD_ARRAY_MWM = GL_TEXTURE_COORD_ARRAY;
+
+ void glOrthoImpl (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+ {
+ glOrtho(left, right, bottom, top, zNear, zFar);
+ }
+
+ void InitializeThread()
+ {}
+
+ void FinalizeThread()
+ {}
+
void InitExtensions()
{
DumpGLInformation();
+ glEnableFn = &glEnable;
+ glDisableFn = &glDisable;
+ glAlphaFuncFn = &glAlphaFunc;
+
+ glVertexPointerFn = &glVertexPointer;
+ glTexCoordPointerFn = &glTexCoordPointer;
+ glEnableClientStateFn = &glEnableClientState;
+
+ glMatrixModeFn = &glMatrixMode;
+ glLoadIdentityFn = &glLoadIdentity;
+ glOrthoFn = &glOrthoImpl;
+ glDrawElementsFn = &glDrawElements;
+
g_isBufferObjectsSupported = HasExtension("GL_ARB_vertex_buffer_object")
|| HasExtension("GLX_ARB_vertex_buffer_object");
diff --git a/yg/internal/opengl_glsl_es2.cpp b/yg/internal/opengl_glsl_es2.cpp
new file mode 100644
index 0000000000..0cc8947d19
--- /dev/null
+++ b/yg/internal/opengl_glsl_es2.cpp
@@ -0,0 +1,84 @@
+#include "opengl.hpp"
+#include "opengl_glsl_impl.hpp"
+
+#ifdef OMIM_OS_ANDROID
+ #define GL_GLEXT_PROTOTYPES
+ #include
+#endif
+
+#ifdef OMIM_OS_IPHONE
+ #include
+ #include
+#endif
+
+namespace yg
+{
+ namespace gl
+ {
+ const int GL_FRAMEBUFFER_BINDING_MWM = GL_FRAMEBUFFER_BINDING;
+ const int GL_FRAMEBUFFER_MWM = GL_FRAMEBUFFER;
+ const int GL_FRAMEBUFFER_UNSUPPORTED_MWM = GL_FRAMEBUFFER_UNSUPPORTED;
+ const int GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_MWM = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ const int GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_MWM = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+ const int GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_MWM = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ const int GL_FRAMEBUFFER_COMPLETE_MWM = GL_FRAMEBUFFER_COMPLETE;
+
+ const int GL_DEPTH_ATTACHMENT_MWM = GL_DEPTH_ATTACHMENT;
+ const int GL_COLOR_ATTACHMENT0_MWM = GL_COLOR_ATTACHMENT0;
+ const int GL_RENDERBUFFER_MWM = GL_RENDERBUFFER;
+ const int GL_RENDERBUFFER_BINDING_MWM = GL_RENDERBUFFER_BINDING;
+ const int GL_DEPTH_COMPONENT16_MWM = GL_DEPTH_COMPONENT16;
+ const int GL_DEPTH_COMPONENT24_MWM = GL_DEPTH_COMPONENT24_OES;
+ const int GL_RGBA8_MWM = GL_RGBA8_OES;
+
+ const int GL_WRITE_ONLY_MWM = GL_WRITE_ONLY_OES;
+
+ void InitExtensions()
+ {
+ DumpGLInformation();
+
+ glEnableFn = &glsl::glEnable;
+ glDisableFn = &glsl::glDisable;
+ glAlphaFuncFn = &glsl::glAlphaFunc;
+
+ glVertexPointerFn = &glsl::glVertexPointer;
+ glTexCoordPointerFn = &glsl::glTexCoordPointer;
+ glEnableClientStateFn = &glsl::glEnableClientState;
+
+ glMatrixModeFn = &glsl::glMatrixMode;
+ glLoadIdentityFn = &glsl::glLoadIdentity;
+ glOrthoFn = &glsl::glOrtho;
+ glDrawElementsFn = &glsl::glDrawElements;
+
+ g_isBufferObjectsSupported = HasExtension("GL_OES_mapbuffer");
+
+ glBindBufferFn = &glBindBuffer;
+ glGenBuffersFn = &glGenBuffers;
+ glBufferDataFn = &glBufferData;
+ glBufferSubDataFn = &glBufferSubData;
+ glDeleteBuffersFn = &glDeleteBuffers;
+ glMapBufferFn = &glMapBufferOES;
+ glUnmapBufferFn = &glUnmapBufferOES;
+
+ g_isFramebufferSupported = true;
+
+ glBindFramebufferFn = &glBindFramebuffer;
+ glFramebufferTexture2DFn = &glFramebufferTexture2D;
+ glFramebufferRenderbufferFn = &glFramebufferRenderbuffer;
+ glGenFramebuffersFn = &glGenFramebuffers;
+ glDeleteFramebuffersFn = &glDeleteFramebuffers;
+ glCheckFramebufferStatusFn = &glCheckFramebufferStatus;
+
+ g_isRenderbufferSupported = g_isFramebufferSupported;
+
+ glGenRenderbuffersFn = &glGenRenderbuffers;
+ glDeleteRenderbuffersFn = &glDeleteRenderbuffers;
+ glBindRenderbufferFn = &glBindRenderbuffer;
+ glRenderbufferStorageFn = &glRenderbufferStorage;
+
+ g_isSeparateBlendFuncSupported = true;
+ glBlendFuncSeparateFn = &glBlendFuncSeparate;
+ }
+ }
+}
+
diff --git a/yg/internal/opengl_glsl_ext.cpp b/yg/internal/opengl_glsl_ext.cpp
new file mode 100644
index 0000000000..9192a884d2
--- /dev/null
+++ b/yg/internal/opengl_glsl_ext.cpp
@@ -0,0 +1,79 @@
+#include "opengl.hpp"
+
+#include "opengl_glsl_impl.hpp"
+
+#include "../../base/matrix.hpp"
+#include "../../platform/platform.hpp"
+
+namespace yg
+{
+ namespace gl
+ {
+ const int GL_FRAMEBUFFER_BINDING_MWM = GL_FRAMEBUFFER_BINDING_EXT;
+ const int GL_FRAMEBUFFER_MWM = GL_FRAMEBUFFER_EXT;
+ const int GL_FRAMEBUFFER_UNSUPPORTED_MWM = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+ const int GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_MWM = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
+ const int GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_MWM = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
+ const int GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_MWM = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
+ const int GL_FRAMEBUFFER_COMPLETE_MWM = GL_FRAMEBUFFER_COMPLETE_EXT;
+
+ const int GL_DEPTH_ATTACHMENT_MWM = GL_DEPTH_ATTACHMENT_EXT;
+ const int GL_COLOR_ATTACHMENT0_MWM = GL_COLOR_ATTACHMENT0_EXT;
+ const int GL_RENDERBUFFER_MWM = GL_RENDERBUFFER_EXT;
+ const int GL_RENDERBUFFER_BINDING_MWM = GL_RENDERBUFFER_BINDING_EXT;
+ const int GL_DEPTH_COMPONENT16_MWM = GL_DEPTH_COMPONENT16;
+ const int GL_DEPTH_COMPONENT24_MWM = GL_DEPTH_COMPONENT24;
+ const int GL_RGBA8_MWM = GL_RGBA8;
+
+ const int GL_WRITE_ONLY_MWM = GL_WRITE_ONLY;
+
+ void InitExtensions()
+ {
+ DumpGLInformation();
+
+ glEnableFn = &glsl::glEnable;
+ glDisableFn = &glsl::glDisable;
+ glAlphaFuncFn = &glsl::glAlphaFunc;
+
+ glVertexPointerFn = &glsl::glVertexPointer;
+ glTexCoordPointerFn = &glsl::glTexCoordPointer;
+ glEnableClientStateFn = &glsl::glEnableClientState;
+
+ glMatrixModeFn = &glsl::glMatrixMode;
+ glLoadIdentityFn = &glsl::glLoadIdentity;
+ glOrthoFn = &glsl::glOrtho;
+ glDrawElementsFn = &glsl::glDrawElements;
+
+ g_isBufferObjectsSupported = HasExtension("GL_OES_mapbuffer");
+
+ glBindBufferFn = &glBindBuffer;
+ glGenBuffersFn = &glGenBuffers;
+ glBufferDataFn = &glBufferData;
+ glBufferSubDataFn = &glBufferSubData;
+ glDeleteBuffersFn = &glDeleteBuffers;
+ glMapBufferFn = &glMapBuffer;
+ glUnmapBufferFn = &glUnmapBuffer;
+
+ g_isFramebufferSupported = HasExtension("GL_ARB_framebuffer_object");
+
+ glBindFramebufferFn = &glBindFramebufferEXT;
+ glFramebufferTexture2DFn = &glFramebufferTexture2DEXT;
+ glFramebufferRenderbufferFn = &glFramebufferRenderbufferEXT;
+ glGenFramebuffersFn = &glGenFramebuffersEXT;
+ glDeleteFramebuffersFn = &glDeleteFramebuffersEXT;
+ glCheckFramebufferStatusFn = &glCheckFramebufferStatusEXT;
+
+ g_isRenderbufferSupported = g_isFramebufferSupported;
+
+ glGenRenderbuffersFn = &glGenRenderbuffersEXT;
+ glDeleteRenderbuffersFn = &glDeleteRenderbuffersEXT;
+ glBindRenderbufferFn = &glBindRenderbufferEXT;
+ glRenderbufferStorageFn = &glRenderbufferStorageEXT;
+
+ g_isSeparateBlendFuncSupported = HasExtension("GL_EXT_blend_func_separate");
+ glBlendFuncSeparateFn = &glBlendFuncSeparateEXT;
+ }
+ }
+}
+
+
diff --git a/yg/internal/opengl_glsl_impl.cpp b/yg/internal/opengl_glsl_impl.cpp
new file mode 100644
index 0000000000..943c83e8f7
--- /dev/null
+++ b/yg/internal/opengl_glsl_impl.cpp
@@ -0,0 +1,369 @@
+#include "opengl_glsl_impl.hpp"
+
+#include "opengl.hpp"
+
+#include "../../base/matrix.hpp"
+#include "../../base/thread.hpp"
+
+namespace yg
+{
+ namespace gl
+ {
+ const GLenum GL_MODELVIEW_MWM = 0;
+ const GLenum GL_PROJECTION_MWM = 1;
+
+ const GLenum GL_VERTEX_ARRAY_MWM = 0;
+ const GLenum GL_TEXTURE_COORD_ARRAY_MWM = 1;
+
+ const GLenum GL_ALPHA_TEST_MWM = 0x0BC0;
+
+#if defined(OMIM_GL_ES)
+ #define PRECISION "lowp"
+#else
+ #define PRECISION ""
+#endif
+
+ namespace glsl
+ {
+ /// Vertex Shader Source
+
+ static const char g_vxSrc[] =
+ "attribute vec4 Position;\n"
+ "attribute vec2 TexCoordIn;\n"
+ "uniform mat4 ProjM;\n"
+ "uniform mat4 ModelViewM;\n"
+ "varying vec2 TexCoordOut;\n"
+ "void main(void) {\n"
+ " gl_Position = ProjM * Position;\n"
+ " TexCoordOut = TexCoordIn;\n"
+ "}\n";
+
+ /// Fragment Shader with alphaTest
+
+ static const char g_alphaTestFrgSrc [] =
+ "uniform sampler2D Texture;\n"
+ "varying " PRECISION " vec2 TexCoordOut;\n"
+ "void main(void) {\n"
+ " gl_FragColor = texture2D(Texture, TexCoordOut);\n"
+ " if (gl_FragColor.a == 0.0)\n"
+ " discard;\n"
+ "}\n";
+
+ /// Fragment shader without alphaTest
+
+ static const char g_noAlphaTestFrgSrc[] =
+ "uniform sampler2D Texture;\n"
+ "varying " PRECISION " vec2 TexCoordOut;\n"
+ "void main(void) {\n"
+ " gl_FragColor = texture2D(Texture, TexCoordOut);\n"
+ "}\n";
+
+ /// Structure that holds a single GLSL program
+ /// along with handles to attributes and uniforms
+ struct Program
+ {
+ GLuint m_program;
+ GLuint m_positionHandle;
+ GLuint m_texCoordHandle;
+ GLuint m_projectionUniform;
+ GLuint m_textureUniform;
+
+ bool createProgram(GLuint vertexShader, GLuint fragmentShader)
+ {
+ m_program = ::glCreateProgram();
+ OGLCHECKAFTER;
+
+ if (!m_program)
+ return false;
+
+ OGLCHECK(::glAttachShader(m_program, vertexShader));
+ OGLCHECK(::glAttachShader(m_program, fragmentShader));
+ OGLCHECK(::glLinkProgram(m_program));
+
+ int linkStatus = GL_FALSE;
+ OGLCHECK(::glGetProgramiv(m_program, GL_LINK_STATUS, &linkStatus));
+
+ if (linkStatus != GL_TRUE)
+ {
+ int bufLength = 0;
+ OGLCHECK(::glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &bufLength));
+ if (bufLength)
+ {
+ char * buf = new char[bufLength];
+ ::glGetProgramInfoLog(m_program, bufLength, NULL, buf);
+ LOG(LINFO, ("Could not link program:"));
+ LOG(LINFO, (buf));
+ delete [] buf;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void attachProjection(char const * name)
+ {
+ m_projectionUniform = ::glGetUniformLocation(m_program, name);
+ OGLCHECKAFTER;
+ }
+
+ void attachTexture(char const * name)
+ {
+ m_textureUniform = ::glGetUniformLocation(m_program, name);
+ OGLCHECKAFTER;
+ }
+
+ void attachPosition(char const * name)
+ {
+ m_positionHandle = ::glGetAttribLocation(m_program, name);
+ OGLCHECKAFTER;
+ }
+
+ void attachTexCoord(char const * name)
+ {
+ m_texCoordHandle = ::glGetAttribLocation(m_program, "TexCoordIn");
+ OGLCHECKAFTER;
+ }
+
+ void apply()
+ {
+ OGLCHECK(::glUseProgram(m_program));
+ }
+ };
+
+ struct ThreadData
+ {
+ GLenum m_matrixMode;
+ math::Matrix m_matrices[2];
+
+ Program m_noAlphaTestProgram;
+ Program m_alphaTestProgram;
+
+ /// currently bound GLSL program
+ Program * m_currentProgram;
+
+ GLuint m_vertexShader;
+ GLuint m_noAlphaTestFrgSh;
+ GLuint m_alphaTestFrgSh;
+
+ void setCurrentProgram(Program * program)
+ {
+ if (m_currentProgram != program)
+ {
+ m_currentProgram = program;
+ m_currentProgram->apply();
+ }
+ }
+
+ GLuint loadShader(char const * shaderSource, GLenum shaderType)
+ {
+ GLuint res = ::glCreateShader(shaderType);
+ OGLCHECKAFTER;
+
+ int len = strlen(shaderSource);
+
+ OGLCHECK(::glShaderSource(res, 1, &shaderSource, &len));
+
+ OGLCHECK(::glCompileShader(res));
+
+ GLint compileRes;
+ OGLCHECK(::glGetShaderiv(res, GL_COMPILE_STATUS, &compileRes));
+
+ if (compileRes == GL_FALSE)
+ {
+ GLchar msg[256];
+ OGLCHECK(::glGetShaderInfoLog(res, sizeof(msg), 0, msg));
+ LOG(LINFO, ("Couldn't compile shader :"));
+ LOG(LERROR, (msg));
+ return 0;
+ }
+
+ return res;
+ }
+
+ ThreadData()
+ : m_matrixMode(-1),
+ m_vertexShader(0),
+ m_noAlphaTestFrgSh(0),
+ m_alphaTestFrgSh(0)
+ {}
+
+ void Initialize()
+ {
+ m_vertexShader = loadShader(g_vxSrc, GL_VERTEX_SHADER);
+ m_noAlphaTestFrgSh = loadShader(g_noAlphaTestFrgSrc, GL_FRAGMENT_SHADER);
+ m_alphaTestFrgSh = loadShader(g_alphaTestFrgSrc, GL_FRAGMENT_SHADER);
+
+ /// creating program
+ m_alphaTestProgram.createProgram(m_vertexShader, m_alphaTestFrgSh);
+ m_noAlphaTestProgram.createProgram(m_vertexShader, m_noAlphaTestFrgSh);
+
+ m_alphaTestProgram.attachProjection("ProjM");
+ m_alphaTestProgram.attachTexture("Texture");
+ m_alphaTestProgram.attachPosition("Position");
+ m_alphaTestProgram.attachTexCoord("TexCoordIn");
+
+ m_noAlphaTestProgram.attachProjection("ProjM");
+ m_noAlphaTestProgram.attachTexture("Texture");
+ m_noAlphaTestProgram.attachPosition("Position");
+ m_noAlphaTestProgram.attachTexCoord("TexCoordIn");
+
+ m_currentProgram = &m_noAlphaTestProgram;
+ m_currentProgram->apply();
+ }
+
+ void Finalize()
+ {
+ if (yg::gl::g_hasContext)
+ ::glDeleteProgram(m_alphaTestProgram.m_program);
+ if (yg::gl::g_hasContext)
+ ::glDeleteProgram(m_noAlphaTestProgram.m_program);
+ if (yg::gl::g_hasContext)
+ ::glDeleteShader(m_vertexShader);
+ if (yg::gl::g_hasContext)
+ ::glDeleteShader(m_noAlphaTestFrgSh);
+ if (yg::gl::g_hasContext)
+ ::glDeleteShader(m_alphaTestFrgSh);
+ }
+ };
+
+ typedef map ThreadDataMap;
+ ThreadDataMap g_threadData;
+
+ void glEnable(GLenum cap)
+ {
+ if (cap == GL_ALPHA_TEST_MWM)
+ {
+ ThreadData & threadData = g_threadData[threads::GetCurrentThreadID()];
+ threadData.setCurrentProgram(&threadData.m_alphaTestProgram);
+ }
+ else
+ ::glEnable(cap);
+ }
+
+ void glDisable(GLenum cap)
+ {
+ if (cap == GL_ALPHA_TEST_MWM)
+ {
+ ThreadData & threadData = g_threadData[threads::GetCurrentThreadID()];
+ threadData.setCurrentProgram(&threadData.m_noAlphaTestProgram);
+ }
+ else
+ ::glDisable(cap);
+ }
+
+ void glAlphaFunc(GLenum func, GLclampf ref)
+ {
+ ASSERT((func == GL_NOTEQUAL) && (ref == 0.0), ("only GL_NOEQUAL with 0.0 reference value is supported for alphaTest"));
+ }
+
+ void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+ {
+ ThreadData & threadData = g_threadData[threads::GetCurrentThreadID()];
+ ::glVertexAttribPointer(threadData.m_alphaTestProgram.m_positionHandle, size, type, GL_FALSE, stride, pointer);
+ ::glVertexAttribPointer(threadData.m_noAlphaTestProgram.m_positionHandle, size, type, GL_FALSE, stride, pointer);
+ }
+
+ void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+ {
+ ThreadData & threadData = g_threadData[threads::GetCurrentThreadID()];
+ ::glVertexAttribPointer(threadData.m_alphaTestProgram.m_texCoordHandle, size, type, GL_FALSE, stride, pointer);
+ ::glVertexAttribPointer(threadData.m_noAlphaTestProgram.m_texCoordHandle, size, type, GL_FALSE, stride, pointer);
+ }
+
+ void glEnableClientState(GLenum array)
+ {
+ ThreadData & threadData = g_threadData[threads::GetCurrentThreadID()];
+ switch (array)
+ {
+ case GL_VERTEX_ARRAY_MWM:
+ ::glEnableVertexAttribArray(threadData.m_alphaTestProgram.m_positionHandle);
+ ::glEnableVertexAttribArray(threadData.m_noAlphaTestProgram.m_positionHandle);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_MWM:
+ ::glEnableVertexAttribArray(threadData.m_alphaTestProgram.m_texCoordHandle);
+ ::glEnableVertexAttribArray(threadData.m_noAlphaTestProgram.m_texCoordHandle);
+ break;
+ default:
+ LOG(LERROR, ("Unknown option is passed to glEnableClientState"));
+ };
+ }
+
+ void glMatrixMode(GLenum mode)
+ {
+ ThreadData & threadData = g_threadData[threads::GetCurrentThreadID()];
+ threadData.m_matrixMode = mode;
+ }
+
+ void glLoadIdentity()
+ {
+ ThreadData & threadData = g_threadData[threads::GetCurrentThreadID()];
+ threadData.m_matrices[threadData.m_matrixMode] = math::Identity();
+ }
+
+ void glOrtho(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
+ {
+ ThreadData & threadData = g_threadData[threads::GetCurrentThreadID()];
+
+ math::Matrix m = math::Identity();
+
+ /// matrices are stored in column-major order
+
+ m(0, 0) = 2 / (r - l); m(1, 0) = 0; m(2, 0) = 0; m(3, 0) = -(r + l) / (r - l);
+ m(0, 1) = 0; m(1, 1) = 2 / (t - b);m(2, 1) = 0; m(3, 1) = -(t + b) / (t - b);
+ m(0, 2) = 0; m(1, 2) = 0; m(2, 2) = -2 / (f - n); m(3, 2) = - (f + n) / (f - n);
+ m(0, 3) = 0; m(1, 3) = 0; m(2, 3) = 0; m(3, 3) = 1;
+
+ threadData.m_matrices[threadData.m_matrixMode] = m * threadData.m_matrices[threadData.m_matrixMode];
+ }
+
+ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+ {
+ ThreadData & threadData = g_threadData[threads::GetCurrentThreadID()];
+
+ math::Matrix const & projM = threadData.m_matrices[GL_PROJECTION_MWM];
+ math::Matrix const & modelViewM = threadData.m_matrices[GL_MODELVIEW_MWM];
+
+ // applying shader parameters
+ OGLCHECK(::glUniformMatrix4fv(threadData.m_currentProgram->m_projectionUniform, 1, 0, &projM(0, 0)));
+ OGLCHECK(::glUniform1i(threadData.m_currentProgram->m_textureUniform, 0));
+
+ // drawing elements
+ OGLCHECK(::glDrawElements(mode, count, type, indices));
+ }
+ }
+
+ void InitializeThread()
+ {
+ threads::ThreadID id = threads::GetCurrentThreadID();
+ glsl::ThreadDataMap::const_iterator it = glsl::g_threadData.find(id);
+
+ if (it != glsl::g_threadData.end())
+ {
+ LOG(LWARNING, ("GLSL structures for thread", threads::GetCurrentThreadID(), "is already initialized"));
+ return;
+ }
+
+ LOG(LINFO, ("initializing GLSL structures for thread", threads::GetCurrentThreadID()));
+ glsl::g_threadData[id].Initialize();
+ }
+
+ void FinalizeThread()
+ {
+ threads::ThreadID id = threads::GetCurrentThreadID();
+ glsl::ThreadDataMap::const_iterator it = glsl::g_threadData.find(id);
+
+ if (it == glsl::g_threadData.end())
+ {
+ LOG(LWARNING, ("GLSL structures for thread", threads::GetCurrentThreadID(), "is already finalized"));
+ return;
+ }
+
+ LOG(LINFO, ("finalizing GLSL structures for thread", threads::GetCurrentThreadID()));
+
+ glsl::g_threadData[id].Finalize();
+ glsl::g_threadData.erase(id);
+ }
+ }
+}
diff --git a/yg/internal/opengl_glsl_impl.hpp b/yg/internal/opengl_glsl_impl.hpp
new file mode 100644
index 0000000000..f2cb2b093d
--- /dev/null
+++ b/yg/internal/opengl_glsl_impl.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "opengl.hpp"
+
+namespace yg
+{
+ namespace gl
+ {
+ namespace glsl
+ {
+ void glEnable(GLenum cap);
+ void glDisable(GLenum cap);
+ void glAlphaFunc(GLenum func, GLclampf ref);
+
+ void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+ void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+ void glEnableClientState(GLenum array);
+
+ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+ void glOrtho(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+ void glLoadIdentity();
+ void glMatrixMode(GLenum mode);
+ }
+ }
+}
diff --git a/yg/render_state_updater.cpp b/yg/render_state_updater.cpp
index 28ab926ca4..4a043a0032 100644
--- a/yg/render_state_updater.cpp
+++ b/yg/render_state_updater.cpp
@@ -67,7 +67,7 @@ namespace yg
OGLCHECK(glFinish());
- OGLCHECK(glDisable(GL_SCISSOR_TEST));
+ OGLCHECK(glDisableFn(GL_SCISSOR_TEST));
m_auxFrameBuffer->setRenderTarget(m_renderState->m_backBuffer);
m_auxFrameBuffer->makeCurrent();
@@ -91,7 +91,7 @@ namespace yg
m_frameBuffer->makeCurrent();
if (m_isClipRectEnabled)
- OGLCHECK(glEnable(GL_SCISSOR_TEST));
+ OGLCHECK(glEnableFn(GL_SCISSOR_TEST));
OGLCHECK(glScissor(m_clipRect.minX(), m_clipRect.minY(), m_clipRect.maxX(), m_clipRect.maxY()));
diff --git a/yg/rendercontext.cpp b/yg/rendercontext.cpp
index 2619d4b2d7..91f3a239c3 100644
--- a/yg/rendercontext.cpp
+++ b/yg/rendercontext.cpp
@@ -10,6 +10,12 @@ namespace yg
{
OGLCHECK(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
OGLCHECK(glPixelStorei(GL_PACK_ALIGNMENT, 1));
+ yg::gl::InitializeThread();
+ }
+
+ void RenderContext::endThreadDrawing()
+ {
+ yg::gl::FinalizeThread();
}
}
}
diff --git a/yg/rendercontext.hpp b/yg/rendercontext.hpp
index 7ff41a2af2..640caa3629 100644
--- a/yg/rendercontext.hpp
+++ b/yg/rendercontext.hpp
@@ -15,7 +15,7 @@ namespace yg
/// Create a render context which is shared with this one.
virtual shared_ptr createShared() = 0;
/// called at the end of thread
- virtual void endThreadDrawing() = 0;
+ virtual void endThreadDrawing();
/// !! IMPORTANT !!
/// this function must be called from each opengl
/// thread to setup texture related params
diff --git a/yg/utils.cpp b/yg/utils.cpp
index 3c96b3403c..84c8820ef4 100644
--- a/yg/utils.cpp
+++ b/yg/utils.cpp
@@ -15,23 +15,16 @@ namespace yg
{
OGLCHECK(glViewport(0, 0, width, height));
- OGLCHECK(glMatrixMode(GL_MODELVIEW));
- OGLCHECK(glLoadIdentity());
+ OGLCHECK(glMatrixModeFn(GL_MODELVIEW_MWM));
+ OGLCHECK(glLoadIdentityFn());
- OGLCHECK(glMatrixMode(GL_PROJECTION));
- OGLCHECK(glLoadIdentity());
+ OGLCHECK(glMatrixModeFn(GL_PROJECTION_MWM));
+ OGLCHECK(glLoadIdentityFn());
-#ifdef OMIM_GL_ES
if (!doSwap)
- OGLCHECK(glOrthof(0, width, 0, height, -yg::maxDepth, yg::maxDepth));
+ OGLCHECK(glOrthoFn(0, width, 0, height, -yg::maxDepth, yg::maxDepth));
else
- OGLCHECK(glOrthof(0, width, height, 0, -yg::maxDepth, yg::maxDepth));
-#else
- if (!doSwap)
- OGLCHECK(glOrtho(0, width, 0, height, -yg::maxDepth, yg::maxDepth));
- else
- OGLCHECK(glOrtho(0, width, height, 0, -yg::maxDepth, yg::maxDepth));
-#endif
+ OGLCHECK(glOrthoFn(0, width, height, 0, -yg::maxDepth, yg::maxDepth));
}
}
}
diff --git a/yg/vertex.cpp b/yg/vertex.cpp
index 5cba704f24..6253fc31ed 100644
--- a/yg/vertex.cpp
+++ b/yg/vertex.cpp
@@ -30,12 +30,11 @@ namespace yg
void Vertex::setupLayout(void * glPtr)
{
- OGLCHECK(glDisableClientState(GL_COLOR_ARRAY));
- OGLCHECK(glEnableClientState(GL_VERTEX_ARRAY));
- OGLCHECK(glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)((char*)glPtr + Vertex::vertexOffset)));
- OGLCHECK(glEnable(GL_TEXTURE_2D));
- OGLCHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
- OGLCHECK(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)((char*)glPtr + Vertex::texCoordOffset)));
+ OGLCHECK(glEnableClientStateFn(GL_VERTEX_ARRAY_MWM));
+ OGLCHECK(glVertexPointerFn(3, GL_FLOAT, sizeof(Vertex), (void*)((char*)glPtr + Vertex::vertexOffset)));
+
+ OGLCHECK(glEnableClientStateFn(GL_TEXTURE_COORD_ARRAY_MWM));
+ OGLCHECK(glTexCoordPointerFn(2, GL_FLOAT, sizeof(Vertex), (void*)((char*)glPtr + Vertex::texCoordOffset)));
}
}
}
diff --git a/yg/yg.pro b/yg/yg.pro
index 0ddd4faa00..2c473fbf4a 100644
--- a/yg/yg.pro
+++ b/yg/yg.pro
@@ -120,14 +120,35 @@ HEADERS += \
circle_element.hpp \
packets_queue.hpp \
+# uncomment to enable GLSL support
+CONFIG += glsl
+
win32* {
SOURCES += internal/opengl_win32.cpp
} else: android*|iphone* {
- SOURCES += internal/opengl_es.cpp
+ CONFIG(glsl) {
+ DEFINES += USING_GLSL
+ HEADERS += internal/opengl_glsl_impl.hpp
+ SOURCES += internal/opengl_glsl_es2.cpp \
+ internal/opengl_glsl_impl.cpp
+ } else {
+ SOURCES += internal/opengl_es.cpp
+ }
} else {
- SOURCES += internal/opengl_ext.cpp
+ CONFIG(glsl) {
+ DEFINES += USING_GLSL
+ HEADERS += internal/opengl_glsl_impl.hpp
+ SOURCES += internal/opengl_glsl_ext.cpp \
+ internal/opengl_glsl_impl.cpp
+ } else {
+ SOURCES += internal/opengl_ext.cpp
+ }
}
+
+
+
+