ovr_sdk

diff LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp	Wed Jan 14 06:51:16 2015 +0200
     1.3 @@ -0,0 +1,571 @@
     1.4 +/************************************************************************************
     1.5 +
     1.6 +Filename    :   CAPI_GL_Util.cpp
     1.7 +Content     :   RenderDevice implementation for OpenGL
     1.8 +Created     :   September 10, 2012
     1.9 +Authors     :   David Borel, Andrew Reisse
    1.10 +
    1.11 +Copyright   :   Copyright 2014 Oculus VR, LLC All Rights reserved.
    1.12 +
    1.13 +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
    1.14 +you may not use the Oculus VR Rift SDK except in compliance with the License,
    1.15 +which is provided at the time of installation or download, or which
    1.16 +otherwise accompanies this software in either electronic or hard copy form.
    1.17 +
    1.18 +You may obtain a copy of the License at
    1.19 +
    1.20 +http://www.oculusvr.com/licenses/LICENSE-3.2
    1.21 +
    1.22 +Unless required by applicable law or agreed to in writing, the Oculus VR SDK
    1.23 +distributed under the License is distributed on an "AS IS" BASIS,
    1.24 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1.25 +See the License for the specific language governing permissions and
    1.26 +limitations under the License.
    1.27 +
    1.28 +************************************************************************************/
    1.29 +
    1.30 +#include "CAPI_GL_Util.h"
    1.31 +#include "../../Kernel/OVR_Log.h"
    1.32 +#include <string.h>
    1.33 +
    1.34 +#if defined(OVR_OS_LINUX)
    1.35 + #include "../../Displays/OVR_Linux_SDKWindow.h"
    1.36 +#endif
    1.37 +
    1.38 +#if defined(OVR_OS_MAC)
    1.39 +    #include <CoreGraphics/CGDirectDisplay.h>
    1.40 +    #include <OpenGL/OpenGL.h>
    1.41 +
    1.42 +typedef void *CGSConnectionID;
    1.43 +typedef int32_t CGSWindowID;
    1.44 +typedef int32_t CGSSurfaceID;
    1.45 +
    1.46 +extern "C" CGLError CGLGetSurface(CGLContextObj ctx, CGSConnectionID *cid, CGSWindowID *wid, CGSSurfaceID *sid);
    1.47 +extern "C" CGLError CGLSetSurface(CGLContextObj ctx, CGSConnectionID cid, CGSWindowID wid, CGSSurfaceID sid);
    1.48 +#endif
    1.49 +
    1.50 +
    1.51 +
    1.52 +
    1.53 +namespace OVR {
    1.54 +
    1.55 +
    1.56 +OVR::GLEContext gleContext;
    1.57 +
    1.58 +
    1.59 +OVR::GLEContext* GetGLEContext()
    1.60 +{
    1.61 +    return &gleContext;
    1.62 +}
    1.63 +
    1.64 +
    1.65 +namespace CAPI { namespace GL {
    1.66 +
    1.67 +
    1.68 +void InitGLExtensions()
    1.69 +{
    1.70 +    if(!gleContext.IsInitialized())
    1.71 +    {
    1.72 +        gleContext.SetCurrentContext(&gleContext);
    1.73 +        gleContext.Init();
    1.74 +    }
    1.75 +}
    1.76 +    
    1.77 +    
    1.78 +Buffer::Buffer(RenderParams* rp) : pParams(rp), Size(0), Use(0), GLBuffer(0)
    1.79 +{
    1.80 +}
    1.81 +
    1.82 +Buffer::~Buffer()
    1.83 +{
    1.84 +    if (GLBuffer)
    1.85 +        glDeleteBuffers(1, &GLBuffer);
    1.86 +}
    1.87 +
    1.88 +bool Buffer::Data(int use, const void* buffer, size_t size)
    1.89 +{
    1.90 +    Size = size;
    1.91 +
    1.92 +    switch (use & Buffer_TypeMask)
    1.93 +    {
    1.94 +    case Buffer_Index:     Use = GL_ELEMENT_ARRAY_BUFFER; break;
    1.95 +    default:               Use = GL_ARRAY_BUFFER; break;
    1.96 +    }
    1.97 +
    1.98 +    if (!GLBuffer)
    1.99 +        glGenBuffers(1, &GLBuffer);
   1.100 +
   1.101 +    int mode = GL_DYNAMIC_DRAW;
   1.102 +    if (use & Buffer_ReadOnly)
   1.103 +        mode = GL_STATIC_DRAW;
   1.104 +
   1.105 +    glBindBuffer(Use, GLBuffer);
   1.106 +    glBufferData(Use, size, buffer, mode);
   1.107 +    return 1;
   1.108 +}
   1.109 +
   1.110 +void* Buffer::Map(size_t, size_t, int)
   1.111 +{
   1.112 +    int mode = GL_WRITE_ONLY;
   1.113 +    //if (flags & Map_Unsynchronized)
   1.114 +    //    mode |= GL_MAP_UNSYNCHRONIZED;
   1.115 +    
   1.116 +    glBindBuffer(Use, GLBuffer);
   1.117 +    void* v = glMapBuffer(Use, mode);
   1.118 +    return v;
   1.119 +}
   1.120 +
   1.121 +bool Buffer::Unmap(void*)
   1.122 +{
   1.123 +    glBindBuffer(Use, GLBuffer);
   1.124 +    int r = glUnmapBuffer(Use);
   1.125 +    return r != 0;
   1.126 +}
   1.127 +
   1.128 +ShaderSet::ShaderSet() : 
   1.129 +  //Shaders[],
   1.130 +    UniformInfo(),
   1.131 +  //Prog(0)
   1.132 +    ProjLoc(0),
   1.133 +    ViewLoc(0),
   1.134 +  //TexLoc[],
   1.135 +    UsesLighting(false),
   1.136 +    LightingVer(0)
   1.137 +{
   1.138 +    memset(TexLoc, 0, sizeof(TexLoc));
   1.139 +    Prog = glCreateProgram();
   1.140 +}
   1.141 +ShaderSet::~ShaderSet()
   1.142 +{
   1.143 +    glDeleteProgram(Prog);
   1.144 +}
   1.145 +
   1.146 +GLint ShaderSet::GetGLShader(Shader* s)
   1.147 +{
   1.148 +    switch (s->Stage)
   1.149 +    {
   1.150 +    case Shader_Vertex: {
   1.151 +        ShaderImpl<Shader_Vertex, GL_VERTEX_SHADER>* gls = (ShaderImpl<Shader_Vertex, GL_VERTEX_SHADER>*)s;
   1.152 +        return gls->GLShader;
   1.153 +    } break;
   1.154 +    case Shader_Fragment: {
   1.155 +        ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER>* gls = (ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER>*)s;
   1.156 +        return gls->GLShader;
   1.157 +    } break;
   1.158 +    default: break;
   1.159 +    }
   1.160 +
   1.161 +    return -1;
   1.162 +}
   1.163 +
   1.164 +void ShaderSet::SetShader(Shader *s)
   1.165 +{
   1.166 +    Shaders[s->Stage] = s;
   1.167 +    GLint GLShader = GetGLShader(s);
   1.168 +    glAttachShader(Prog, GLShader);
   1.169 +    if (Shaders[Shader_Vertex] && Shaders[Shader_Fragment])
   1.170 +        Link();
   1.171 +}
   1.172 +
   1.173 +void ShaderSet::UnsetShader(int stage)
   1.174 +{
   1.175 +    if (Shaders[stage] == NULL)
   1.176 +        return;
   1.177 +
   1.178 +    GLint GLShader = GetGLShader(Shaders[stage]);
   1.179 +    glDetachShader(Prog, GLShader);
   1.180 +
   1.181 +    Shaders[stage] = NULL;
   1.182 +}
   1.183 +
   1.184 +bool ShaderSet::SetUniform(const char* name, int n, const float* v)
   1.185 +{
   1.186 +    for (unsigned int i = 0; i < UniformInfo.GetSize(); i++)
   1.187 +        if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
   1.188 +        {
   1.189 +            OVR_ASSERT(UniformInfo[i].Location >= 0);
   1.190 +            glUseProgram(Prog);
   1.191 +            switch (UniformInfo[i].Type)
   1.192 +            {
   1.193 +            case 1:   glUniform1fv(UniformInfo[i].Location, n, v); break;
   1.194 +            case 2:   glUniform2fv(UniformInfo[i].Location, n/2, v); break;
   1.195 +            case 3:   glUniform3fv(UniformInfo[i].Location, n/3, v); break;
   1.196 +            case 4:   glUniform4fv(UniformInfo[i].Location, n/4, v); break;
   1.197 +            case 12:  glUniformMatrix3fv(UniformInfo[i].Location, 1, 1, v); break;
   1.198 +            case 16:  glUniformMatrix4fv(UniformInfo[i].Location, 1, 1, v); break;
   1.199 +            default: OVR_ASSERT(0);
   1.200 +            }
   1.201 +            return 1;
   1.202 +        }
   1.203 +
   1.204 +    OVR_DEBUG_LOG(("Warning: uniform %s not present in selected shader", name));
   1.205 +    return 0;
   1.206 +}
   1.207 +
   1.208 +bool ShaderSet::Link()
   1.209 +{
   1.210 +    glLinkProgram(Prog);
   1.211 +    GLint r;
   1.212 +    glGetProgramiv(Prog, GL_LINK_STATUS, &r);
   1.213 +    if (!r)
   1.214 +    {
   1.215 +        GLchar msg[1024];
   1.216 +        glGetProgramInfoLog(Prog, sizeof(msg), 0, msg);
   1.217 +        OVR_DEBUG_LOG(("Linking shaders failed: %s\n", msg));
   1.218 +        if (!r)
   1.219 +            return 0;
   1.220 +    }
   1.221 +    glUseProgram(Prog);
   1.222 +
   1.223 +    UniformInfo.Clear();
   1.224 +    LightingVer = 0;
   1.225 +    UsesLighting = 0;
   1.226 +
   1.227 +    GLint uniformCount = 0;
   1.228 +    glGetProgramiv(Prog, GL_ACTIVE_UNIFORMS, &uniformCount);
   1.229 +    OVR_ASSERT(uniformCount >= 0);
   1.230 +
   1.231 +    for(GLuint i = 0; i < (GLuint)uniformCount; i++)
   1.232 +    {
   1.233 +        GLsizei namelen;
   1.234 +        GLint size = 0;
   1.235 +        GLenum type;
   1.236 +        GLchar name[32];
   1.237 +        glGetActiveUniform(Prog, i, sizeof(name), &namelen, &size, &type, name);
   1.238 +
   1.239 +        if (size)
   1.240 +        {
   1.241 +            int l = glGetUniformLocation(Prog, name);
   1.242 +            char *np = name;
   1.243 +            while (*np)
   1.244 +            {
   1.245 +                if (*np == '[')
   1.246 +                    *np = 0;
   1.247 +                np++;
   1.248 +            }
   1.249 +            Uniform u;
   1.250 +            u.Name = name;
   1.251 +            u.Location = l;
   1.252 +            u.Size = size;
   1.253 +            switch (type)
   1.254 +            {
   1.255 +            case GL_FLOAT:      u.Type = 1; break;
   1.256 +            case GL_FLOAT_VEC2: u.Type = 2; break;
   1.257 +            case GL_FLOAT_VEC3: u.Type = 3; break;
   1.258 +            case GL_FLOAT_VEC4: u.Type = 4; break;
   1.259 +            case GL_FLOAT_MAT3: u.Type = 12; break;
   1.260 +            case GL_FLOAT_MAT4: u.Type = 16; break;
   1.261 +            default:
   1.262 +                continue;
   1.263 +            }
   1.264 +            UniformInfo.PushBack(u);
   1.265 +            if (!strcmp(name, "LightCount"))
   1.266 +                UsesLighting = 1;
   1.267 +        }
   1.268 +        else
   1.269 +            break;
   1.270 +    }
   1.271 +
   1.272 +    ProjLoc = glGetUniformLocation(Prog, "Proj");
   1.273 +    ViewLoc = glGetUniformLocation(Prog, "View");
   1.274 +    for (int i = 0; i < 8; i++)
   1.275 +    {
   1.276 +        char texv[32];
   1.277 +        OVR_sprintf(texv, 10, "Texture%d", i);
   1.278 +        TexLoc[i] = glGetUniformLocation(Prog, texv);
   1.279 +        if (TexLoc[i] < 0)
   1.280 +            break;
   1.281 +
   1.282 +        glUniform1i(TexLoc[i], i);
   1.283 +    }
   1.284 +    if (UsesLighting)
   1.285 +        OVR_ASSERT(ProjLoc >= 0 && ViewLoc >= 0);
   1.286 +    return 1;
   1.287 +}
   1.288 +
   1.289 +bool ShaderBase::SetUniform(const char* name, int n, const float* v)
   1.290 +{
   1.291 +    for(unsigned i = 0; i < UniformReflSize; i++)
   1.292 +    {
   1.293 +        if (!strcmp(UniformRefl[i].Name, name))
   1.294 +        {
   1.295 +            memcpy(UniformData + UniformRefl[i].Offset, v, n * sizeof(float));
   1.296 +            return 1;
   1.297 +        }
   1.298 +    }
   1.299 +    return 0;
   1.300 +}
   1.301 +
   1.302 +bool ShaderBase::SetUniformBool(const char* name, int n, const bool* v) 
   1.303 +{
   1.304 +    OVR_UNUSED(n);
   1.305 +    for(unsigned i = 0; i < UniformReflSize; i++)
   1.306 +    {
   1.307 +        if (!strcmp(UniformRefl[i].Name, name))
   1.308 +        {
   1.309 +            memcpy(UniformData + UniformRefl[i].Offset, v, UniformRefl[i].Size);
   1.310 +            return 1;
   1.311 +        }
   1.312 +    }
   1.313 +    return 0;
   1.314 +}
   1.315 +
   1.316 +void ShaderBase::InitUniforms(const Uniform* refl, size_t reflSize)
   1.317 +{
   1.318 +    if(!refl)
   1.319 +    {
   1.320 +        UniformRefl = NULL;
   1.321 +        UniformReflSize = 0;
   1.322 +
   1.323 +        UniformsSize = 0;
   1.324 +        if (UniformData)
   1.325 +        {
   1.326 +            OVR_FREE(UniformData);
   1.327 +            UniformData = 0;
   1.328 +        }
   1.329 +        return; // no reflection data
   1.330 +    }
   1.331 +
   1.332 +    UniformRefl = refl;
   1.333 +    UniformReflSize = reflSize;
   1.334 +    
   1.335 +    UniformsSize = UniformRefl[UniformReflSize-1].Offset + UniformRefl[UniformReflSize-1].Size;
   1.336 +    UniformData = (unsigned char*)OVR_ALLOC(UniformsSize);
   1.337 +}
   1.338 +
   1.339 +Texture::Texture(RenderParams* rp, int w, int h) : IsUserAllocated(false), pParams(rp), TexId(0), Width(w), Height(h)
   1.340 +{
   1.341 +    if (w && h)
   1.342 +        glGenTextures(1, &TexId);
   1.343 +}
   1.344 +
   1.345 +Texture::~Texture()
   1.346 +{
   1.347 +    if (TexId && !IsUserAllocated)
   1.348 +        glDeleteTextures(1, &TexId);
   1.349 +}
   1.350 +
   1.351 +void Texture::Set(int slot, ShaderStage) const
   1.352 +{
   1.353 +    glActiveTexture(GL_TEXTURE0 + slot);
   1.354 +    glBindTexture(GL_TEXTURE_2D, TexId);
   1.355 +}
   1.356 +
   1.357 +void Texture::SetSampleMode(int sm)
   1.358 +{
   1.359 +    glBindTexture(GL_TEXTURE_2D, TexId);
   1.360 +    switch (sm & Sample_FilterMask)
   1.361 +    {
   1.362 +    case Sample_Linear:
   1.363 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
   1.364 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   1.365 +        if(GLE_EXT_texture_filter_anisotropic)
   1.366 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
   1.367 +        break;
   1.368 +
   1.369 +    case Sample_Anisotropic:
   1.370 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
   1.371 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   1.372 +        if(GLE_EXT_texture_filter_anisotropic)
   1.373 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8);
   1.374 +        break;
   1.375 +
   1.376 +    case Sample_Nearest:
   1.377 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1.378 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1.379 +        if(GLE_EXT_texture_filter_anisotropic)
   1.380 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
   1.381 +        break;
   1.382 +    }
   1.383 +
   1.384 +    switch (sm & Sample_AddressMask)
   1.385 +    {
   1.386 +    case Sample_Repeat:
   1.387 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   1.388 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
   1.389 +        break;
   1.390 +
   1.391 +    case Sample_Clamp:
   1.392 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   1.393 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   1.394 +        break;
   1.395 +
   1.396 +    case Sample_ClampBorder:
   1.397 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
   1.398 +        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
   1.399 +        break;
   1.400 +    }
   1.401 +}
   1.402 +
   1.403 +void Texture::UpdatePlaceholderTexture(GLuint texId, const Sizei& textureSize)
   1.404 +{
   1.405 +    if (!IsUserAllocated && TexId && texId != TexId)
   1.406 +        glDeleteTextures(1, &TexId);
   1.407 +
   1.408 +    TexId = texId;
   1.409 +    Width = textureSize.w;
   1.410 +    Height = textureSize.h;
   1.411 +
   1.412 +    IsUserAllocated = true;
   1.413 +}
   1.414 +
   1.415 +
   1.416 +
   1.417 +
   1.418 +
   1.419 +Context::Context() : initialized(false), ownsContext(true), incarnation(0)
   1.420 +{
   1.421 +#if defined(OVR_OS_MAC)
   1.422 +    systemContext = 0;
   1.423 +#elif defined(OVR_OS_WIN32)
   1.424 +    hdc = 0;
   1.425 +    systemContext = 0;
   1.426 +#elif defined(OVR_OS_LINUX)
   1.427 +    x11Display = NULL;
   1.428 +    x11Drawable = 0;
   1.429 +    systemContext = 0;
   1.430 +    memset(&x11Visual, 0, sizeof(x11Visual));
   1.431 +#endif
   1.432 +
   1.433 +}
   1.434 +
   1.435 +void Context::InitFromCurrent()
   1.436 +{
   1.437 +    Destroy();
   1.438 +
   1.439 +    initialized = true;
   1.440 +    ownsContext = false;
   1.441 +    incarnation++;
   1.442 +    
   1.443 +#if defined(OVR_OS_MAC)
   1.444 +    systemContext = CGLGetCurrentContext();
   1.445 +    {
   1.446 +        CGSConnectionID cid;
   1.447 +        CGSWindowID wid;
   1.448 +        CGSSurfaceID sid;
   1.449 +        CGLError e  = kCGLNoError;
   1.450 +        e = CGLGetSurface(systemContext, &cid, &wid, &sid);
   1.451 +        OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e);
   1.452 +    }
   1.453 +
   1.454 +#elif defined(OVR_OS_WIN32)
   1.455 +    hdc = wglGetCurrentDC();
   1.456 +    systemContext = wglGetCurrentContext();
   1.457 +#elif defined(OVR_OS_LINUX)
   1.458 +    x11Display = glXGetCurrentDisplay();
   1.459 +    x11Drawable = glXGetCurrentDrawable();
   1.460 +    systemContext = glXGetCurrentContext();
   1.461 +    if (!SDKWindow::getVisualFromDrawable(x11Drawable, &x11Visual))
   1.462 +    {
   1.463 +        OVR::LogError("[Context] Unable to obtain x11 visual from context");
   1.464 +        memset(&x11Visual, 0, sizeof(x11Visual));
   1.465 +    }
   1.466 +#endif
   1.467 +}
   1.468 +
   1.469 +
   1.470 +void Context::CreateShared( Context & ctx )
   1.471 +{
   1.472 +    Destroy();
   1.473 +    OVR_ASSERT( ctx.initialized == true );
   1.474 +    if( ctx.initialized == false )
   1.475 +    {
   1.476 +        return;
   1.477 +    }
   1.478 +
   1.479 +    initialized = true;
   1.480 +    ownsContext = true;
   1.481 +    incarnation++;
   1.482 +    
   1.483 +#if defined(OVR_OS_MAC)
   1.484 +    CGLPixelFormatObj pixelFormat = CGLGetPixelFormat( ctx.systemContext );
   1.485 +    CGLError e = CGLCreateContext( pixelFormat, ctx.systemContext, &systemContext );
   1.486 +    OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e);
   1.487 +    SetSurface(ctx);
   1.488 +#elif defined(OVR_OS_WIN32)
   1.489 +    hdc = ctx.hdc;
   1.490 +    systemContext = wglCreateContext( ctx.hdc );
   1.491 +    BOOL success = wglShareLists(ctx.systemContext, systemContext );
   1.492 +    OVR_ASSERT( success == TRUE );
   1.493 +    OVR_UNUSED(success);
   1.494 +#elif defined(OVR_OS_LINUX)
   1.495 +    x11Display = ctx.x11Display;
   1.496 +    x11Drawable = ctx.x11Drawable;
   1.497 +    x11Visual = ctx.x11Visual;
   1.498 +        systemContext = glXCreateContext( ctx.x11Display, &x11Visual, ctx.systemContext, True );
   1.499 +        OVR_ASSERT( systemContext != NULL );
   1.500 +#endif
   1.501 +}
   1.502 +
   1.503 +#if defined(OVR_OS_MAC)
   1.504 +void Context::SetSurface( Context & ctx ) {
   1.505 +    CGLError e = kCGLNoError;
   1.506 +    CGSConnectionID cid, cid2;
   1.507 +    CGSWindowID wid, wid2;
   1.508 +    CGSSurfaceID sid, sid2;
   1.509 +
   1.510 +    e = CGLGetSurface(ctx.systemContext, &cid, &wid, &sid);
   1.511 +    OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e);
   1.512 +    e = CGLGetSurface(systemContext, &cid2, &wid2, &sid2);
   1.513 +    OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e);
   1.514 +    if( sid && sid != sid2 ) {
   1.515 +        e = CGLSetSurface(systemContext, cid, wid, sid);
   1.516 +        OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e);
   1.517 +    }
   1.518 +}
   1.519 +#endif
   1.520 +
   1.521 +void Context::Destroy()
   1.522 +{
   1.523 +    if( initialized == false )
   1.524 +    {
   1.525 +        return;
   1.526 +    }
   1.527 +  
   1.528 +    if (systemContext)
   1.529 +    {
   1.530 +#if defined(OVR_OS_MAC)
   1.531 +        CGLDestroyContext( systemContext );
   1.532 +#elif defined(OVR_OS_WIN32)
   1.533 +        BOOL success = wglDeleteContext( systemContext );
   1.534 +        OVR_ASSERT( success == TRUE );
   1.535 +        OVR_UNUSED( success );
   1.536 +#elif defined(OVR_OS_LINUX)
   1.537 +        glXDestroyContext( x11Display, systemContext );
   1.538 +#endif
   1.539 +
   1.540 +        systemContext = NULL;
   1.541 +    }
   1.542 +  
   1.543 +    initialized = false;
   1.544 +    ownsContext = true;
   1.545 +}
   1.546 +
   1.547 +void Context::Bind()
   1.548 +{
   1.549 +    if(systemContext)
   1.550 +    {
   1.551 +#if defined(OVR_OS_MAC)
   1.552 +        glFlush(); //Apple doesn't automatically flush within CGLSetCurrentContext, unlike other platforms.
   1.553 +        CGLSetCurrentContext( systemContext );
   1.554 +#elif defined(OVR_OS_WIN32)
   1.555 +        wglMakeCurrent( hdc, systemContext );
   1.556 +#elif defined(OVR_OS_LINUX)
   1.557 +        glXMakeCurrent( x11Display, x11Drawable, systemContext );
   1.558 +#endif
   1.559 +    }
   1.560 +}
   1.561 +
   1.562 +void Context::Unbind()
   1.563 +{
   1.564 +#if defined(OVR_OS_MAC)
   1.565 +    glFlush(); //Apple doesn't automatically flush within CGLSetCurrentContext, unlike other platforms.
   1.566 +    CGLSetCurrentContext( NULL );
   1.567 +#elif defined(OVR_OS_WIN32)
   1.568 +    wglMakeCurrent( hdc, NULL );
   1.569 +#elif defined(OVR_OS_LINUX)
   1.570 +    glXMakeCurrent( x11Display, None, NULL );
   1.571 +#endif
   1.572 +}
   1.573 +
   1.574 +}}} // namespace OVR::CAPI::GL