forked from organicmaps/organicmaps
[android][iphone][mac] added support for rendering with GLSL shaders and enabled it by default.
This commit is contained in:
parent
ad647d0de6
commit
b1740c4329
26 changed files with 798 additions and 78 deletions
|
@ -7,7 +7,7 @@
|
|||
android:sharedUserId="com.mapswithme"
|
||||
android:sharedUserLabel="@string/app_name">
|
||||
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="14"/>
|
||||
<uses-feature android:glEsVersion="0x00010001" />
|
||||
<uses-feature android:glEsVersion="0x00020000" />
|
||||
<uses-feature android:required="true" android:name="android.hardware.touchscreen.multitouch" />
|
||||
<uses-feature android:required="false" android:name="android.hardware.wifi" />
|
||||
<uses-feature android:required="false" android:name="android.hardware.location" />
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace qt
|
|||
void RenderContext::endThreadDrawing()
|
||||
{
|
||||
m_context.reset();
|
||||
yg::gl::RenderContext::endThreadDrawing();
|
||||
}
|
||||
|
||||
RenderContext::RenderContext(RenderContext * renderContext)
|
||||
|
|
|
@ -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<yg::gl::RenderContext> const & primaryRC, bool doSupportRotation, size_t idCacheSize)
|
||||
|
@ -37,6 +39,7 @@ RenderPolicy::RenderPolicy(shared_ptr<yg::gl::RenderContext> 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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <gl/gl.h>
|
||||
|
@ -19,16 +22,28 @@
|
|||
#include <TargetConditionals.h>
|
||||
|
||||
#ifdef OMIM_OS_IPHONE
|
||||
#define USE_OPENGLES20_IF_AVAILABLE 0
|
||||
#include <OpenGLES/ES1/gl.h>
|
||||
#define OMIM_GL_ES
|
||||
#ifdef USING_GLSL
|
||||
#define USE_OPENGLES20_IF_AVAILABLE 1
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#define OMIM_GL_ES
|
||||
#else
|
||||
#define USE_OPENGLES20_IF_AVAILABLE 0
|
||||
#include <OpenGLES/ES1/gl.h>
|
||||
#define OMIM_GL_ES
|
||||
#endif
|
||||
#else
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glext.h>
|
||||
#endif
|
||||
|
||||
#elif defined(OMIM_OS_ANDROID)
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#ifdef USING_GLSL
|
||||
#include <GLES2/gl2.h>
|
||||
#else
|
||||
#include <GLES/gl.h>
|
||||
#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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
84
yg/internal/opengl_glsl_es2.cpp
Normal file
84
yg/internal/opengl_glsl_es2.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include "opengl.hpp"
|
||||
#include "opengl_glsl_impl.hpp"
|
||||
|
||||
#ifdef OMIM_OS_ANDROID
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GLES2/gl2ext.h>
|
||||
#endif
|
||||
|
||||
#ifdef OMIM_OS_IPHONE
|
||||
#include <TargetConditionals.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
79
yg/internal/opengl_glsl_ext.cpp
Normal file
79
yg/internal/opengl_glsl_ext.cpp
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
369
yg/internal/opengl_glsl_impl.cpp
Normal file
369
yg/internal/opengl_glsl_impl.cpp
Normal file
|
@ -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<float, 4, 4> 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<threads::ThreadID, glsl::ThreadData> 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<float, 4>();
|
||||
}
|
||||
|
||||
void glOrtho(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
|
||||
{
|
||||
ThreadData & threadData = g_threadData[threads::GetCurrentThreadID()];
|
||||
|
||||
math::Matrix<float, 4, 4> m = math::Identity<float, 4>();
|
||||
|
||||
/// 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<float, 4, 4> const & projM = threadData.m_matrices[GL_PROJECTION_MWM];
|
||||
math::Matrix<float, 4, 4> 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);
|
||||
}
|
||||
}
|
||||
}
|
25
yg/internal/opengl_glsl_impl.hpp
Normal file
25
yg/internal/opengl_glsl_impl.hpp
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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()));
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace yg
|
|||
/// Create a render context which is shared with this one.
|
||||
virtual shared_ptr<RenderContext> 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
|
||||
|
|
19
yg/utils.cpp
19
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
25
yg/yg.pro
25
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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue