[android][iphone][mac] added support for rendering with GLSL shaders and enabled it by default.

This commit is contained in:
rachytski 2012-04-07 15:21:43 +04:00 committed by Alex Zolotarev
parent ad647d0de6
commit b1740c4329
26 changed files with 798 additions and 78 deletions

View file

@ -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" />

View file

@ -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

View file

@ -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)

View file

@ -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)
{

View file

@ -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()

View file

@ -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()

View file

@ -40,6 +40,7 @@ namespace qt
void RenderContext::endThreadDrawing()
{
m_context.reset();
yg::gl::RenderContext::endThreadDrawing();
}
RenderContext::RenderContext(RenderContext * renderContext)

View file

@ -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();
}

View file

@ -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)

View file

@ -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();

View file

@ -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));
}
}
}

View file

@ -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
}
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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");

View 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;
}
}
}

View 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;
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View file

@ -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()));

View file

@ -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();
}
}
}

View file

@ -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

View file

@ -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));
}
}
}

View file

@ -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)));
}
}
}

View file

@ -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
}
}