summaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/CAPI/GL
diff options
context:
space:
mode:
Diffstat (limited to 'LibOVR/Src/CAPI/GL')
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp122
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h5
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h4
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp219
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h4
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp165
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_Util.h60
7 files changed, 368 insertions, 211 deletions
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp
index bb52d98..2c903b6 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp
@@ -98,6 +98,9 @@ DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager
{
DistortionMeshVAOs[0] = 0;
DistortionMeshVAOs[1] = 0;
+
+ // Initialize render params.
+ memset(&RParams, 0, sizeof(RParams));
}
DistortionRenderer::~DistortionRenderer()
@@ -155,7 +158,6 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig,
RParams.Win = config->OGL.Win;
if (!RParams.Win)
{
- int unused;
RParams.Win = glXGetCurrentDrawable();
}
if (!RParams.Win)
@@ -270,9 +272,16 @@ void DistortionRenderer::EndFrame(bool swapBuffers)
if (swapBuffers)
{
bool useVsync = ((RState.EnabledHmdCaps & ovrHmdCap_NoVSync) == 0);
- int swapInterval = (useVsync) ? 1 : 0;
+ int swapInterval = (useVsync) ? 1 : 0;
#if defined(OVR_OS_WIN32)
- if (wglGetSwapIntervalEXT() != swapInterval)
+#ifndef NO_SCREEN_TEAR_HEALING
+ if (TimeManager.ScreenTearingReaction())
+ {
+ swapInterval = 0;
+ useVsync = false;
+ }
+#endif // NO_SCREEN_TEAR_HEALING
+ if (wglGetSwapIntervalEXT() != swapInterval)
wglSwapIntervalEXT(swapInterval);
HDC dc = (RParams.DC != NULL) ? RParams.DC : GetDC(RParams.Window);
@@ -297,7 +306,7 @@ void DistortionRenderer::EndFrame(bool swapBuffers)
{
GLuint currentSwapInterval = 0;
glXQueryDrawable(RParams.Disp, RParams.Win, GLX_SWAP_INTERVAL_EXT, &currentSwapInterval);
- if (currentSwapInterval != swapInterval)
+ if (currentSwapInterval != (GLuint)swapInterval)
glXSwapIntervalEXT(RParams.Disp, RParams.Win, swapInterval);
}
@@ -332,58 +341,17 @@ double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime)
return WaitTillTime(absTime);
}
-
-
+
+
DistortionRenderer::GraphicsState::GraphicsState()
{
- bool foundVersion = false;
- const char* glVersionString = (const char*)glGetString(GL_VERSION);
- if (glVersionString)
- {
- OVR_DEBUG_LOG(("GL_VERSION STRING: %s", (const char*)glVersionString));
- char prefix[64];
+ GetGLVersionAndExtensions(GLVersionInfo);
+}
- for (int i = 10; i < 30; ++i)
- {
- int major = i / 10;
- int minor = i % 10;
- OVR_sprintf(prefix, 64, "%d.%d", major, minor);
- if (strstr(glVersionString, prefix) == glVersionString)
- {
- GlMajorVersion = major;
- GlMinorVersion = minor;
- foundVersion = true;
- break;
- }
- }
- }
-
- if (!foundVersion)
- {
- glGetIntegerv(GL_MAJOR_VERSION, &GlMajorVersion);
- glGetIntegerv(GL_MAJOR_VERSION, &GlMinorVersion);
- }
- OVR_ASSERT(GlMajorVersion >= 2);
-
- if (GlMajorVersion >= 3)
- {
- SupportsVao = true;
- SupportsDrawBuffers = true;
- }
- else
- {
- const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
- SupportsVao = (strstr(extensions, "GL_ARB_vertex_array_object") != NULL
- || strstr(extensions, "GL_APPLE_vertex_array_object") != NULL);
- SupportsDrawBuffers = (strstr(extensions, "GL_EXT_draw_buffers2") != NULL);
- }
-}
-
-
void DistortionRenderer::GraphicsState::ApplyBool(GLenum Name, GLint Value, GLint index)
{
- if (SupportsDrawBuffers && index != -1)
+ if (GLVersionInfo.SupportsDrawBuffers && index != -1)
{
if (Value != 0)
glEnablei(Name, index);
@@ -410,7 +378,7 @@ void DistortionRenderer::GraphicsState::Save()
glGetIntegerv(GL_CURRENT_PROGRAM, &Program);
glGetIntegerv(GL_ACTIVE_TEXTURE, &ActiveTexture);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &TextureBinding);
- if (SupportsVao)
+ if (GLVersionInfo.SupportsVAO)
{
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &VertexArrayBinding);
}
@@ -420,7 +388,7 @@ void DistortionRenderer::GraphicsState::Save()
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &ArrayBufferBinding);
}
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &FrameBufferBinding);
- if (SupportsDrawBuffers)
+ if (GLVersionInfo.SupportsDrawBuffers)
{
glGetIntegeri_v(GL_BLEND, 0, &Blend);
glGetIntegeri_v(GL_COLOR_WRITEMASK, 0, ColorWritemask);
@@ -432,8 +400,10 @@ void DistortionRenderer::GraphicsState::Save()
}
glGetIntegerv(GL_DITHER, &Dither);
glGetIntegerv(GL_RASTERIZER_DISCARD, &RasterizerDiscard);
- if ((GlMajorVersion == 3 && GlMinorVersion >= 2) || GlMajorVersion >= 4)
+ if ((GLVersionInfo.MajorVersion == 3 && GLVersionInfo.MinorVersion >= 2) || GLVersionInfo.MajorVersion >= 4)
+ {
glGetIntegerv(GL_SAMPLE_MASK, &SampleMask);
+ }
IsValid = true;
}
@@ -441,7 +411,7 @@ void DistortionRenderer::GraphicsState::Save()
#ifdef OVR_OS_MAC
bool DistortionRenderer::GraphicsState::isAtLeastOpenGL3()
{
- return !(GlMajorVersion < 3|| (GlMajorVersion == 3 && GlMinorVersion < 2));
+ return (((GLVersionInfo.MajorVersion * 100) + GLVersionInfo.MinorVersion) >= 302); // OpenGL 3.2 or later
}
#endif
@@ -461,7 +431,7 @@ void DistortionRenderer::GraphicsState::Restore()
glUseProgram(Program);
glActiveTexture(ActiveTexture);
glBindTexture(GL_TEXTURE_2D, TextureBinding);
- if (SupportsVao)
+ if (GLVersionInfo.SupportsVAO)
{
#ifdef OVR_OS_MAC
if (isAtLeastOpenGL3())
@@ -485,15 +455,22 @@ void DistortionRenderer::GraphicsState::Restore()
ApplyBool(GL_BLEND, Blend, 0);
- if (SupportsDrawBuffers)
+ if (GLVersionInfo.SupportsDrawBuffers)
+ {
glColorMaski(0, (GLboolean)ColorWritemask[0], (GLboolean)ColorWritemask[1], (GLboolean)ColorWritemask[2], (GLboolean)ColorWritemask[3]);
+ }
else
+ {
glColorMask((GLboolean)ColorWritemask[0], (GLboolean)ColorWritemask[1], (GLboolean)ColorWritemask[2], (GLboolean)ColorWritemask[3]);
+ }
ApplyBool(GL_DITHER, Dither);
ApplyBool(GL_RASTERIZER_DISCARD, RasterizerDiscard);
- if ((GlMajorVersion == 3 && GlMinorVersion >= 2) || GlMajorVersion >= 4)
+ if ((GLVersionInfo.MajorVersion == 3 && GLVersionInfo.MinorVersion >= 2) ||
+ GLVersionInfo.MajorVersion >= 4)
+ {
ApplyBool(GL_SAMPLE_MASK, SampleMask);
+ }
}
@@ -525,9 +502,13 @@ void DistortionRenderer::initBuffersAndShaders()
{
pCurVBVert->ScreenPosNDC.x = pCurOvrVert->ScreenPosNDC.x;
pCurVBVert->ScreenPosNDC.y = pCurOvrVert->ScreenPosNDC.y;
- pCurVBVert->TanEyeAnglesR = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesR);
- pCurVBVert->TanEyeAnglesG = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesG);
- pCurVBVert->TanEyeAnglesB = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesB);
+
+ // Previous code here did this: pCurVBVert->TanEyeAnglesR = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesR); However that's an usafe
+ // cast of unrelated types which can result in undefined behavior by a conforming compiler. A safe equivalent is simply memcpy.
+ static_assert(sizeof(OVR::Vector2f) == sizeof(ovrVector2f), "Mismatch of structs that are presumed binary equivalents.");
+ memcpy(&pCurVBVert->TanEyeAnglesR, &pCurOvrVert->TanEyeAnglesR, sizeof(pCurVBVert->TanEyeAnglesR));
+ memcpy(&pCurVBVert->TanEyeAnglesG, &pCurOvrVert->TanEyeAnglesG, sizeof(pCurVBVert->TanEyeAnglesG));
+ memcpy(&pCurVBVert->TanEyeAnglesB, &pCurOvrVert->TanEyeAnglesB, sizeof(pCurVBVert->TanEyeAnglesB));
// Convert [0.0f,1.0f] to [0,255]
if (DistortionCaps & ovrDistortionCap_Vignette)
@@ -569,7 +550,7 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
- if (glState->SupportsDrawBuffers)
+ if (glState->GLVersionInfo.SupportsDrawBuffers)
{
glDisablei(GL_BLEND, 0);
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
@@ -582,8 +563,10 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ
glDisable(GL_DITHER);
glDisable(GL_RASTERIZER_DISCARD);
- if ((glState->GlMajorVersion >= 3 && glState->GlMinorVersion >= 2) || glState->GlMajorVersion >= 4)
+ if ((glState->GLVersionInfo.MajorVersion >= 3 && glState->GLVersionInfo.MinorVersion >= 2) || glState->GLVersionInfo.MajorVersion >= 4)
+ {
glDisable(GL_SAMPLE_MASK);
+ }
glClearColor(
RState.ClearColor[0],
@@ -780,7 +763,7 @@ void DistortionRenderer::renderPrimitives(
}
else
{
- if (glState->SupportsVao)
+ if (glState->GLVersionInfo.SupportsVAO)
{
#ifdef OVR_OS_MAC
if (glState->isAtLeastOpenGL3())
@@ -836,7 +819,7 @@ void DistortionRenderer::renderPrimitives(
glDrawArrays(prim, 0, count);
- if (!glState->SupportsVao)
+ if (!glState->GLVersionInfo.SupportsVAO)
{
for (int i = 0; i < attributeCount; ++i)
glDisableVertexAttribArray(locs[i]);
@@ -844,7 +827,7 @@ void DistortionRenderer::renderPrimitives(
delete[] locs;
- if (glState->SupportsVao)
+ if (glState->GLVersionInfo.SupportsVAO)
{
#ifdef OVR_OS_MAC
if (glState->isAtLeastOpenGL3())
@@ -874,7 +857,8 @@ void DistortionRenderer::initShaders()
GraphicsState* glState = (GraphicsState*)GfxState.GetPtr();
const char* shaderPrefix =
- (glState->GlMajorVersion < 3 || (glState->GlMajorVersion == 3 && glState->GlMinorVersion < 2)) ?
+ (glState->GLVersionInfo.MajorVersion < 3 ||
+ (glState->GLVersionInfo.MajorVersion == 3 && glState->GLVersionInfo.MinorVersion < 2)) ?
glsl2Prefix : glsl3Prefix;
{
@@ -979,11 +963,13 @@ void DistortionRenderer::destroy()
SaveGraphicsState();
GraphicsState* glState = (GraphicsState*)GfxState.GetPtr();
-
+
for(int eyeNum = 0; eyeNum < 2; eyeNum++)
{
- if (glState->SupportsVao)
+ if (glState->GLVersionInfo.SupportsVAO)
+ {
glDeleteVertexArrays(1, &DistortionMeshVAOs[eyeNum]);
+ }
DistortionMeshVAOs[eyeNum] = 0;
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h
index 9189ae6..1017c6e 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h
@@ -77,10 +77,7 @@ protected:
void ApplyBool(GLenum Name, GLint Value, GLint index = -1);
public:
- GLint GlMajorVersion;
- GLint GlMinorVersion;
- bool SupportsVao;
- bool SupportsDrawBuffers;
+ GLVersionAndExtensions GLVersionInfo;
GLint Viewport[4];
GLfloat ClearColor[4];
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h
index 5c68c50..76e8c81 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h
@@ -30,6 +30,7 @@ namespace OVR { namespace CAPI { namespace GL {
"#define _VS_OUT varying\n"
"#define _FS_IN varying\n"
"#define _TEXTURELOD texture2DLod\n"
+ "#define _TEXTURE texture2D\n"
"#define _FRAGCOLOR gl_FragColor\n";
static const char glsl3Prefix[] =
@@ -39,6 +40,7 @@ namespace OVR { namespace CAPI { namespace GL {
"#define _VS_OUT out\n"
"#define _FS_IN in\n"
"#define _TEXTURELOD textureLod\n"
+ "#define _TEXTURE texture\n"
"#define _FRAGCOLOR FragColor\n";
static const char SimpleQuad_vs[] =
@@ -127,7 +129,7 @@ namespace OVR { namespace CAPI { namespace GL {
"void main()\n"
"{\n"
- " _FRAGCOLOR = oColor * texture2D(Texture0, oTexCoord);\n"
+ " _FRAGCOLOR = oColor * _TEXTURE(Texture0, oTexCoord);\n"
"}\n";
// The following is copied from the generated D3D SimpleTexturedQuad_ps_refl.h file, with D3D_NS renamed to GL.
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp
index 6c0106d..f024ac5 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp
@@ -232,9 +232,6 @@ Texture* LoadTextureTga(RenderParams& rParams, int samplerMode, const uint8_t* p
HSWDisplay::HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState)
: OVR::CAPI::HSWDisplay(api, hmd, renderState)
, RenderParams()
- , GLMajorVersion(0)
- , GLMinorVersion(0)
- , SupportsVao(false)
, FrameBuffer(0)
, pTexture()
, pShaderSet()
@@ -276,10 +273,8 @@ bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig)
if (config->OGL.Win)
RenderParams.Win= config->OGL.Win;
if (!RenderParams.Win)
- {
- int unused;
RenderParams.Win = glXGetCurrentDrawable();
- }
+
if (!RenderParams.Win)
{
OVR_DEBUG_LOG(("XGetInputFocus failed."));
@@ -332,17 +327,14 @@ void HSWDisplay::UnloadGraphics()
if(VAO)
{
#ifdef OVR_OS_MAC
- if(GLMajorVersion >= 3)
- {
- glDeleteVertexArrays(1, &VAO);
- }
- else
- {
- glDeleteVertexArraysAPPLE(1, &VAO);
- }
- #else
+ if(GLVersionInfo.WholeVersion >= 302)
+ glDeleteVertexArrays(1, &VAO);
+ else
+ glDeleteVertexArraysAPPLE(1, &VAO);
+ #else
glDeleteVertexArrays(1, &VAO);
#endif
+
VAO = 0;
VAOInitialized = false;
}
@@ -352,31 +344,10 @@ void HSWDisplay::UnloadGraphics()
void HSWDisplay::LoadGraphics()
{
- const char* glVersionString = (const char*)glGetString(GL_VERSION);
-
- OVR_ASSERT(glVersionString);
- if (glVersionString)
- {
- int fieldCount = sscanf(glVersionString, isdigit(*glVersionString) ? "%d.%d" : "%*[^0-9]%d.%d", &GLMajorVersion, &GLMinorVersion); // Skip all leading non-digits before reading %d. Example glVersionStrings: "1.5 ATI-1.4.18", "OpenGL ES-CM 3.2"
-
- if(fieldCount != 2)
- {
- static_assert(sizeof(GLMajorVersion) == sizeof(GLint), "type mis-match");
- glGetIntegerv(GL_MAJOR_VERSION, &GLMajorVersion);
- }
- }
-
- // SupportsVao
- if(GLMajorVersion >= 3)
- SupportsVao = true;
- else
- {
- const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
- SupportsVao = (strstr(extensions, "GL_ARB_vertex_array_object") || strstr(extensions, "GL_APPLE_vertex_array_object"));
- }
-
if (FrameBuffer == 0)
+ {
glGenFramebuffers(1, &FrameBuffer);
+ }
if (!pTexture) // To do: Add support for .dds files, which would be significantly smaller than the size of the tga.
{
@@ -385,12 +356,14 @@ void HSWDisplay::LoadGraphics()
pTexture = *LoadTextureTga(RenderParams, Sample_Linear | Sample_Clamp, TextureData, (int)textureSize, 255);
}
- if(!pShaderSet)
+ if (!pShaderSet)
+ {
pShaderSet = *new ShaderSet();
+ }
if(!pVertexShader)
{
- OVR::String strShader((GLMajorVersion >= 3) ? glsl3Prefix : glsl2Prefix);
+ OVR::String strShader((GLVersionInfo.MajorVersion >= 3) ? glsl3Prefix : glsl2Prefix);
strShader += SimpleTexturedQuad_vs;
pVertexShader = *new VertexShader(&RenderParams, const_cast<char*>(strShader.ToCStr()), strShader.GetLength(), SimpleTexturedQuad_vs_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_vs_refl));
@@ -399,7 +372,7 @@ void HSWDisplay::LoadGraphics()
if(!pFragmentShader)
{
- OVR::String strShader((GLMajorVersion >= 3) ? glsl3Prefix : glsl2Prefix);
+ OVR::String strShader((GLVersionInfo.MajorVersion >= 3) ? glsl3Prefix : glsl2Prefix);
strShader += SimpleTexturedQuad_ps;
pFragmentShader = *new FragmentShader(&RenderParams, const_cast<char*>(strShader.ToCStr()), strShader.GetLength(), SimpleTexturedQuad_ps_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_ps_refl));
@@ -432,18 +405,15 @@ void HSWDisplay::LoadGraphics()
}
// We don't generate the vertex arrays here
- if(!VAO && SupportsVao)
+ if (!VAO && GLVersionInfo.SupportsVAO)
{
OVR_ASSERT(!VAOInitialized);
+
#ifdef OVR_OS_MAC
- if(GLMajorVersion >= 3)
- {
- glGenVertexArrays(1, &VAO);
- }
- else
- {
- glGenVertexArraysAPPLE(1, &VAO);
- }
+ if(GLVersionInfo.WholeVersion >= 302)
+ glGenVertexArrays(1, &VAO);
+ else
+ glGenVertexArraysAPPLE(1, &VAO);
#else
glGenVertexArrays(1, &VAO);
#endif
@@ -455,9 +425,13 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
{
if(RenderEnabled && eyeTexture)
{
- // Hack - Clear previous errors.
+ // glGetError clears any previous error state. We call it here in order to start with
+ // a clean slate, as we are asserting below that our calls do not generate errors.
glGetError();
+ if(GLVersionInfo.MajorVersion == 0) // If not yet initialized...
+ GetGLVersionAndExtensions(GLVersionInfo);
+
// We need to render to the eyeTexture with the texture viewport.
// Setup rendering to the texture.
ovrGLTexture* eyeTextureGL = const_cast<ovrGLTexture*>(reinterpret_cast<const ovrGLTexture*>(eyeTexture));
@@ -468,15 +442,19 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
// Save state
// To do: Converge this with the state setting/restoring functionality present in the distortion renderer.
+ // Consider usage of the EXT_direct_state_access (http://www.opengl.org/registry/specs/EXT/direct_state_access.txt) extension.
// Note that the glGet functions below will block until command buffer has completed.
// glPushAttrib is deprecated, so we use glGet* to save/restore fixed-function settings.
// https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glGet.xml
//
- GLint RenderModeSaved;
- glGetIntegerv(GL_RENDER_MODE, &RenderModeSaved);
- OVR_ASSERT(glGetError() == 0);
- OVR_ASSERT(RenderModeSaved == GL_RENDER); // Make sure it's not GL_SELECT or GL_FEEDBACK.
-
+ GLint RenderModeSaved = 0;
+ if(!GLVersionInfo.IsCoreProfile) // glGetIntegerv can fail if an OpenGL 3.x+ core profile is enabled due to GL_RENDER_MODE being no longer supported.
+ {
+ glGetIntegerv(GL_RENDER_MODE, &RenderModeSaved);
+ OVR_ASSERT(glGetError() == 0);
+ OVR_ASSERT(RenderModeSaved == GL_RENDER); // Make sure it's not GL_SELECT or GL_FEEDBACK.
+ }
+
GLint FrameBufferBindingSaved; // OpenGL renamed GL_FRAMEBUFFER_BINDING to GL_DRAW_FRAMEBUFFER_BINDING and adds GL_READ_FRAMEBUFFER_BINDING.
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &FrameBufferBindingSaved);
OVR_ASSERT(glGetError() == 0);
@@ -494,8 +472,8 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
OVR_ASSERT(glGetError() == 0);
GLdouble DepthRangeSaved[2];
- #if defined(OVR_OS_MAC)
- // Using glDepthRange as a conditional will always evaluate to true on Mac.
+ #if defined(OVR_OS_MAC) || defined(OVR_OS_LINUX)
+ // Using glDepthRange as a conditional will always evaluate to true on Mac/Linux.
glGetDoublev(GL_DEPTH_RANGE, DepthRangeSaved);
#else
GLfloat DepthRangefSaved[2];
@@ -547,7 +525,7 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
OVR_ASSERT(glGetError() == 0);
GLint SampleMaskSaved = 0;
- if(((GLMajorVersion * 100) + GLMinorVersion) >= 302) // OpenGL 3.2 or later
+ if (GLVersionInfo.WholeVersion >= 302) // OpenGL 3.2 or later
{
glGetIntegerv(GL_SAMPLE_MASK, &SampleMaskSaved);
OVR_ASSERT(glGetError() == 0);
@@ -572,37 +550,46 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
glGetIntegerv(GL_TEXTURE_BINDING_2D, &TextureBindingSaved);
OVR_ASSERT(glGetError() == 0);
- // https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glVertexAttribPointer.xml
+ GLint VertexArrayBindingSaved = 0;
+ if (GLVersionInfo.SupportsVAO)
+ glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &VertexArrayBindingSaved);
+
+ // If the core profile is enabled then we can't get the vertex attributes unless there is
+ // an active VAO. Otherwise there can be an error with some OpenGL implementations (notably Apple's).
+ // If the core profile is not enabled then pre-OpenGL 3.0 behavior is possible in which the
+ // application may not be using VAOs and thus there may be active vertex attributes.
GLint VertexAttribEnabledSaved[kSavedVertexAttribCount];
GLint VertexAttribSizeSaved[kSavedVertexAttribCount];
GLint VertexAttribTypeSaved[kSavedVertexAttribCount];
GLint VertexAttribNormalizedSaved[kSavedVertexAttribCount];
GLint VertexAttribStrideSaved[kSavedVertexAttribCount];
GLvoid* VertexAttribPointerSaved[kSavedVertexAttribCount];
- for(GLuint i = 0; i < kSavedVertexAttribCount; i++)
+
+ if(VertexArrayBindingSaved || !GLVersionInfo.IsCoreProfile)
{
- glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &VertexAttribEnabledSaved[i]);
+ for(GLuint i = 0; i < kSavedVertexAttribCount; i++)
+ {
+ // https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glVertexAttribPointer.xml
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &VertexAttribEnabledSaved[i]);
- glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &VertexAttribSizeSaved[i]);
- glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &VertexAttribTypeSaved[i]);
- glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &VertexAttribNormalizedSaved[i]);
- glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &VertexAttribStrideSaved[i]);
- glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &VertexAttribPointerSaved[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &VertexAttribSizeSaved[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &VertexAttribTypeSaved[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &VertexAttribNormalizedSaved[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &VertexAttribStrideSaved[i]);
+ glGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &VertexAttribPointerSaved[i]);
- OVR_ASSERT(glGetError() == 0);
+ OVR_ASSERT(glGetError() == 0);
+ }
}
-
- GLint VertexArrayBindingSaved = 0;
- if (SupportsVao)
- glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &VertexArrayBindingSaved);
-
//
// End of save state
// Load the graphics if not loaded already.
if (!pTexture)
+ {
LoadGraphics();
+ }
// Calculate ortho projection.
GetOrthoProjection(RenderState, OrthoProjection);
@@ -628,10 +615,10 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
// Set fixed-function render states
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
OVR_ASSERT(glGetError() == 0);
- #if defined(OVR_OS_MAC) // On Mac we are directly using OpenGL functions instead of function pointers.
+ #if defined(OVR_OS_MAC) || defined(OVR_OS_LINUX) // On Mac/Linux we are directly using OpenGL functions instead of function pointers.
glDepthRange(0.0, 1.0);
#else
- if(glDepthRange) // If we can use the double version (glDepthRangef may not be available)...
+ if(glDepthRange) // If we can use the double version (glDepthRangef isn't available with older OpenGL, glDepthRange isn't available with OpenGL ES)...
glDepthRange(0.0, 1.0);
else
glDepthRangef(0.f, 1.f);
@@ -645,8 +632,10 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
glDisable(GL_DITHER);
glDisable(GL_RASTERIZER_DISCARD);
glDisable(GL_SCISSOR_TEST);
- if(((GLMajorVersion * 100) + GLMinorVersion) >= 302) // OpenGL 3.2 or later
+ if (GLVersionInfo.WholeVersion >= 302) // OpenGL 3.2 or later
+ {
glDisable(GL_SAMPLE_MASK);
+ }
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
OVR_ASSERT(glGetError() == 0);
@@ -668,18 +657,15 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
// To do: We must add support for vertext array objects (VAOs) here. When using an OpenGL 3.2+ core profile,
// the application is required to use vertex array objects and glVertexAttribPointer will fail otherwise.
- if(SupportsVao)
+ if (GLVersionInfo.SupportsVAO)
{
OVR_ASSERT(VAO != 0);
+
#ifdef OVR_OS_MAC
- if(GLMajorVersion >= 3)
- {
- glBindVertexArray(VAO);
- }
- else
- {
- glBindVertexArrayAPPLE(VAO);
- }
+ if(GLVersionInfo.WholeVersion >= 302)
+ glBindVertexArray(VAO);
+ else
+ glBindVertexArrayAPPLE(VAO);
#else
glBindVertexArray(VAO);
#endif
@@ -718,19 +704,15 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
OVR_ASSERT(glGetError() == 0);
- if(SupportsVao)
+ if (GLVersionInfo.SupportsVAO)
{
VAOInitialized = true;
#ifdef OVR_OS_MAC
- if(GLMajorVersion >= 3)
- {
- glBindVertexArray(0);
- }
- else
- {
+ if(GLVersionInfo.WholeVersion >= 302)
+ glBindVertexArray(0);
+ else
glBindVertexArrayAPPLE(0);
- }
#else
glBindVertexArray(0);
#endif
@@ -740,31 +722,21 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
// We restore the state in the reverse order that we saved it.
// To do: Make the code below avoid changes that are effectively no-ops.
//
- if (SupportsVao)
+ if (GLVersionInfo.SupportsVAO)
{
-#ifdef OVR_OS_MAC
- if(GLMajorVersion >= 3)
- {
+ #ifdef OVR_OS_MAC
+ if(GLVersionInfo.WholeVersion >= 302)
+ glBindVertexArray(VertexArrayBindingSaved);
+ else
+ glBindVertexArrayAPPLE(VertexArrayBindingSaved);
+ #else
glBindVertexArray(VertexArrayBindingSaved);
- }
- else
- {
- glBindVertexArrayAPPLE(VertexArrayBindingSaved);
- }
-#else
- glBindVertexArray(VertexArrayBindingSaved);
-#endif
+ #endif
}
- for (GLuint i = 0; i < kSavedVertexAttribCount; i++)
+ if(VertexArrayBindingSaved || !GLVersionInfo.IsCoreProfile) // If the OpenGL version is older or in core profile compatibility mode, or if there's a VAO currently installed...
{
- // We have a problem here: if the GL context was initialized with a core profile version 3.x or later, calls to glVertexAttribPointer can fail when there is no Vertex Array Object
- // in place. That case is possible here, and we don't have an easy means to detect that a core profile was specified and thus that the glVertexAttribPointer call below could fail.
- // Our current solution is to call glVertexAttribPointer only if vertex array objects are not supported. We cannot simply decide based on whether the given vertex attrib was enabled
- // or if there was a vertex array object installed. With our solution below a problem can occur when using OpenGL 3.x+ which supports VAOs, the user has vertex attrib pointers installed,
- // the currently installed VAO is 0, and the user is somehow dependent on us returning to the user with those vertex attrib pointers reinstalled.
-
- if (!SupportsVao || (VertexArrayBindingSaved != 0)) // If the OpenGL version is older or in core profile compatibility mode, or if there's a VAO currently installed...
+ for (GLuint i = 0; i < kSavedVertexAttribCount; i++)
{
glVertexAttribPointer(i, VertexAttribSizeSaved[i], VertexAttribTypeSaved[i], (GLboolean)VertexAttribNormalizedSaved[i], VertexAttribStrideSaved[i], VertexAttribPointerSaved[i]);
@@ -776,14 +748,14 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
OVR_ASSERT(glGetError() == 0);
}
}
-
+
glBindTexture(GL_TEXTURE_2D, TextureBindingSaved);
glActiveTexture(ActiveTextureSaved);
glUseProgram(ProgramSaved);
glBindBuffer(GL_ARRAY_BUFFER, ArrayBufferBindingSaved);
glColorMask((GLboolean)ColorWriteMaskSaved[0], (GLboolean)ColorWriteMaskSaved[1], (GLboolean)ColorWriteMaskSaved[2], (GLboolean)ColorWriteMaskSaved[3]);
- if(((GLMajorVersion * 100) + GLMinorVersion) >= 302) // OpenGL 3.2 or later
+ if (GLVersionInfo.WholeVersion >= 302) // OpenGL 3.2 or later
{
if(SampleMaskSaved)
glEnable(GL_SAMPLE_MASK);
@@ -806,7 +778,8 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
else
glDisable(GL_DITHER);
- glBlendFunc(BlendSrcRGBSaved, BlendDstRGBSaved); // What about BlendSrcAlphaSaved / BlendDstAlphaSaved?
+ // With OpenGL 4.0+, we may need to be aware of glBlendFuncSeparatei.
+ glBlendFuncSeparate(BlendSrcRGBSaved, BlendDstRGBSaved, BlendSrcAlphaSaved, BlendDstAlphaSaved);
if(BlendSaved)
glEnable(GL_BLEND);
@@ -826,7 +799,7 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
glDisable(GL_DEPTH_TEST);
glDepthMask(DepthWriteMaskSaved ? GL_TRUE : GL_FALSE);
- #if defined(OVR_OS_MAC) // On Mac we are directly using OpenGL functions instead of function pointers.
+ #if defined(OVR_OS_MAC) || defined(OVR_OS_LINUX) // On Mac/Linux we are directly using OpenGL functions instead of function pointers.
glDepthRange(DepthRangeSaved[0], DepthRangeSaved[1]);
#else
if(glDepthRange) // If we can use the double version (glDepthRangef may not be available)...
@@ -839,7 +812,9 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
glViewport(ViewportSaved[0], ViewportSaved[1], ViewportSaved[2], ViewportSaved[3]);
glBindTexture(GL_TEXTURE_2D, TextureBinding2DSaved);
glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferBindingSaved);
- //glRenderMode(RenderModeSaved);
+
+ if(!GLVersionInfo.IsCoreProfile)
+ glRenderMode(RenderModeSaved);
OVR_ASSERT(glGetError() == 0);
//
@@ -848,12 +823,4 @@ void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
}
-
}}} // namespace OVR::CAPI::GL
-
-
-
-
-
-
-
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h
index 3517157..4b110d5 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h
@@ -55,9 +55,7 @@ namespace OVR { namespace CAPI { namespace GL {
void LoadGraphics();
OVR::CAPI::GL::RenderParams RenderParams;
- int GLMajorVersion; // Derived from glGetString(GL_VERSION). To consider: Move this into GL::RenderParams.
- int GLMinorVersion; //
- bool SupportsVao; // True if Vertex Array Objects are supported by the OpenGL version.
+ GLVersionAndExtensions GLVersionInfo;
GLuint FrameBuffer; // This is a container for a texture, depth buffer, stencil buffer to be rendered to. To consider: Make a wrapper class, like the OculusWorldDemo RBuffer class.
Ptr<OVR::CAPI::GL::Texture> pTexture;
Ptr<OVR::CAPI::GL::ShaderSet> pShaderSet;
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp
index 22482d8..ed9e654 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp
@@ -28,7 +28,6 @@ limitations under the License.
namespace OVR { namespace CAPI { namespace GL {
-
// GL Hooks for non-Mac.
#if !defined(OVR_OS_MAC)
@@ -78,6 +77,7 @@ PFNGLENABLEIPROC glEnablei;
PFNGLDISABLEIPROC glDisablei;
PFNGLCOLORMASKIPROC glColorMaski;
PFNGLGETINTEGERI_VPROC glGetIntegeri_v;
+PFNGLGETSTRINGIPROC glGetStringi;
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
PFNGLDELETESHADERPROC glDeleteShader;
@@ -124,7 +124,7 @@ PFNGLUNIFORM1FVPROC glUniform1fv;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
-PFNGLFEEDBACKBUFFERPROC glFeedbackBuffer;
+PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
#if defined(OVR_OS_WIN32)
@@ -191,6 +191,7 @@ void InitGLExtensions()
glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) GetFunction("glXSwapIntervalEXT");
#endif
+ glGetStringi = (PFNGLGETSTRINGIPROC) GetFunction("glGetStringi");
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) GetFunction("glGenFramebuffersEXT");
glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) GetFunction("glDeleteFramebuffersEXT");
glEnablei = (PFNGLENABLEIPROC) GetFunction("glEnableIndexedEXT");
@@ -242,7 +243,7 @@ void InitGLExtensions()
glDetachShader = (PFNGLDETACHSHADERPROC) GetFunction("glDetachShader");
glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) GetFunction("glBindAttribLocation");
glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) GetFunction("glGetAttribLocation");
- glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC) GetFunction("glFeedbackBuffer");
+ glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) GetFunction("glBlendFuncSeparate");
}
#endif
@@ -499,7 +500,7 @@ void ShaderBase::InitUniforms(const Uniform* refl, size_t reflSize)
UniformData = (unsigned char*)OVR_ALLOC(UniformsSize);
}
-Texture::Texture(RenderParams* rp, int w, int h) : IsUserAllocated(true), pParams(rp), TexId(0), Width(w), Height(h)
+Texture::Texture(RenderParams* rp, int w, int h) : IsUserAllocated(false), pParams(rp), TexId(0), Width(w), Height(h)
{
if (w && h)
glGenTextures(1, &TexId);
@@ -573,6 +574,160 @@ void Texture::UpdatePlaceholderTexture(GLuint texId, const Sizei& textureSize)
}
-}}}
+//// GLVersion
+
+void GLVersionAndExtensions::ParseGLVersion()
+{
+ const char* version = (const char*)glGetString(GL_VERSION);
+ int fields = 0, major = 0, minor = 0;
+ bool isGLES = false;
+
+ OVR_ASSERT(version);
+ if (version)
+ {
+ OVR_DEBUG_LOG(("GL_VERSION: %s", (const char*)version));
+
+ // Skip all leading non-digits before reading %d.
+ // Example GL_VERSION strings:
+ // "1.5 ATI-1.4.18"
+ // "OpenGL ES-CM 3.2"
+ OVR_DISABLE_MSVC_WARNING(4996) // "scanf may be unsafe"
+ fields = sscanf(version, isdigit(*version) ? "%d.%d" : "%*[^0-9]%d.%d", &major, &minor);
+ isGLES = (strstr(version, "OpenGL ES") != NULL);
+ OVR_RESTORE_MSVC_WARNING()
+ }
+ else
+ {
+ LogText("Warning: GL_VERSION was NULL\n");
+ }
+
+ // If two fields were not found,
+ if (fields != 2)
+ {
+ static_assert(sizeof(major) == sizeof(GLint), "type mis-match");
+
+ glGetIntegerv(GL_MAJOR_VERSION, &major);
+ glGetIntegerv(GL_MINOR_VERSION, &minor);
+ }
+
+ // Write version data
+ MajorVersion = major;
+ MinorVersion = minor;
+ WholeVersion = (major * 100) + minor;
+ IsGLES = isGLES;
+ IsCoreProfile = (MajorVersion >= 3); // Until we get a better way to detect core profiles, we err on the conservative side and set to true if the version is >= 3.
+}
+
+
+bool GLVersionAndExtensions::HasGLExtension(const char* searchKey) const
+{
+ if(Extensions && Extensions[0]) // If we have an extension string to search for individual extensions...
+ {
+ const int searchKeyLen = (int)strlen(searchKey);
+ const char* p = Extensions;
+
+ for (;;)
+ {
+ p = strstr(p, searchKey);
+
+ // If not found,
+ if (p == NULL)
+ {
+ break;
+ }
+
+ // Only match full string
+ if ((p == Extensions || p[-1] == ' ') &&
+ (p[searchKeyLen] == '\0' || p[searchKeyLen] == ' '))
+ {
+ return true;
+ }
+
+ // Skip ahead
+ p += searchKeyLen;
+ }
+ }
+ else
+ {
+ if(MajorVersion >= 3) // If glGetIntegerv(GL_NUM_EXTENSIONS, ...) is supported...
+ {
+ GLint extensionCount = 0;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount);
+ GLenum err = glGetError();
+
+ if(err == 0)
+ {
+ for(GLint i = 0; i != extensionCount; ++i)
+ {
+ const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, (GLuint)i);
+
+ if(extension) // glGetStringi returns NULL upon error.
+ {
+ if(strcmp(extension, searchKey) == 0)
+ return true;
+ }
+ else
+ break;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+void GLVersionAndExtensions::ParseGLExtensions()
+{
+ if(MajorVersion >= 3)
+ {
+ // Set to empty because we need to use glGetStringi to read extensions on recent OpenGL.
+ Extensions = "";
+ }
+ else
+ {
+ const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
+
+ OVR_ASSERT(extensions);
+ if (!extensions)
+ {
+ extensions = ""; // Note: glGetString() can return null
+ LogText("Warning: GL_EXTENSIONS was NULL\n");
+ }
+ else
+ {
+ // Cannot print this to debug log: It's too long!
+ //OVR_DEBUG_LOG(("GL_EXTENSIONS: %s", (const char*)extensions));
+ }
+
+ Extensions = extensions;
+ }
+
+ // To do: revise the code below to loop through calls to glGetStringi(GL_EXTENSIONS, ...) so that all extensions below
+ // can be searched with a single pass over the extensions instead of a full loop per HasGLExtensionCall.
+
+ if (MajorVersion >= 3)
+ {
+ SupportsVAO = true;
+ }
+ else
+ {
+ SupportsVAO =
+ HasGLExtension("GL_ARB_vertex_array_object") ||
+ HasGLExtension("GL_APPLE_vertex_array_object");
+ }
+
+ SupportsDrawBuffers = HasGLExtension("GL_EXT_draw_buffers2");
+
+ // Add more extension checks here...
+}
+
+void GetGLVersionAndExtensions(GLVersionAndExtensions& versionInfo)
+{
+ versionInfo.ParseGLVersion();
+ // GL Version must be parsed before parsing extensions:
+ versionInfo.ParseGLExtensions();
+ // To consider: Call to glGetStringi(GL_SHADING_LANGUAGE_VERSION, ...) check/validate the GLSL support.
+}
+}}} // namespace OVR::CAPI::GL
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h
index bc7c8ab..aa6a26b 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h
@@ -58,6 +58,7 @@ limitations under the License.
namespace OVR { namespace CAPI { namespace GL {
+
// GL extension Hooks for Non-Mac.
#if !defined(OVR_OS_MAC)
@@ -69,7 +70,8 @@ typedef void (__stdcall *PFNGLENABLEPROC) (GLenum);
typedef void (__stdcall *PFNGLDISABLEPROC) (GLenum);
typedef void (__stdcall *PFNGLGETFLOATVPROC) (GLenum, GLfloat*);
typedef const GLubyte * (__stdcall *PFNGLGETSTRINGPROC) (GLenum);
-typedef void (__stdcall *PFNGLGETINTEGERVPROC) (GLenum, GLint*);
+typedef const GLubyte * (__stdcall *PFNGLGETSTRINGIPROC) (GLenum, GLuint);
+typedef void(__stdcall *PFNGLGETINTEGERVPROC) (GLenum, GLint*);
typedef void (__stdcall *PFNGLGETDOUBLEVPROC) (GLenum, GLdouble*);
typedef PROC (__stdcall *PFNWGLGETPROCADDRESS) (LPCSTR);
typedef void (__stdcall *PFNGLFLUSHPROC) ();
@@ -91,7 +93,6 @@ typedef void (__stdcall *PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, G
typedef void (__stdcall *PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
typedef void (__stdcall *PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor);
typedef void (__stdcall *PFNGLFRONTFACEPROC) (GLenum mode);
-typedef void (__stdcall *PFNGLFEEDBACKBUFFERPROC) (GLsizei size, GLenum type, GLfloat *buffer);
typedef GLint (__stdcall *PFNGLRENDERMODEPROC) (GLenum mode);
typedef void (__stdcall *PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
@@ -138,6 +139,7 @@ extern PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT;
#endif // defined(OVR_OS_WIN32)
+extern PFNGLGETSTRINGIPROC glGetStringi;
extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
extern PFNGLDELETESHADERPROC glDeleteShader;
@@ -183,7 +185,7 @@ extern PFNGLUNIFORM1FVPROC glUniform1fv;
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
-extern PFNGLFEEDBACKBUFFERPROC glFeedbackBuffer;
+extern PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
extern void InitGLExtensions();
@@ -527,6 +529,7 @@ public:
OVR_UNUSED(size);
success = Compile((const char*) s);
OVR_ASSERT(success);
+ OVR_UNUSED(success);
InitUniforms(refl, reflSize);
}
~ShaderImpl()
@@ -571,7 +574,56 @@ typedef ShaderImpl<Shader_Vertex, GL_VERTEX_SHADER> VertexShader;
typedef ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER> FragmentShader;
-}}}
+//// GLVersionAndExtensions
+//
+// FIXME: CODE DUPLICATION WARNING
+// Right now we have this same code in CommonSrc and in CAPI::GL.
+// At some point we need to consolidate these, in Kernel or Util.
+// Be sure to update both locations for now!
+//
+// This class needs to be initialized at runtime with GetGLVersionAndExtensions,
+// after an OpenGL context has been created. It must be re-initialized any time
+// a new OpenGL context is created, as the new context may differ in version or
+// supported functionality.
+struct GLVersionAndExtensions
+{
+ // Version information
+ int MajorVersion; // Best guess at major version
+ int MinorVersion; // Best guess at minor version
+ int WholeVersion; // Equals ((MajorVersion * 100) + MinorVersion). Example usage: if(glv.WholeVersion >= 302) // If OpenGL v3.02+ ...
+ bool IsGLES; // Open GL ES?
+ bool IsCoreProfile; // Is the current OpenGL context a core profile context? Its trueness may be a false positive but will never be a false negative.
+
+ // Extension information
+ bool SupportsVAO; // Supports Vertex Array Objects?
+ bool SupportsDrawBuffers; // Supports Draw Buffers?
+ const char* Extensions; // Other extensions string (will not be null)
+
+ GLVersionAndExtensions()
+ : MajorVersion(0),
+ MinorVersion(0),
+ WholeVersion(0),
+ IsGLES(false),
+ IsCoreProfile(false),
+ SupportsDrawBuffers(false),
+ SupportsVAO(false),
+ Extensions("")
+ {
+ }
+
+ bool HasGLExtension(const char* searchKey) const;
+
+protected:
+ friend void GetGLVersionAndExtensions(GLVersionAndExtensions& versionInfo);
+
+ void ParseGLVersion();
+ void ParseGLExtensions();
+};
+
+void GetGLVersionAndExtensions(GLVersionAndExtensions& versionInfo);
+
+
+}}} // namespace OVR::CAPI::GL
#endif // INC_OVR_CAPI_GL_Util_h