aboutsummaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/CAPI/GL
diff options
context:
space:
mode:
authorBrad Davis <[email protected]>2014-07-24 16:47:31 -0700
committerBrad Davis <[email protected]>2014-07-24 16:47:31 -0700
commit0f49ce8fc6aa54224e4c0d6fda8c4527ad39cce1 (patch)
treeda07ebc6a7f75185bda857dd5f1c34710b416a93 /LibOVR/Src/CAPI/GL
parentca79271759ff7eecd22ec5c4db438370fe51d687 (diff)
0.4 Win-Beta0.4.0
Diffstat (limited to 'LibOVR/Src/CAPI/GL')
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp404
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h17
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h77
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp460
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h74
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp40
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_Util.h29
7 files changed, 960 insertions, 141 deletions
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp
index 21b6509..0bf0aa4 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp
@@ -18,9 +18,11 @@ otherwise accompanies this software in either electronic or hard copy form.
#include "CAPI_GL_DistortionShaders.h"
#include "../../OVR_CAPI_GL.h"
+#include "../../Kernel/OVR_Color.h"
namespace OVR { namespace CAPI { namespace GL {
+
// Distortion pixel shader lookup.
// Bit 0: Chroma Correction
// Bit 1: Timewarp
@@ -69,10 +71,10 @@ void DistortionShaderBitIndexCheck()
struct DistortionVertex
{
- Vector2f Pos;
- Vector2f TexR;
- Vector2f TexG;
- Vector2f TexB;
+ Vector2f ScreenPosNDC;
+ Vector2f TanEyeAnglesR;
+ Vector2f TanEyeAnglesG;
+ Vector2f TanEyeAnglesB;
Color Col;
};
@@ -120,6 +122,8 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig,
{
GfxState = *new GraphicsState();
+ SaveGraphicsState();
+
const ovrGLConfig* config = (const ovrGLConfig*)apiConfig;
if (!config)
@@ -135,18 +139,39 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig,
RParams.RTSize = config->OGL.Header.RTSize;
#if defined(OVR_OS_WIN32)
RParams.Window = (config->OGL.Window) ? config->OGL.Window : GetActiveWindow();
+ RParams.DC = config->OGL.DC;
#elif defined(OVR_OS_LINUX)
- RParams.Disp = (config->OGL.Disp) ? config->OGL.Disp : XOpenDisplay(NULL);
- RParams.Win = config->OGL.Win;
+ if (config->OGL.Disp)
+ RParams.Disp = config->OGL.Disp;
+ if (!RParams.Disp)
+ RParams.Disp = XOpenDisplay(NULL);
+ if (!RParams.Disp)
+ {
+ OVR_DEBUG_LOG(("XOpenDisplay failed."));
+ return false;
+ }
+
+ if (config->OGL.Win)
+ RParams.Win = config->OGL.Win;
if (!RParams.Win)
{
int unused;
- XGetInputFocus(RParams.Disp, &RParams.Win, &unused);
+ RParams.Win = glXGetCurrentDrawable();
+ }
+ if (!RParams.Win)
+ {
+ OVR_DEBUG_LOG(("XGetInputFocus failed."));
+ return false;
}
#endif
DistortionCaps = distortionCaps;
+ DistortionMeshVAOs[0] = 0;
+ DistortionMeshVAOs[1] = 0;
+
+ LatencyVAO = 0;
+
//DistortionWarper.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true);
pEyeTextures[0] = *new Texture(&RParams, 0, 0);
@@ -154,13 +179,15 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig,
initBuffersAndShaders();
+ RestoreGraphicsState();
+
return true;
}
-void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture)
+void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture)
{
- // Doesn't do a lot in here??
+ // Doesn't do a lot in here??
const ovrGLTexture* tex = (const ovrGLTexture*)eyeTexture;
// Write in values
@@ -179,44 +206,65 @@ void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture)
eachEye[eyeId].TextureSize, eachEye[eyeId].RenderViewport,
eachEye[eyeId].UVScaleOffset );
+ if (!(RState.DistortionCaps & ovrDistortionCap_FlipInput))
+ {
+ eachEye[eyeId].UVScaleOffset[0].y = -eachEye[eyeId].UVScaleOffset[0].y;
+ eachEye[eyeId].UVScaleOffset[1].y = 1.0f - eachEye[eyeId].UVScaleOffset[1].y;
+ }
+
pEyeTextures[eyeId]->UpdatePlaceholderTexture(tex->OGL.TexId,
tex->OGL.Header.TextureSize);
}
}
-void DistortionRenderer::EndFrame(bool swapBuffers,
- unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor)
+void DistortionRenderer::renderEndFrame()
{
- if (!TimeManager.NeedDistortionTimeMeasurement())
- {
- if (RState.DistortionCaps & ovrDistortionCap_TimeWarp)
- {
- // Wait for timewarp distortion if it is time and Gpu idle
- FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime);
- }
+ renderDistortion(pEyeTextures[0], pEyeTextures[1]);
+
+ // TODO: Add rendering context to callback.
+ if(RegisteredPostDistortionCallback)
+ RegisteredPostDistortionCallback(NULL);
- renderDistortion(pEyeTextures[0], pEyeTextures[1]);
+ if(LatencyTest2Active)
+ {
+ renderLatencyPixel(LatencyTest2DrawColor);
}
- else
+}
+
+void DistortionRenderer::EndFrame(bool swapBuffers)
+{
+ // Don't spin if we are explicitly asked not to
+ if (RState.DistortionCaps & ovrDistortionCap_TimeWarp &&
+ !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits))
{
- // If needed, measure distortion time so that TimeManager can better estimate
- // latency-reducing time-warp wait timing.
- WaitUntilGpuIdle();
- double distortionStartTime = ovr_GetTimeInSeconds();
+ if (!TimeManager.NeedDistortionTimeMeasurement())
+ {
+ // Wait for timewarp distortion if it is time and Gpu idle
+ FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime);
- renderDistortion(pEyeTextures[0], pEyeTextures[1]);
+ renderEndFrame();
+ }
+ else
+ {
+ // If needed, measure distortion time so that TimeManager can better estimate
+ // latency-reducing time-warp wait timing.
+ WaitUntilGpuIdle();
+ double distortionStartTime = ovr_GetTimeInSeconds();
- WaitUntilGpuIdle();
- TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime);
- }
+ renderEndFrame();
- if(latencyTesterDrawColor)
+ WaitUntilGpuIdle();
+ TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime);
+ }
+ }
+ else
{
- renderLatencyQuad(latencyTesterDrawColor);
+ renderEndFrame();
}
- else if(latencyTester2DrawColor)
+
+ if(LatencyTestActive)
{
- renderLatencyPixel(latencyTester2DrawColor);
+ renderLatencyQuad(LatencyTestDrawColor);
}
if (swapBuffers)
@@ -227,11 +275,13 @@ void DistortionRenderer::EndFrame(bool swapBuffers,
if (wglGetSwapIntervalEXT() != swapInterval)
wglSwapIntervalEXT(swapInterval);
- HDC dc = GetDC(RParams.Window);
+ HDC dc = (RParams.DC != NULL) ? RParams.DC : GetDC(RParams.Window);
BOOL success = SwapBuffers(dc);
- ReleaseDC(RParams.Window, dc);
- OVR_ASSERT(success);
+ OVR_ASSERT(success);
OVR_UNUSED(success);
+
+ if (RParams.DC == NULL)
+ ReleaseDC(RParams.Window, dc);
#elif defined(OVR_OS_MAC)
CGLContextObj context = CGLGetCurrentContext();
GLint currentSwapInterval = 0;
@@ -253,58 +303,58 @@ void DistortionRenderer::EndFrame(bool swapBuffers,
glXSwapBuffers(RParams.Disp, RParams.Win);
#endif
+ // Force GPU to flush the scene, resulting in the lowest possible latency.
+ // It's critical that this flush is *after* present.
+ // With the display driver this flush is obsolete and theoretically should
+ // be a no-op.
+ // Doesn't need to be done if running through the Oculus driver.
+ if (RState.OurHMDInfo.InCompatibilityMode &&
+ !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits))
+ WaitUntilGpuIdle();
}
}
void DistortionRenderer::WaitUntilGpuIdle()
{
- glFlush();
glFinish();
}
double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime)
{
- double initialTime = ovr_GetTimeInSeconds();
- if (initialTime >= absTime)
- return 0.0;
-
- glFlush();
- glFinish();
+ // because glFlush() is not strict enough certain GL drivers
+ // we do a glFinish(), but before doing so, we make sure we're not
+ // running late
+ double initialTime = ovr_GetTimeInSeconds();
+ if (initialTime >= absTime)
+ return 0.0;
- double newTime = initialTime;
- volatile int i;
+ glFinish();
- while (newTime < absTime)
- {
- for (int j = 0; j < 50; j++)
- i = 0;
-
- newTime = ovr_GetTimeInSeconds();
- }
-
- // How long we waited
- return newTime - initialTime;
+ return WaitTillTime(absTime);
}
DistortionRenderer::GraphicsState::GraphicsState()
{
- const char* glVersionString = (const char*)glGetString(GL_VERSION);
- OVR_DEBUG_LOG(("GL_VERSION STRING: %s", (const char*)glVersionString));
- char prefix[64];
bool foundVersion = false;
-
- for (int i = 10; i < 30; ++i)
+ const char* glVersionString = (const char*)glGetString(GL_VERSION);
+ if (glVersionString)
{
- int major = i / 10;
- int minor = i % 10;
- OVR_sprintf(prefix, 64, "%d.%d", major, minor);
- if (strstr(glVersionString, prefix) == glVersionString)
+ OVR_DEBUG_LOG(("GL_VERSION STRING: %s", (const char*)glVersionString));
+ char prefix[64];
+
+ for (int i = 10; i < 30; ++i)
{
- GlMajorVersion = major;
- GlMinorVersion = minor;
- foundVersion = true;
- break;
+ 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;
+ }
}
}
@@ -319,21 +369,34 @@ DistortionRenderer::GraphicsState::GraphicsState()
if (GlMajorVersion >= 3)
{
SupportsVao = true;
+ SupportsDrawBuffers = true;
}
else
{
const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
- SupportsVao = (strstr("GL_ARB_vertex_array_object", extensions) != NULL);
+ 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)
+void DistortionRenderer::GraphicsState::ApplyBool(GLenum Name, GLint Value, GLint index)
{
- if (Value != 0)
- glEnable(Name);
- else
- glDisable(Name);
+ if (SupportsDrawBuffers && index != -1)
+ {
+ if (Value != 0)
+ glEnablei(Name, index);
+ else
+ glDisablei(Name, index);
+ }
+ else
+ {
+ if (Value != 0)
+ glEnable(Name);
+ else
+ glDisable(Name);
+ }
}
@@ -343,18 +406,34 @@ void DistortionRenderer::GraphicsState::Save()
glGetFloatv(GL_COLOR_CLEAR_VALUE, ClearColor);
glGetIntegerv(GL_DEPTH_TEST, &DepthTest);
glGetIntegerv(GL_CULL_FACE, &CullFace);
+ glGetIntegerv(GL_FRAMEBUFFER_SRGB, &SRGB);
glGetIntegerv(GL_CURRENT_PROGRAM, &Program);
glGetIntegerv(GL_ACTIVE_TEXTURE, &ActiveTexture);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &TextureBinding);
- glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &VertexArray);
+ if (SupportsVao)
+ {
+ glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &VertexArrayBinding);
+ }
+ else
+ {
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &ElementArrayBufferBinding);
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &ArrayBufferBinding);
+ }
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &FrameBufferBinding);
- glGetIntegerv(GL_BLEND, &Blend);
- glGetIntegerv(GL_COLOR_WRITEMASK, ColorWritemask);
+ if (SupportsDrawBuffers)
+ {
+ glGetIntegeri_v(GL_BLEND, 0, &Blend);
+ glGetIntegeri_v(GL_COLOR_WRITEMASK, 0, ColorWritemask);
+ }
+ else
+ {
+ glGetIntegerv(GL_BLEND, &Blend);
+ glGetIntegerv(GL_COLOR_WRITEMASK, ColorWritemask);
+ }
glGetIntegerv(GL_DITHER, &Dither);
glGetIntegerv(GL_RASTERIZER_DISCARD, &RasterizerDiscard);
- if (GlMajorVersion >= 3 && GlMajorVersion >= 2)
+ if ((GlMajorVersion == 3 && GlMinorVersion >= 2) || GlMajorVersion >= 4)
glGetIntegerv(GL_SAMPLE_MASK, &SampleMask);
- glGetIntegerv(GL_SCISSOR_TEST, &ScissorTest);
IsValid = true;
}
@@ -371,22 +450,37 @@ void DistortionRenderer::GraphicsState::Restore()
ApplyBool(GL_DEPTH_TEST, DepthTest);
ApplyBool(GL_CULL_FACE, CullFace);
+ ApplyBool(GL_FRAMEBUFFER_SRGB, SRGB);
glUseProgram(Program);
glActiveTexture(ActiveTexture);
glBindTexture(GL_TEXTURE_2D, TextureBinding);
if (SupportsVao)
- glBindVertexArray(VertexArray);
+ {
+#ifdef OVR_OS_MAC
+ glBindVertexArrayAPPLE(VertexArrayBinding);
+#else
+ glBindVertexArray(VertexArrayBinding);
+#endif
+ }
+ else
+ {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementArrayBufferBinding);
+ glBindBuffer(GL_ARRAY_BUFFER, ArrayBufferBinding);
+ }
glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferBinding);
- ApplyBool(GL_BLEND, Blend);
+ ApplyBool(GL_BLEND, Blend, 0);
+
+ if (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]);
- 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 && GlMajorVersion >= 2)
+ if ((GlMajorVersion == 3 && GlMinorVersion >= 2) || GlMajorVersion >= 4)
ApplyBool(GL_SAMPLE_MASK, SampleMask);
- ApplyBool(GL_SCISSOR_TEST, ScissorTest);
}
@@ -416,16 +510,21 @@ void DistortionRenderer::initBuffersAndShaders()
for ( unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++ )
{
- pCurVBVert->Pos.x = pCurOvrVert->Pos.x;
- pCurVBVert->Pos.y = pCurOvrVert->Pos.y;
- pCurVBVert->TexR = (*(Vector2f*)&pCurOvrVert->TexR);
- pCurVBVert->TexG = (*(Vector2f*)&pCurOvrVert->TexG);
- pCurVBVert->TexB = (*(Vector2f*)&pCurOvrVert->TexB);
+ 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);
+
// Convert [0.0f,1.0f] to [0,255]
- pCurVBVert->Col.R = (OVR::UByte)( pCurOvrVert->VignetteFactor * 255.99f );
+ if (DistortionCaps & ovrDistortionCap_Vignette)
+ pCurVBVert->Col.R = (uint8_t)( pCurOvrVert->VignetteFactor * 255.99f );
+ else
+ pCurVBVert->Col.R = 255;
+
pCurVBVert->Col.G = pCurVBVert->Col.R;
pCurVBVert->Col.B = pCurVBVert->Col.R;
- pCurVBVert->Col.A = (OVR::UByte)( pCurOvrVert->TimeWarpFactor * 255.99f );;
+ pCurVBVert->Col.A = (uint8_t)( pCurOvrVert->TimeWarpFactor * 255.99f );;
pCurOvrVert++;
pCurVBVert++;
}
@@ -433,7 +532,7 @@ void DistortionRenderer::initBuffersAndShaders()
DistortionMeshVBs[eyeNum] = *new Buffer(&RParams);
DistortionMeshVBs[eyeNum]->Data ( Buffer_Vertex | Buffer_ReadOnly, pVBVerts, sizeof(DistortionVertex) * meshData.VertexCount );
DistortionMeshIBs[eyeNum] = *new Buffer(&RParams);
- DistortionMeshIBs[eyeNum]->Data ( Buffer_Index | Buffer_ReadOnly, meshData.pIndexData, ( sizeof(SInt16) * meshData.IndexCount ) );
+ DistortionMeshIBs[eyeNum]->Data ( Buffer_Index | Buffer_ReadOnly, meshData.pIndexData, ( sizeof(int16_t) * meshData.IndexCount ) );
OVR_FREE ( pVBVerts );
ovrHmd_DestroyDistortionMesh( &meshData );
@@ -449,16 +548,29 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ
glBindFramebuffer(GL_FRAMEBUFFER, 0);
setViewport( Recti(0,0, RParams.RTSize.w, RParams.RTSize.h) );
+ if (DistortionCaps & ovrDistortionCap_SRGB)
+ glEnable(GL_FRAMEBUFFER_SRGB);
+ else
+ glDisable(GL_FRAMEBUFFER_SRGB);
+
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
- glDisable(GL_BLEND);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
+ if (glState->SupportsDrawBuffers)
+ {
+ glDisablei(GL_BLEND, 0);
+ glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
+ }
+ else
+ {
+ glDisable(GL_BLEND);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
+ }
+
glDisable(GL_DITHER);
glDisable(GL_RASTERIZER_DISCARD);
- if (glState->GlMajorVersion >= 3 && glState->GlMajorVersion >= 2)
+ if ((glState->GlMajorVersion >= 3 && glState->GlMinorVersion >= 2) || glState->GlMajorVersion >= 4)
glDisable(GL_SAMPLE_MASK);
- glDisable(GL_SCISSOR_TEST);
glClearColor(
RState.ClearColor[0],
@@ -536,20 +648,21 @@ void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor
createDrawQuad();
}
- ShaderFill quadFill(SimpleQuadShader);
+ Ptr<ShaderSet> quadShader = (DistortionCaps & ovrDistortionCap_SRGB) ? SimpleQuadGammaShader : SimpleQuadShader;
+ ShaderFill quadFill(quadShader);
//quadFill.SetInputLayout(SimpleQuadVertexIL);
setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h));
- SimpleQuadShader->SetUniform2f("Scale", 0.2f, 0.2f);
- SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterDrawColor[0] / 255.99f,
- (float)latencyTesterDrawColor[0] / 255.99f,
- (float)latencyTesterDrawColor[0] / 255.99f,
- 1.0f);
+ quadShader->SetUniform2f("Scale", 0.3f, 0.3f);
+ quadShader->SetUniform4f("Color", (float)latencyTesterDrawColor[0] / 255.99f,
+ (float)latencyTesterDrawColor[0] / 255.99f,
+ (float)latencyTesterDrawColor[0] / 255.99f,
+ 1.0f);
for(int eyeNum = 0; eyeNum < 2; eyeNum++)
{
- SimpleQuadShader->SetUniform2f("PositionOffset", eyeNum == 0 ? -0.4f : 0.4f, 0.0f);
+ quadShader->SetUniform2f("PositionOffset", eyeNum == 0 ? -0.5f : 0.5f, 0.0f);
renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, 0, numQuadVerts, Prim_TriangleStrip, &LatencyVAO, false);
}
}
@@ -563,18 +676,28 @@ void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelCol
createDrawQuad();
}
- ShaderFill quadFill(SimpleQuadShader);
+ Ptr<ShaderSet> quadShader = (DistortionCaps & ovrDistortionCap_SRGB) ? SimpleQuadGammaShader : SimpleQuadShader;
+ ShaderFill quadFill(quadShader);
setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h));
- SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f,
- (float)latencyTesterPixelColor[0] / 255.99f,
- (float)latencyTesterPixelColor[0] / 255.99f,
- 1.0f);
+#ifdef OVR_BUILD_DEBUG
+ quadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f,
+ (float)latencyTesterPixelColor[1] / 255.99f,
+ (float)latencyTesterPixelColor[2] / 255.99f,
+ 1.0f);
- Vector2f scale(2.0f / RParams.RTSize.w, 2.0f / RParams.RTSize.h);
- SimpleQuadShader->SetUniform2f("Scale", scale.x, scale.y);
- SimpleQuadShader->SetUniform2f("PositionOffset", 1.0f, 1.0f);
+ Vector2f scale(20.0f / RParams.RTSize.w, 20.0f / RParams.RTSize.h);
+#else
+ quadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f,
+ (float)latencyTesterPixelColor[0] / 255.99f,
+ (float)latencyTesterPixelColor[0] / 255.99f,
+ 1.0f);
+
+ Vector2f scale(1.0f / RParams.RTSize.w, 1.0f / RParams.RTSize.h);
+#endif
+ quadShader->SetUniform2f("Scale", scale.x, scale.y);
+ quadShader->SetUniform2f("PositionOffset", 1.0f-scale.x, 1.0f-scale.y);
renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, 0, numQuadVerts, Prim_TriangleStrip, &LatencyVAO, false);
}
@@ -611,7 +734,11 @@ void DistortionRenderer::renderPrimitives(
{
if (*vao != 0)
{
+#ifdef OVR_OS_MAC
+ glBindVertexArrayAPPLE(*vao);
+#else
glBindVertexArray(*vao);
+#endif
if (isDistortionMesh)
glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL);
@@ -622,8 +749,13 @@ void DistortionRenderer::renderPrimitives(
{
if (glState->SupportsVao)
{
+#ifdef OVR_OS_MAC
+ glGenVertexArraysAPPLE(1, vao);
+ glBindVertexArrayAPPLE(*vao);
+#else
glGenVertexArrays(1, vao);
glBindVertexArray(*vao);
+#endif
}
int attributeCount = (isDistortionMesh) ? 5 : 1;
@@ -641,11 +773,11 @@ void DistortionRenderer::renderPrimitives(
locs[3] = glGetAttribLocation(prog, "TexCoord1");
locs[4] = glGetAttribLocation(prog, "TexCoord2");
- glVertexAttribPointer(locs[0], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, Pos));
+ glVertexAttribPointer(locs[0], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, ScreenPosNDC));
glVertexAttribPointer(locs[1], 4, GL_UNSIGNED_BYTE, true, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, Col));
- glVertexAttribPointer(locs[2], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TexR));
- glVertexAttribPointer(locs[3], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TexG));
- glVertexAttribPointer(locs[4], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TexB));
+ glVertexAttribPointer(locs[2], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TanEyeAnglesR));
+ glVertexAttribPointer(locs[3], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TanEyeAnglesG));
+ glVertexAttribPointer(locs[4], 2, GL_FLOAT, false, sizeof(DistortionVertex), reinterpret_cast<char*>(offset)+offsetof(DistortionVertex, TanEyeAnglesB));
}
else
{
@@ -751,12 +883,44 @@ void DistortionRenderer::initShaders()
SimpleQuadShader->SetShader(ps);
delete[](psSource);
- }
+ }
+ {
+ size_t vsSize = strlen(shaderPrefix)+sizeof(SimpleQuad_vs);
+ char* vsSource = new char[vsSize];
+ OVR_strcpy(vsSource, vsSize, shaderPrefix);
+ OVR_strcat(vsSource, vsSize, SimpleQuad_vs);
+
+ Ptr<GL::VertexShader> vs = *new GL::VertexShader(
+ &RParams,
+ (void*)vsSource, vsSize,
+ SimpleQuad_vs_refl, sizeof(SimpleQuad_vs_refl) / sizeof(SimpleQuad_vs_refl[0]));
+
+ SimpleQuadGammaShader = *new ShaderSet;
+ SimpleQuadGammaShader->SetShader(vs);
+
+ delete[](vsSource);
+
+ size_t psSize = strlen(shaderPrefix)+sizeof(SimpleQuadGamma_fs);
+ char* psSource = new char[psSize];
+ OVR_strcpy(psSource, psSize, shaderPrefix);
+ OVR_strcat(psSource, psSize, SimpleQuadGamma_fs);
+
+ Ptr<GL::FragmentShader> ps = *new GL::FragmentShader(
+ &RParams,
+ (void*)psSource, psSize,
+ SimpleQuadGamma_fs_refl, sizeof(SimpleQuadGamma_fs_refl) / sizeof(SimpleQuadGamma_fs_refl[0]));
+
+ SimpleQuadGammaShader->SetShader(ps);
+
+ delete[](psSource);
+ }
}
void DistortionRenderer::destroy()
{
+ SaveGraphicsState();
+
GraphicsState* glState = (GraphicsState*)GfxState.GetPtr();
for(int eyeNum = 0; eyeNum < 2; eyeNum++)
@@ -778,7 +942,15 @@ void DistortionRenderer::destroy()
}
LatencyTesterQuadVB.Clear();
- LatencyVAO = 0;
+
+ if(LatencyVAO != 0)
+ {
+ glDeleteVertexArrays(1, &LatencyVAO);
+ LatencyVAO = 0;
+ }
+
+ RestoreGraphicsState();
}
+
}}} // OVR::CAPI::GL
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h
index 60f1a9f..24dbbd6 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h
@@ -47,9 +47,9 @@ public:
virtual bool Initialize(const ovrRenderAPIConfig* apiConfig,
unsigned distortionCaps);
- virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture);
+ virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture);
- virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor);
+ virtual void EndFrame(bool swapBuffers);
void WaitUntilGpuIdle();
@@ -68,21 +68,25 @@ protected:
virtual void Restore();
protected:
- void ApplyBool(GLenum Name, GLint Value);
+ void ApplyBool(GLenum Name, GLint Value, GLint index = -1);
public:
GLint GlMajorVersion;
GLint GlMinorVersion;
bool SupportsVao;
+ bool SupportsDrawBuffers;
GLint Viewport[4];
GLfloat ClearColor[4];
GLint DepthTest;
GLint CullFace;
+ GLint SRGB;
GLint Program;
GLint ActiveTexture;
GLint TextureBinding;
- GLint VertexArray;
+ GLint VertexArrayBinding;
+ GLint ElementArrayBufferBinding;
+ GLint ArrayBufferBinding;
GLint FrameBufferBinding;
GLint Blend;
@@ -140,6 +144,8 @@ protected:
void renderLatencyQuad(unsigned char* latencyTesterDrawColor);
void renderLatencyPixel(unsigned char* latencyTesterPixelColor);
+ void renderEndFrame();
+
Ptr<Texture> pEyeTextures[2];
Ptr<Buffer> DistortionMeshVBs[2]; // one per-eye
@@ -157,6 +163,7 @@ protected:
GLuint LatencyVAO;
Ptr<Buffer> LatencyTesterQuadVB;
Ptr<ShaderSet> SimpleQuadShader;
+ Ptr<ShaderSet> SimpleQuadGammaShader;
Ptr<Texture> CurRenderTarget;
Array<Ptr<Texture> > DepthBuffers;
@@ -175,4 +182,4 @@ protected:
}}} // OVR::CAPI::GL
-#endif // OVR_CAPI_GL_DistortionRenderer_h \ No newline at end of file
+#endif // OVR_CAPI_GL_DistortionRenderer_h
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h
index 03fd174..ce7e2c5 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h
@@ -72,7 +72,70 @@ namespace OVR { namespace CAPI { namespace GL {
{
{ "Color", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 16 },
};
-
+
+ static const char SimpleQuadGamma_fs[] =
+ "uniform vec4 Color;\n"
+
+ "_FRAGCOLOR_DECLARATION\n"
+
+ "void main()\n"
+ "{\n"
+ " _FRAGCOLOR.rgb = pow(Color.rgb, vec3(2.2));\n"
+ " _FRAGCOLOR.a = Color.a;\n"
+ "}\n";
+
+ const OVR::CAPI::GL::ShaderBase::Uniform SimpleQuadGamma_fs_refl[] =
+ {
+ { "Color", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 16 },
+ };
+
+ // This must be prefixed with glsl2Prefix or glsl3Prefix before being compiled.
+ static const char SimpleTexturedQuad_vs[] =
+ "uniform vec2 PositionOffset;\n"
+ "uniform vec2 Scale;\n"
+
+ "_VS_IN vec3 Position;\n"
+ "_VS_IN vec4 Color;\n"
+ "_VS_IN vec2 TexCoord;\n"
+
+ "_VS_OUT vec4 oColor;\n"
+ "_VS_OUT vec2 oTexCoord;\n"
+
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(Position.xy * Scale + PositionOffset, 0.5, 1.0);\n"
+ " oColor = Color;\n"
+ " oTexCoord = TexCoord;\n"
+ "}\n";
+
+ // The following declaration is copied from the generated D3D SimpleTexturedQuad_vs_refl.h file, with D3D_NS renamed to GL.
+ const OVR::CAPI::GL::ShaderBase::Uniform SimpleTexturedQuad_vs_refl[] =
+ {
+ { "PositionOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 },
+ { "Scale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 },
+ };
+
+
+ // This must be prefixed with glsl2Prefix or glsl3Prefix before being compiled.
+ static const char SimpleTexturedQuad_ps[] =
+ "uniform sampler2D Texture0;\n"
+
+ "_FS_IN vec4 oColor;\n"
+ "_FS_IN vec2 oTexCoord;\n"
+
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = texture2D(Texture0, oTexCoord);\n"
+ " if(oColor.a < 0.02)\n"
+ " gl_FragColor.a = 0.0;\n"
+ "}\n";
+
+ // The following is copied from the generated D3D SimpleTexturedQuad_ps_refl.h file, with D3D_NS renamed to GL.
+ const OVR::CAPI::GL::ShaderBase::Uniform SimpleTexturedQuad_ps_refl[] =
+ {
+ { "Color", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 16 },
+ };
+
static const char Distortion_vs[] =
"uniform vec2 EyeToSourceUVScale;\n"
@@ -94,7 +157,6 @@ namespace OVR { namespace CAPI { namespace GL {
// Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion).
// Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye)
" oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
- " oTexCoord0.y = 1.0 - oTexCoord0.y;\n"
" oColor = Color;\n" // Used for vignette fade.
"}\n";
@@ -129,8 +191,8 @@ namespace OVR { namespace CAPI { namespace GL {
"_VS_IN vec4 Color;\n"
"_VS_IN vec2 TexCoord0;\n"
- "_FS_IN vec4 oColor;\n"
- "_FS_IN vec2 oTexCoord0;\n"
+ "_VS_OUT vec4 oColor;\n"
+ "_VS_OUT vec2 oTexCoord0;\n"
"void main()\n"
"{\n"
@@ -163,7 +225,6 @@ namespace OVR { namespace CAPI { namespace GL {
// Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye)
" vec2 SrcCoord = Flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
" oTexCoord0 = SrcCoord;\n"
- " oTexCoord0.y = 1.0-oTexCoord0.y;\n"
" oColor = vec4(Color.r, Color.r, Color.r, Color.r);\n" // Used for vignette fade.
"}\n";
@@ -199,11 +260,8 @@ namespace OVR { namespace CAPI { namespace GL {
// Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion).
// Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye)
" oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
- " oTexCoord0.y = 1.0-oTexCoord0.y;\n"
" oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
- " oTexCoord1.y = 1.0-oTexCoord1.y;\n"
" oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
- " oTexCoord2.y = 1.0-oTexCoord2.y;\n"
" oColor = Color;\n" // Used for vignette fade.
"}\n";
@@ -303,11 +361,8 @@ namespace OVR { namespace CAPI { namespace GL {
" vec2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
" oTexCoord0 = SrcCoordR;\n"
- " oTexCoord0.y = 1.0-oTexCoord0.y;\n"
" oTexCoord1 = SrcCoordG;\n"
- " oTexCoord1.y = 1.0-oTexCoord1.y;\n"
" oTexCoord2 = SrcCoordB;\n"
- " oTexCoord2.y = 1.0-oTexCoord2.y;\n"
" oColor = vec4(Color.r, Color.r, Color.r, Color.r);\n" // Used for vignette fade.
"}\n";
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp
new file mode 100644
index 0000000..36830ca
--- /dev/null
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp
@@ -0,0 +1,460 @@
+/************************************************************************************
+
+Filename : CAPI_GL_HSWDisplay.cpp
+Content : Implements Health and Safety Warning system.
+Created : July 7, 2014
+Authors : Paul Pedriana
+
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
+you may not use the Oculus VR Rift SDK except in compliance with the License,
+which is provided at the time of installation or download, or which
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+http://www.oculusvr.com/licenses/LICENSE-3.1
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+************************************************************************************/
+
+
+#include "CAPI_GL_HSWDisplay.h"
+#include "CAPI_GL_DistortionShaders.h"
+#include "../../OVR_CAPI_GL.h"
+#include "../../Kernel/OVR_File.h"
+#include "../../Kernel/OVR_Math.h"
+#include "../../Kernel/OVR_Allocator.h"
+#include "../../Kernel/OVR_Color.h"
+
+#include "../Textures/healthAndSafety.tga.h"
+
+OVR_DISABLE_MSVC_WARNING(4996) // "This function or variable may be unsafe..."
+
+
+namespace OVR { namespace CAPI {
+
+
+// Loads the TGA data from the File as an array of width * height 32 bit Texture_RGBA values.
+// Returned pointer must be freed with OVR_FREE.
+uint8_t* LoadTextureTgaData(OVR::File* f, uint8_t alpha, int& width, int& height)
+{
+ // See http://www.fileformat.info/format/tga/egff.htm for format details.
+ // The TGA file must be exported with compression disabled and with the origin set to the top-left.
+ // To do: Support at least RLE formats.
+ // TGA files are stored with little-endian data.
+ uint8_t* pRGBA = NULL;
+
+ f->SeekToBegin();
+
+ const int desclen = f->ReadUByte();
+ const int palette = f->ReadUByte();
+ OVR_UNUSED(palette);
+ const int imgtype = f->ReadUByte();
+ f->ReadUInt16(); // Skip bytes
+ int palCount = f->ReadUInt16();
+ int palSize = f->ReadUByte();
+ f->ReadUInt16();
+ f->ReadUInt16();
+ width = f->ReadUInt16();
+ height = f->ReadUInt16();
+ int bpp = f->ReadUByte();
+ f->ReadUByte();
+
+ OVR_ASSERT((imgtype == 2) && ((bpp == 24) || (bpp == 32)));
+
+ if((imgtype == 2) && ((bpp == 24) || (bpp == 32)))
+ {
+ int imgsize = width * height * 4;
+ pRGBA = (uint8_t*) OVR_ALLOC(imgsize);
+ f->Skip(desclen);
+ f->Skip(palCount * (palSize + 7) >> 3);
+ int strideBytes = width * 4; // This is the number of bytes between successive rows.
+
+
+ unsigned char buf[16];
+
+ switch (imgtype)
+ {
+ case 2: // uncompressed true-color image -- the only image type we support.
+ switch (bpp)
+ {
+ case 24:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ f->Read(buf, 3); // Data is stored as B, G, R
+ pRGBA[y*strideBytes + x*4 + 0] = buf[2];
+ pRGBA[y*strideBytes + x*4 + 1] = buf[1];
+ pRGBA[y*strideBytes + x*4 + 2] = buf[0];
+ pRGBA[y*strideBytes + x*4 + 3] = alpha;
+ }
+ }
+ break;
+ case 32:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ f->Read(buf, 4); // Data is stored as B, G, R, A
+ pRGBA[y*strideBytes + x*4 + 0] = buf[2];
+ pRGBA[y*strideBytes + x*4 + 1] = buf[1];
+ pRGBA[y*strideBytes + x*4 + 2] = buf[0];
+ pRGBA[y*strideBytes + x*4 + 3] = buf[3];
+ }
+ }
+ break;
+ }
+ break;
+ }
+ }
+
+ return pRGBA;
+} // LoadTextureTgaData
+
+
+
+namespace GL {
+
+
+// To do: This needs to be promoted to a central version, possibly in CAPI_HSWDisplay.h
+struct HASWVertex
+{
+ Vector3f Pos;
+ Color C;
+ float U, V;
+
+ HASWVertex(const Vector3f& p, const Color& c = Color(64,0,0,255), float u = 0, float v = 0)
+ : Pos(p), C(c), U(u), V(v)
+ {}
+
+ HASWVertex(float x, float y, float z, const Color& c = Color(64,0,0,255), float u = 0, float v = 0)
+ : Pos(x,y,z), C(c), U(u), V(v)
+ {}
+
+ bool operator==(const HASWVertex& b) const
+ {
+ return (Pos == b.Pos) && (C == b.C) && (U == b.U) && (V == b.V);
+ }
+};
+
+
+
+// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way.
+Texture* LoadTextureTga(RenderParams& rParams, int samplerMode, OVR::File* f, uint8_t alpha)
+{
+ OVR::CAPI::GL::Texture* pTexture = NULL;
+
+ int width, height;
+ const uint8_t* pRGBA = LoadTextureTgaData(f, alpha, width, height);
+
+ if (pRGBA)
+ {
+ pTexture = new OVR::CAPI::GL::Texture(&rParams, width, height);
+
+ // SetSampleMode forces the use of mipmaps through GL_LINEAR_MIPMAP_LINEAR.
+ pTexture->SetSampleMode(samplerMode); // Calls glBindTexture internally.
+
+ // We are intentionally not using mipmaps. We need to use this because Texture::SetSampleMode unilaterally uses GL_LINEAR_MIPMAP_LINEAR.
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pRGBA);
+ OVR_ASSERT(glGetError() == 0);
+
+ // With OpenGL 4.2+ we can use this instead of glTexImage2D:
+ // glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
+ // glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pRGBA);
+
+ OVR_FREE(const_cast<uint8_t*>(pRGBA));
+ }
+
+ return pTexture;
+}
+
+
+// Loads a texture from a memory image of a TGA file.
+Texture* LoadTextureTga(RenderParams& rParams, int samplerMode, const uint8_t* pData, int dataSize, uint8_t alpha)
+{
+ MemoryFile memoryFile("", pData, dataSize);
+
+ return LoadTextureTga(rParams, samplerMode, &memoryFile, alpha);
+}
+
+
+
+
+// The texture below may conceivably be shared between HSWDisplay instances. However,
+// beware that sharing may not be possible if two HMDs are using different locales
+// simultaneously. As of this writing it's not clear if that can occur in practice.
+
+HSWDisplay::HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState)
+ : OVR::CAPI::HSWDisplay(api, hmd, renderState),
+ RenderParams(),
+ FrameBuffer(0)
+{
+}
+
+bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig)
+{
+ const ovrGLConfig* config = (const ovrGLConfig*)apiConfig;
+
+ if(config)
+ {
+ // The following is essentially copied from CAPI_GL_DistortionRender.cpp's
+ // Initialize function. To do: Merge this to a central location.
+ RenderParams.Multisample = config->OGL.Header.Multisample;
+ RenderParams.RTSize = config->OGL.Header.RTSize;
+
+ #if defined(OVR_OS_WIN32)
+ RenderParams.Window = (config->OGL.Window) ? config->OGL.Window : GetActiveWindow();
+ RenderParams.DC = config->OGL.DC;
+ #elif defined(OVR_OS_LINUX)
+ if (config->OGL.Disp)
+ RenderParams.Disp = config->OGL.Disp;
+ if (!RenderParams.Disp)
+ RenderParams.Disp = XOpenDisplay(NULL);
+ if (!RenderParams.Disp)
+ {
+ OVR_DEBUG_LOG(("XOpenDisplay failed."));
+ return false;
+ }
+
+ 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."));
+ return false;
+ }
+ #endif
+ }
+ else
+ {
+ UnloadGraphics();
+ }
+
+ return true;
+}
+
+
+void HSWDisplay::Shutdown()
+{
+ UnloadGraphics();
+}
+
+
+void HSWDisplay::DisplayInternal()
+{
+ HSWDISPLAY_LOG(("[HSWDisplay GL] DisplayInternal()"));
+ // We may want to call LoadGraphics here instead of within Render.
+}
+
+
+void HSWDisplay::DismissInternal()
+{
+ HSWDISPLAY_LOG(("[HSWDisplay GL] DismissInternal()"));
+ UnloadGraphics();
+}
+
+
+void HSWDisplay::UnloadGraphics()
+{
+ // RenderParams: No need to clear.
+ if(FrameBuffer != 0)
+ {
+ glDeleteFramebuffers(1, &FrameBuffer);
+ FrameBuffer = 0;
+ }
+ pTexture.Clear();
+ pShaderSet.Clear();
+ pVertexShader.Clear();
+ pFragmentShader.Clear();
+ pVB.Clear();
+ // OrthoProjection: No need to clear.
+}
+
+
+void HSWDisplay::LoadGraphics()
+{
+ int glVersionMajor = 0;
+ int glVersionMinor = 0;
+ 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", &glVersionMajor, &glVersionMinor); // 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(glVersionMajor) == sizeof(GLint), "type mis-match");
+ glGetIntegerv(GL_MAJOR_VERSION, &glVersionMajor);
+ }
+ }
+
+ 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.
+ pTexture = *LoadTextureTga(RenderParams, Sample_Linear | Sample_Clamp, healthAndSafety_tga, (int)sizeof(healthAndSafety_tga), 255);
+
+ if(!pShaderSet)
+ pShaderSet = *new ShaderSet();
+
+ if(!pVertexShader)
+ {
+ OVR::String strShader((glVersionMajor >= 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));
+ pShaderSet->SetShader(pVertexShader);
+ }
+
+ if(!pFragmentShader)
+ {
+ OVR::String strShader((glVersionMajor >= 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));
+ pShaderSet->SetShader(pFragmentShader);
+ }
+
+ if(!pVB)
+ {
+ pVB = *new Buffer(&RenderParams);
+
+ pVB->Data(Buffer_Vertex, NULL, 4 * sizeof(HASWVertex));
+ HASWVertex* pVertices = (HASWVertex*)pVB->Map(0, 4 * sizeof(HASWVertex), Map_Discard);
+ OVR_ASSERT(pVertices);
+
+ if(pVertices)
+ {
+ const bool flip = ((RenderState.DistortionCaps & ovrDistortionCap_FlipInput) != 0);
+ const float left = -1.0f; // We currently draw this in normalized device coordinates with an stereo translation
+ const float top = -1.1f; // applied as a vertex shader uniform. In the future when we have a more formal graphics
+ const float right = 1.0f; // API abstraction we may move this draw to an overlay layer or to a more formal
+ const float bottom = 0.9f; // model/mesh scheme with a perspective projection.
+
+ pVertices[0] = HASWVertex(left, top, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 1.f : 0.f); // To do: Make this branchless
+ pVertices[1] = HASWVertex(left, bottom, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 0.f : 1.f);
+ pVertices[2] = HASWVertex(right, top, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 1.f : 0.f);
+ pVertices[3] = HASWVertex(right, bottom, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 0.f : 1.f);
+
+ pVB->Unmap(pVertices);
+ }
+ }
+
+ // Calculate ortho projection.
+ GetOrthoProjection(RenderState, OrthoProjection);
+}
+
+
+void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture)
+{
+ if(RenderEnabled && eyeTexture)
+ {
+ // 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));
+ OVR_ASSERT(eyeTextureGL->Texture.Header.API == ovrRenderAPI_OpenGL);
+
+ // Load the graphics if not loaded already.
+ if (!pTexture)
+ LoadGraphics();
+
+ // Set the rendering to be to the eye texture.
+ glBindFramebuffer(GL_FRAMEBUFFER, FrameBuffer);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, eyeTextureGL->OGL.TexId, 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); // We aren't using depth, as we currently want this to overwrite everything.
+ // GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
+ // glDrawBuffers(OVR_ARRAY_COUNT(DrawBuffers), DrawBuffers);
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ OVR_ASSERT(status == GL_FRAMEBUFFER_COMPLETE); OVR_UNUSED(status);
+
+ // Set up the viewport
+ const GLint x = (GLint)eyeTextureGL->Texture.Header.RenderViewport.Pos.x;
+ const GLint y = (GLint)eyeTextureGL->Texture.Header.RenderViewport.Pos.y; // Note that GL uses bottom-up coordinates.
+ const GLsizei w = (GLsizei)eyeTextureGL->Texture.Header.RenderViewport.Size.w;
+ const GLsizei h = (GLsizei)eyeTextureGL->Texture.Header.RenderViewport.Size.h;
+ glViewport(x, y, w, h);
+
+ // Set fixed-function render states
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE); // Irrelevant to our case here.
+ glFrontFace(GL_CW);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ OVR_ASSERT(glGetError() == 0);
+
+ // Enable the buffer and shaders we use.
+ glBindBuffer(GL_ARRAY_BUFFER, pVB->GLBuffer);
+ OVR_ASSERT(glGetError() == 0);
+
+ ShaderFill fill(pShaderSet);
+ if(pTexture)
+ {
+ fill.SetTexture(0, pTexture);
+ OVR_ASSERT(glGetError() == 0);
+ }
+
+ // Set shader uniforms.
+ const float scale = HSWDISPLAY_SCALE * ((RenderState.OurHMDInfo.HmdType == HmdType_DK1) ? 0.70f : 1.f);
+ pShaderSet->SetUniform2f("Scale", scale, scale / 2.f); // X and Y scale. Y is a fixed proportion to X in order to give a certain aspect ratio.
+ pShaderSet->SetUniform2f("PositionOffset", OrthoProjection[eye].GetTranslation().x, 0.0f);
+ OVR_ASSERT(glGetError() == 0);
+
+ // Set vertex attributes
+ // To consider: We can use glGenVertexArrays + glBindVertexArray here to tell GL to store the attrib values below in
+ // a vertex array object so later we can simply call glBindVertexArray(VertexArrayObject) to enable them instead
+ // of doing all the calls below again. glBindVertexArray(0) to unbind, glDeleteVertexArrays to destory. Requires
+ // OpenGL v3+ or the GL_ARB_vertex_array_object extension.
+
+ const GLuint shaderProgram = pShaderSet->Prog;
+ int attributeLocationArray[3];
+
+ attributeLocationArray[0] = glGetAttribLocation(shaderProgram, "Position");
+ glVertexAttribPointer(attributeLocationArray[0], sizeof(Vector3f)/sizeof(float), GL_FLOAT, false, sizeof(HASWVertex), reinterpret_cast<char*>(offsetof(HASWVertex, Pos)));
+
+ attributeLocationArray[1] = glGetAttribLocation(shaderProgram, "Color");
+ glVertexAttribPointer(attributeLocationArray[1], sizeof(Color)/sizeof(uint8_t), GL_UNSIGNED_BYTE, false, sizeof(HASWVertex), reinterpret_cast<char*>(offsetof(HASWVertex, C)));
+
+ attributeLocationArray[2] = glGetAttribLocation(shaderProgram, "TexCoord");
+ glVertexAttribPointer(attributeLocationArray[2], sizeof(float[2])/sizeof(float), GL_FLOAT, false, sizeof(HASWVertex), reinterpret_cast<char*>(offsetof(HASWVertex, U)));
+
+ for (size_t i = 0; i < OVR_ARRAY_COUNT(attributeLocationArray); i++)
+ glEnableVertexAttribArray((GLuint)i);
+ OVR_ASSERT(glGetError() == 0);
+
+ fill.Set(Prim_TriangleStrip);
+ OVR_ASSERT(glGetError() == 0);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ OVR_ASSERT(glGetError() == 0);
+
+ for (size_t i = 0; i < OVR_ARRAY_COUNT(attributeLocationArray); i++)
+ glDisableVertexAttribArray(i);
+ }
+}
+
+
+}}} // namespace OVR::CAPI::GL
+
+
+
+
+
+
+
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h
new file mode 100644
index 0000000..c799e5d
--- /dev/null
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.h
@@ -0,0 +1,74 @@
+/************************************************************************************
+
+Filename : CAPI_GL_HSWDisplay.h
+Content : Implements Health and Safety Warning system.
+Created : July 7, 2014
+Authors : Paul Pedriana
+
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
+you may not use the Oculus VR Rift SDK except in compliance with the License,
+which is provided at the time of installation or download, or which
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+http://www.oculusvr.com/licenses/LICENSE-3.1
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+************************************************************************************/
+
+#ifndef OVR_CAPI_GL_HSWDisplay_h
+#define OVR_CAPI_GL_HSWDisplay_h
+
+
+#include "../CAPI_HSWDisplay.h"
+#include "CAPI_GL_Util.h"
+
+
+namespace OVR { namespace CAPI { namespace GL {
+
+ class HSWDisplay : public CAPI::HSWDisplay
+ {
+ public:
+ HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState);
+
+ // Must be called before use. apiConfig is such that:
+ // const ovrGLConfig* config = (const ovrGLConfig*)apiConfig; or
+ bool Initialize(const ovrRenderAPIConfig* apiConfig);
+ void Shutdown();
+ void DisplayInternal();
+ void DismissInternal();
+
+ // Draws the warning to the eye texture(s). This must be done at the end of a
+ // frame but prior to executing the distortion rendering of the eye textures.
+ void RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture);
+
+ protected:
+ void UnloadGraphics();
+ void LoadGraphics();
+
+ OVR::CAPI::GL::RenderParams RenderParams;
+ 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;
+ Ptr<OVR::CAPI::GL::VertexShader> pVertexShader;
+ Ptr<OVR::CAPI::GL::FragmentShader> pFragmentShader;
+ Ptr<OVR::CAPI::GL::Buffer> pVB;
+ Matrix4f OrthoProjection[2]; // Projection for 2D.
+
+ private:
+ OVR_NON_COPYABLE(HSWDisplay)
+ };
+
+}}} // namespace OVR::CAPI::GL
+
+
+#endif // OVR_CAPI_GL_HSWDisplay_h
+
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp
index 910e28c..7c0b46b 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp
@@ -36,6 +36,7 @@ namespace OVR { namespace CAPI { namespace GL {
PFNWGLGETPROCADDRESS wglGetProcAddress;
+PFNGLGETERRORPROC glGetError;
PFNGLENABLEPROC glEnable;
PFNGLDISABLEPROC glDisable;
PFNGLGETFLOATVPROC glGetFloatv;
@@ -54,6 +55,9 @@ PFNGLDRAWARRAYSPROC glDrawArrays;
PFNGLGENTEXTURESPROC glGenTextures;
PFNGLDELETETEXTURESPROC glDeleteTextures;
PFNGLBINDTEXTUREPROC glBindTexture;
+PFNGLTEXIMAGE2DPROC glTexImage2D;
+PFNGLBLENDFUNCPROC glBlendFunc;
+PFNGLFRONTFACEPROC glFrontFace;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
@@ -64,7 +68,16 @@ PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT;
#endif
+PFNGLENABLEIPROC glEnablei;
+PFNGLDISABLEIPROC glDisablei;
+PFNGLCOLORMASKIPROC glColorMaski;
+PFNGLGETINTEGERI_VPROC glGetIntegeri_v;
+PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
+PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
PFNGLDELETESHADERPROC glDeleteShader;
+PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
+PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
+PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
PFNGLACTIVETEXTUREPROC glActiveTexture;
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
@@ -131,6 +144,7 @@ void InitGLExtensions()
if (!hInst)
return;
+ glGetError = (PFNGLGETERRORPROC) GetProcAddress(hInst, "glGetError");
glGetFloatv = (PFNGLGETFLOATVPROC) GetProcAddress(hInst, "glGetFloatv");
glGetIntegerv = (PFNGLGETINTEGERVPROC) GetProcAddress(hInst, "glGetIntegerv");
glGetString = (PFNGLGETSTRINGPROC) GetProcAddress(hInst, "glGetString");
@@ -145,19 +159,32 @@ void InitGLExtensions()
glFinish = (PFNGLFINISHPROC) GetProcAddress(hInst, "glFinish");
glDrawArrays = (PFNGLDRAWARRAYSPROC) GetProcAddress(hInst, "glDrawArrays");
glDrawElements = (PFNGLDRAWELEMENTSPROC) GetProcAddress(hInst, "glDrawElements");
- glGenTextures = (PFNGLGENTEXTURESPROC) GetProcAddress(hInst,"glGenTextures");
- glDeleteTextures = (PFNGLDELETETEXTURESPROC) GetProcAddress(hInst,"glDeleteTextures");
- glBindTexture = (PFNGLBINDTEXTUREPROC) GetProcAddress(hInst,"glBindTexture");
+ glGenTextures = (PFNGLGENTEXTURESPROC) GetProcAddress(hInst, "glGenTextures");
+ glDeleteTextures = (PFNGLDELETETEXTURESPROC) GetProcAddress(hInst, "glDeleteTextures");
+ glBindTexture = (PFNGLBINDTEXTUREPROC) GetProcAddress(hInst, "glBindTexture");
+ glTexImage2D = (PFNGLTEXIMAGE2DPROC) GetProcAddress(hInst, "glTexImage2D");
glTexParameteri = (PFNGLTEXPARAMETERIPROC) GetProcAddress(hInst, "glTexParameteri");
+ glBlendFunc = (PFNGLBLENDFUNCPROC) GetProcAddress(hInst, "glBlendFunc");
+ glFrontFace = (PFNGLFRONTFACEPROC) GetProcAddress(hInst, "glFrontFace");
wglGetProcAddress = (PFNWGLGETPROCADDRESS) GetProcAddress(hInst, "wglGetProcAddress");
wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) GetFunction("wglGetSwapIntervalEXT");
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) GetFunction("wglSwapIntervalEXT");
#elif defined(OVR_OS_LINUX)
+
glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) GetFunction("glXSwapIntervalEXT");
#endif
-
+
+ glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) GetFunction("glGenFramebuffersEXT");
+ glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) GetFunction("glDeleteFramebuffersEXT");
+ glEnablei = (PFNGLENABLEIPROC) GetFunction("glEnableIndexedEXT");
+ glDisablei = (PFNGLDISABLEIPROC) GetFunction("glDisableIndexedEXT");
+ glColorMaski = (PFNGLCOLORMASKIPROC) GetFunction("glColorMaskIndexedEXT");
+ glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) GetFunction("glGetIntegerIndexedvEXT");
+ glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) GetFunction("glCheckFramebufferStatusEXT");
+ glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) GetFunction("glFramebufferRenderbufferEXT");
+ glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) GetFunction("glFramebufferTexture2DEXT");
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) GetFunction("glBindFramebufferEXT");
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) GetFunction("glGenVertexArrays");
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) GetFunction("glDeleteVertexArrays");
@@ -490,7 +517,7 @@ void Texture::SetSampleMode(int sm)
break;
case Sample_Nearest:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
break;
@@ -527,4 +554,7 @@ void Texture::UpdatePlaceholderTexture(GLuint texId, const Sizei& textureSize)
IsUserAllocated = true;
}
+
}}}
+
+
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h
index a410f17..e9320d2 100644
--- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h
@@ -33,12 +33,13 @@ limitations under the License.
#include "../../Kernel/OVR_Log.h"
#if defined(OVR_OS_WIN32)
+#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#endif
#if defined(OVR_OS_MAC)
-#include <OpenGL/gl3.h>
-#include <OpenGL/gl3ext.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
#else
#ifndef GL_GLEXT_PROTOTYPES
#define GL_GLEXT_PROTOTYPES
@@ -60,6 +61,7 @@ namespace OVR { namespace CAPI { namespace GL {
// Let Windows apps build without linking GL.
#if defined(OVR_OS_WIN32)
+typedef GLenum (__stdcall *PFNGLGETERRORPROC) ();
typedef void (__stdcall *PFNGLENABLEPROC) (GLenum);
typedef void (__stdcall *PFNGLDISABLEPROC) (GLenum);
typedef void (__stdcall *PFNGLGETFLOATVPROC) (GLenum, GLfloat*);
@@ -75,21 +77,29 @@ typedef void (__stdcall *PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLe
typedef void (__stdcall *PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
typedef void (__stdcall *PFNGLDELETETEXTURESPROC) (GLsizei n, GLuint *textures);
typedef void (__stdcall *PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
+typedef void (__stdcall *PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLint format, GLenum type, const GLvoid *pixels);
typedef void (__stdcall *PFNGLCLEARCOLORPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a);
typedef void (__stdcall *PFNGLCLEARDEPTHPROC) (GLclampd depth);
typedef void (__stdcall *PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
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);
extern PFNWGLGETPROCADDRESS wglGetProcAddress;
extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
+extern PFNGLGETERRORPROC glGetError;
extern PFNGLENABLEPROC glEnable;
+extern PFNGLENABLEIPROC glEnablei;
extern PFNGLDISABLEPROC glDisable;
+extern PFNGLDISABLEIPROC glDisablei;
extern PFNGLCOLORMASKPROC glColorMask;
+extern PFNGLCOLORMASKIPROC glColorMaski;
extern PFNGLGETFLOATVPROC glGetFloatv;
extern PFNGLGETSTRINGPROC glGetString;
extern PFNGLGETINTEGERVPROC glGetIntegerv;
+extern PFNGLGETINTEGERI_VPROC glGetIntegeri_v;
extern PFNGLCLEARPROC glClear;
extern PFNGLCLEARCOLORPROC glClearColor;
extern PFNGLCLEARDEPTHPROC glClearDepth;
@@ -99,9 +109,12 @@ extern PFNGLDRAWELEMENTSPROC glDrawElements;
extern PFNGLGENTEXTURESPROC glGenTextures;
extern PFNGLDELETETEXTURESPROC glDeleteTextures;
extern PFNGLBINDTEXTUREPROC glBindTexture;
+extern PFNGLTEXIMAGE2DPROC glTexImage2D;
extern PFNGLTEXPARAMETERIPROC glTexParameteri;
extern PFNGLFLUSHPROC glFlush;
extern PFNGLFINISHPROC glFinish;
+extern PFNGLBLENDFUNCPROC glBlendFunc;
+extern PFNGLFRONTFACEPROC glFrontFace;
#elif defined(OVR_OS_LINUX)
@@ -109,7 +122,12 @@ extern PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT;
#endif // defined(OVR_OS_WIN32)
+extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
+extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
extern PFNGLDELETESHADERPROC glDeleteShader;
+extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
+extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
+extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
extern PFNGLACTIVETEXTUREPROC glActiveTexture;
extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
@@ -223,9 +241,10 @@ struct RenderParams
{
#if defined(OVR_OS_WIN32)
HWND Window;
+ HDC DC;
#elif defined(OVR_OS_LINUX)
- Display* Disp;
- Window Win;
+ _XDisplay* Disp;
+ Window Win;
#endif
ovrSizei RTSize;
@@ -532,6 +551,8 @@ private:
typedef ShaderImpl<Shader_Vertex, GL_VERTEX_SHADER> VertexShader;
typedef ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER> FragmentShader;
+
}}}
+
#endif // INC_OVR_CAPI_GL_Util_h