ovr_sdk

annotate LibOVR/Src/CAPI/GL/CAPI_GL_Util.h @ 3:f12a8f74fe1f

added the Xcode project
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 21 Jan 2015 11:37:50 +0200
parents
children
rev   line source
nuclear@0 1 /************************************************************************************
nuclear@0 2
nuclear@0 3 Filename : CAPI_GL_Util.h
nuclear@0 4 Content : Utility header for OpenGL
nuclear@0 5 Created : March 27, 2014
nuclear@0 6 Authors : Andrew Reisse, David Borel
nuclear@0 7
nuclear@0 8 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
nuclear@0 9
nuclear@0 10 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
nuclear@0 11 you may not use the Oculus VR Rift SDK except in compliance with the License,
nuclear@0 12 which is provided at the time of installation or download, or which
nuclear@0 13 otherwise accompanies this software in either electronic or hard copy form.
nuclear@0 14
nuclear@0 15 You may obtain a copy of the License at
nuclear@0 16
nuclear@0 17 http://www.oculusvr.com/licenses/LICENSE-3.2
nuclear@0 18
nuclear@0 19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
nuclear@0 20 distributed under the License is distributed on an "AS IS" BASIS,
nuclear@0 21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nuclear@0 22 See the License for the specific language governing permissions and
nuclear@0 23 limitations under the License.
nuclear@0 24
nuclear@0 25 ************************************************************************************/
nuclear@0 26
nuclear@0 27 #ifndef INC_OVR_CAPI_GL_Util_h
nuclear@0 28 #define INC_OVR_CAPI_GL_Util_h
nuclear@0 29
nuclear@0 30 #include "../../OVR_CAPI.h"
nuclear@0 31 #include "../../Kernel/OVR_Array.h"
nuclear@0 32 #include "../../Kernel/OVR_Math.h"
nuclear@0 33 #include "../../Kernel/OVR_RefCount.h"
nuclear@0 34 #include "../../Kernel/OVR_String.h"
nuclear@0 35 #include "../../Kernel/OVR_Types.h"
nuclear@0 36 #include "../../Kernel/OVR_Log.h"
nuclear@0 37
nuclear@0 38 #if defined(OVR_OS_WIN32)
nuclear@0 39 #define WIN32_LEAN_AND_MEAN
nuclear@0 40 #include <Windows.h>
nuclear@0 41 #endif
nuclear@0 42
nuclear@0 43 #if !defined(OVR_DISABLE_GLE) // By default we use the GLE module in order to link to OpenGL functions. However, if an external user
nuclear@0 44 #include "CAPI_GLE.h" // wants to use an alternative mechanism to connect to OpenGL functions, they can #define OVR_DISABLE_GLE.
nuclear@0 45 #endif
nuclear@0 46
nuclear@0 47
nuclear@0 48 #if defined(OVR_OS_MAC)
nuclear@0 49 #include <CoreGraphics/CGDirectDisplay.h>
nuclear@0 50 #include <OpenGL/CGLTypes.h>
nuclear@0 51 #endif
nuclear@0 52
nuclear@0 53
nuclear@0 54 namespace OVR
nuclear@0 55 {
nuclear@0 56 // Get the shared LibOVR GLEContext instance.
nuclear@0 57 class GLEContext;
nuclear@0 58 GLEContext* GetGLEContext();
nuclear@0 59 }
nuclear@0 60
nuclear@0 61 namespace OVR { namespace CAPI { namespace GL {
nuclear@0 62 void InitGLExtensions();
nuclear@0 63
nuclear@0 64
nuclear@0 65 // Rendering primitive type used to render Model.
nuclear@0 66 enum PrimitiveType
nuclear@0 67 {
nuclear@0 68 Prim_Triangles,
nuclear@0 69 Prim_Lines,
nuclear@0 70 Prim_TriangleStrip,
nuclear@0 71 Prim_Unknown,
nuclear@0 72 Prim_Count
nuclear@0 73 };
nuclear@0 74
nuclear@0 75 // Types of shaders that can be stored together in a ShaderSet.
nuclear@0 76 enum ShaderStage
nuclear@0 77 {
nuclear@0 78 Shader_Vertex = 0,
nuclear@0 79 Shader_Fragment = 2,
nuclear@0 80 Shader_Pixel = 2,
nuclear@0 81 Shader_Count = 3,
nuclear@0 82 };
nuclear@0 83
nuclear@0 84 enum MapFlags
nuclear@0 85 {
nuclear@0 86 Map_Discard = 1,
nuclear@0 87 Map_Read = 2, // do not use
nuclear@0 88 Map_Unsynchronized = 4, // like D3D11_MAP_NO_OVERWRITE
nuclear@0 89 };
nuclear@0 90
nuclear@0 91
nuclear@0 92 // Buffer types used for uploading geometry & constants.
nuclear@0 93 enum BufferUsage
nuclear@0 94 {
nuclear@0 95 Buffer_Unknown = 0,
nuclear@0 96 Buffer_Vertex = 1,
nuclear@0 97 Buffer_Index = 2,
nuclear@0 98 Buffer_Uniform = 4,
nuclear@0 99 Buffer_TypeMask = 0xff,
nuclear@0 100 Buffer_ReadOnly = 0x100, // Buffer must be created with Data().
nuclear@0 101 };
nuclear@0 102
nuclear@0 103 enum TextureFormat
nuclear@0 104 {
nuclear@0 105 Texture_RGBA = 0x0100,
nuclear@0 106 Texture_Depth = 0x8000,
nuclear@0 107 Texture_TypeMask = 0xff00,
nuclear@0 108 Texture_SamplesMask = 0x00ff,
nuclear@0 109 Texture_RenderTarget = 0x10000,
nuclear@0 110 Texture_GenMipmaps = 0x20000,
nuclear@0 111 };
nuclear@0 112
nuclear@0 113 // Texture sampling modes.
nuclear@0 114 enum SampleMode
nuclear@0 115 {
nuclear@0 116 Sample_Linear = 0,
nuclear@0 117 Sample_Nearest = 1,
nuclear@0 118 Sample_Anisotropic = 2,
nuclear@0 119 Sample_FilterMask = 3,
nuclear@0 120
nuclear@0 121 Sample_Repeat = 0,
nuclear@0 122 Sample_Clamp = 4,
nuclear@0 123 Sample_ClampBorder = 8, // If unsupported Clamp is used instead.
nuclear@0 124 Sample_AddressMask =12,
nuclear@0 125
nuclear@0 126 Sample_Count =13,
nuclear@0 127 };
nuclear@0 128
nuclear@0 129
nuclear@0 130 // Rendering parameters/pointers describing GL rendering setup.
nuclear@0 131 struct RenderParams
nuclear@0 132 {
nuclear@0 133 #if defined(OVR_OS_WIN32)
nuclear@0 134 HWND Window;
nuclear@0 135 HDC DC;
nuclear@0 136 #elif defined(OVR_OS_LINUX)
nuclear@0 137 struct _XDisplay* Disp;
nuclear@0 138 #endif
nuclear@0 139
nuclear@0 140 ovrSizei BackBufferSize;
nuclear@0 141 int Multisample;
nuclear@0 142 };
nuclear@0 143
nuclear@0 144
nuclear@0 145 class Buffer : public RefCountBase<Buffer>
nuclear@0 146 {
nuclear@0 147 public:
nuclear@0 148 RenderParams* pParams;
nuclear@0 149 size_t Size;
nuclear@0 150 GLenum Use;
nuclear@0 151 GLuint GLBuffer;
nuclear@0 152
nuclear@0 153 public:
nuclear@0 154 Buffer(RenderParams* r);
nuclear@0 155 ~Buffer();
nuclear@0 156
nuclear@0 157 GLuint GetBuffer() { return GLBuffer; }
nuclear@0 158
nuclear@0 159 virtual size_t GetSize() { return Size; }
nuclear@0 160 virtual void* Map(size_t start, size_t size, int flags = 0);
nuclear@0 161 virtual bool Unmap(void *m);
nuclear@0 162 virtual bool Data(int use, const void* buffer, size_t size);
nuclear@0 163 };
nuclear@0 164
nuclear@0 165 class Texture : public RefCountBase<Texture>
nuclear@0 166 {
nuclear@0 167 bool IsUserAllocated;
nuclear@0 168
nuclear@0 169 public:
nuclear@0 170 RenderParams* pParams;
nuclear@0 171 GLuint TexId;
nuclear@0 172 int Width, Height;
nuclear@0 173
nuclear@0 174 Texture(RenderParams* rp, int w, int h);
nuclear@0 175 ~Texture();
nuclear@0 176
nuclear@0 177 virtual int GetWidth() const { return Width; }
nuclear@0 178 virtual int GetHeight() const { return Height; }
nuclear@0 179
nuclear@0 180 virtual void SetSampleMode(int sm);
nuclear@0 181
nuclear@0 182 // Updates texture to point to specified resources
nuclear@0 183 // - used for slave rendering.
nuclear@0 184 void UpdatePlaceholderTexture(GLuint texId,
nuclear@0 185 const Sizei& textureSize);
nuclear@0 186
nuclear@0 187 virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const;
nuclear@0 188 };
nuclear@0 189
nuclear@0 190 // Base class for vertex and pixel shaders. Stored in ShaderSet.
nuclear@0 191 class Shader : public RefCountBase<Shader>
nuclear@0 192 {
nuclear@0 193 friend class ShaderSet;
nuclear@0 194
nuclear@0 195 protected:
nuclear@0 196 ShaderStage Stage;
nuclear@0 197
nuclear@0 198 public:
nuclear@0 199 Shader(ShaderStage s) : Stage(s) {}
nuclear@0 200 virtual ~Shader() {}
nuclear@0 201
nuclear@0 202 ShaderStage GetStage() const { return Stage; }
nuclear@0 203
nuclear@0 204 virtual void Set(PrimitiveType) const { }
nuclear@0 205 virtual void SetUniformBuffer(class Buffer* buffers, int i = 0) { OVR_UNUSED2(buffers, i); }
nuclear@0 206
nuclear@0 207 protected:
nuclear@0 208 virtual bool SetUniform(const char* name, int n, const float* v) { OVR_UNUSED3(name, n, v); return false; }
nuclear@0 209 virtual bool SetUniformBool(const char* name, int n, const bool* v) { OVR_UNUSED3(name, n, v); return false; }
nuclear@0 210 };
nuclear@0 211
nuclear@0 212
nuclear@0 213
nuclear@0 214 // A group of shaders, one per stage.
nuclear@0 215 // A ShaderSet is applied for rendering with a given fill.
nuclear@0 216 class ShaderSet : public RefCountBase<ShaderSet>
nuclear@0 217 {
nuclear@0 218 protected:
nuclear@0 219 Ptr<Shader> Shaders[Shader_Count];
nuclear@0 220
nuclear@0 221 struct Uniform
nuclear@0 222 {
nuclear@0 223 String Name;
nuclear@0 224 int Location, Size;
nuclear@0 225 int Type; // currently number of floats in vector
nuclear@0 226
nuclear@0 227 Uniform() : Name(), Location(0), Size(0), Type(0){}
nuclear@0 228 };
nuclear@0 229 Array<Uniform> UniformInfo;
nuclear@0 230
nuclear@0 231 public:
nuclear@0 232 GLuint Prog;
nuclear@0 233 GLint ProjLoc, ViewLoc;
nuclear@0 234 GLint TexLoc[8];
nuclear@0 235 bool UsesLighting;
nuclear@0 236 int LightingVer;
nuclear@0 237
nuclear@0 238 ShaderSet();
nuclear@0 239 ~ShaderSet();
nuclear@0 240
nuclear@0 241 virtual void SetShader(Shader *s);
nuclear@0 242 virtual void UnsetShader(int stage);
nuclear@0 243 Shader* GetShader(int stage) { return Shaders[stage]; }
nuclear@0 244
nuclear@0 245 virtual void Set(PrimitiveType prim) const
nuclear@0 246 {
nuclear@0 247 glUseProgram(Prog);
nuclear@0 248
nuclear@0 249 for (int i = 0; i < Shader_Count; i++)
nuclear@0 250 if (Shaders[i])
nuclear@0 251 Shaders[i]->Set(prim);
nuclear@0 252 }
nuclear@0 253
nuclear@0 254 // Set a uniform (other than the standard matrices). It is undefined whether the
nuclear@0 255 // uniforms from one shader occupy the same space as those in other shaders
nuclear@0 256 // (unless a buffer is used, then each buffer is independent).
nuclear@0 257 virtual bool SetUniform(const char* name, int n, const float* v);
nuclear@0 258 bool SetUniform1f(const char* name, float x)
nuclear@0 259 {
nuclear@0 260 const float v[] = {x};
nuclear@0 261 return SetUniform(name, 1, v);
nuclear@0 262 }
nuclear@0 263 bool SetUniform2f(const char* name, float x, float y)
nuclear@0 264 {
nuclear@0 265 const float v[] = {x,y};
nuclear@0 266 return SetUniform(name, 2, v);
nuclear@0 267 }
nuclear@0 268 bool SetUniform3f(const char* name, float x, float y, float z)
nuclear@0 269 {
nuclear@0 270 const float v[] = {x,y,z};
nuclear@0 271 return SetUniform(name, 3, v);
nuclear@0 272 }
nuclear@0 273 bool SetUniform4f(const char* name, float x, float y, float z, float w = 1)
nuclear@0 274 {
nuclear@0 275 const float v[] = {x,y,z,w};
nuclear@0 276 return SetUniform(name, 4, v);
nuclear@0 277 }
nuclear@0 278
nuclear@0 279 bool SetUniformv(const char* name, const Vector3f& v)
nuclear@0 280 {
nuclear@0 281 const float a[] = {v.x,v.y,v.z,1};
nuclear@0 282 return SetUniform(name, 4, a);
nuclear@0 283 }
nuclear@0 284
nuclear@0 285 virtual bool SetUniform4x4f(const char* name, const Matrix4f& m)
nuclear@0 286 {
nuclear@0 287 Matrix4f mt = m.Transposed();
nuclear@0 288 return SetUniform(name, 16, &mt.M[0][0]);
nuclear@0 289 }
nuclear@0 290
nuclear@0 291 virtual bool SetUniform3x3f(const char* name, const Matrix4f& m)
nuclear@0 292 {
nuclear@0 293 Matrix4f mt = m.Transposed();
nuclear@0 294 // float3x3 is actually stored the same way as float4x3, with the last items ignored by the code.
nuclear@0 295 return SetUniform(name, 12, &mt.M[0][0]);
nuclear@0 296 }
nuclear@0 297
nuclear@0 298
nuclear@0 299 protected:
nuclear@0 300 GLint GetGLShader(Shader* s);
nuclear@0 301 bool Link();
nuclear@0 302 };
nuclear@0 303
nuclear@0 304
nuclear@0 305 // Fill combines a ShaderSet (vertex, pixel) with textures, if any.
nuclear@0 306 // Every model has a fill.
nuclear@0 307 class ShaderFill : public RefCountBase<ShaderFill>
nuclear@0 308 {
nuclear@0 309 Ptr<ShaderSet> Shaders;
nuclear@0 310 Ptr<class Texture> Textures[8];
nuclear@0 311 void* InputLayout; // HACK this should be abstracted
nuclear@0 312
nuclear@0 313 public:
nuclear@0 314 ShaderFill(ShaderSet* sh) : Shaders(sh) { InputLayout = NULL; }
nuclear@0 315 ShaderFill(ShaderSet& sh) : Shaders(sh) { InputLayout = NULL; }
nuclear@0 316
nuclear@0 317 ShaderSet* GetShaders() const { return Shaders; }
nuclear@0 318 void* GetInputLayout() const { return InputLayout; }
nuclear@0 319
nuclear@0 320 virtual void Set(PrimitiveType prim = Prim_Unknown) const {
nuclear@0 321 Shaders->Set(prim);
nuclear@0 322 for(int i = 0; i < 8; i++)
nuclear@0 323 {
nuclear@0 324 if(Textures[i])
nuclear@0 325 {
nuclear@0 326 Textures[i]->Set(i);
nuclear@0 327 }
nuclear@0 328 }
nuclear@0 329 }
nuclear@0 330
nuclear@0 331 virtual void SetTexture(int i, class Texture* tex) { if (i < 8) Textures[i] = tex; }
nuclear@0 332 };
nuclear@0 333
nuclear@0 334
nuclear@0 335 struct DisplayId
nuclear@0 336 {
nuclear@0 337 // Windows
nuclear@0 338 String MonitorName; // Monitor name for fullscreen mode
nuclear@0 339
nuclear@0 340 // MacOS
nuclear@0 341 long CgDisplayId; // CGDirectDisplayID
nuclear@0 342
nuclear@0 343 DisplayId() : CgDisplayId(0) {}
nuclear@0 344 DisplayId(long id) : CgDisplayId(id) {}
nuclear@0 345 DisplayId(String m, long id=0) : MonitorName(m), CgDisplayId(id) {}
nuclear@0 346
nuclear@0 347 operator bool () const
nuclear@0 348 {
nuclear@0 349 return MonitorName.GetLength() || CgDisplayId;
nuclear@0 350 }
nuclear@0 351
nuclear@0 352 bool operator== (const DisplayId& b) const
nuclear@0 353 {
nuclear@0 354 return CgDisplayId == b.CgDisplayId &&
nuclear@0 355 (strstr(MonitorName.ToCStr(), b.MonitorName.ToCStr()) ||
nuclear@0 356 strstr(b.MonitorName.ToCStr(), MonitorName.ToCStr()));
nuclear@0 357 }
nuclear@0 358 };
nuclear@0 359
nuclear@0 360
nuclear@0 361 class ShaderBase : public Shader
nuclear@0 362 {
nuclear@0 363 public:
nuclear@0 364 RenderParams* pParams;
nuclear@0 365 unsigned char* UniformData;
nuclear@0 366 int UniformsSize;
nuclear@0 367
nuclear@0 368 enum VarType
nuclear@0 369 {
nuclear@0 370 VARTYPE_FLOAT,
nuclear@0 371 VARTYPE_INT,
nuclear@0 372 VARTYPE_BOOL,
nuclear@0 373 };
nuclear@0 374
nuclear@0 375 struct Uniform
nuclear@0 376 {
nuclear@0 377 const char* Name;
nuclear@0 378 VarType Type;
nuclear@0 379 int Offset;
nuclear@0 380 int Size;
nuclear@0 381 };
nuclear@0 382
nuclear@0 383 const Uniform* UniformRefl;
nuclear@0 384 size_t UniformReflSize;
nuclear@0 385
nuclear@0 386 ShaderBase(RenderParams* rp, ShaderStage stage) :
nuclear@0 387 Shader(stage),
nuclear@0 388 pParams(rp),
nuclear@0 389 UniformData(NULL),
nuclear@0 390 UniformsSize(0),
nuclear@0 391 UniformRefl(NULL),
nuclear@0 392 UniformReflSize(0)
nuclear@0 393 {
nuclear@0 394 }
nuclear@0 395 ~ShaderBase()
nuclear@0 396 {
nuclear@0 397 if (UniformData)
nuclear@0 398 {
nuclear@0 399 OVR_FREE(UniformData);
nuclear@0 400 UniformData = NULL;
nuclear@0 401 }
nuclear@0 402
nuclear@0 403 // Do not need to free UniformRefl
nuclear@0 404 UniformRefl = NULL;
nuclear@0 405 }
nuclear@0 406
nuclear@0 407 void InitUniforms(const Uniform* refl, size_t reflSize);
nuclear@0 408 bool SetUniform(const char* name, int n, const float* v);
nuclear@0 409 bool SetUniformBool(const char* name, int n, const bool* v);
nuclear@0 410 };
nuclear@0 411
nuclear@0 412
nuclear@0 413 template<ShaderStage SStage, GLenum SType>
nuclear@0 414 class ShaderImpl : public ShaderBase
nuclear@0 415 {
nuclear@0 416 friend class ShaderSet;
nuclear@0 417
nuclear@0 418 public:
nuclear@0 419 ShaderImpl(RenderParams* rp, void* s, size_t size, const Uniform* refl, size_t reflSize)
nuclear@0 420 : ShaderBase(rp, SStage)
nuclear@0 421 , GLShader(0)
nuclear@0 422 {
nuclear@0 423 bool success;
nuclear@0 424 OVR_UNUSED(size);
nuclear@0 425 success = Compile((const char*) s);
nuclear@0 426 OVR_ASSERT(success);
nuclear@0 427 OVR_UNUSED(success);
nuclear@0 428 InitUniforms(refl, reflSize);
nuclear@0 429 }
nuclear@0 430 ~ShaderImpl()
nuclear@0 431 {
nuclear@0 432 if (GLShader)
nuclear@0 433 {
nuclear@0 434 glDeleteShader(GLShader);
nuclear@0 435 GLShader = 0;
nuclear@0 436 }
nuclear@0 437 }
nuclear@0 438 bool Compile(const char* src)
nuclear@0 439 {
nuclear@0 440 if (!GLShader)
nuclear@0 441 GLShader = glCreateShader(GLStage());
nuclear@0 442
nuclear@0 443 glShaderSource(GLShader, 1, &src, 0);
nuclear@0 444 glCompileShader(GLShader);
nuclear@0 445 GLint r;
nuclear@0 446 glGetShaderiv(GLShader, GL_COMPILE_STATUS, &r);
nuclear@0 447 if (!r)
nuclear@0 448 {
nuclear@0 449 GLchar msg[1024];
nuclear@0 450 glGetShaderInfoLog(GLShader, sizeof(msg), 0, msg);
nuclear@0 451 if (msg[0])
nuclear@0 452 OVR_DEBUG_LOG(("Compiling shader\n%s\nfailed: %s\n", src, msg));
nuclear@0 453
nuclear@0 454 return 0;
nuclear@0 455 }
nuclear@0 456 return 1;
nuclear@0 457 }
nuclear@0 458
nuclear@0 459 GLenum GLStage() const
nuclear@0 460 {
nuclear@0 461 return SType;
nuclear@0 462 }
nuclear@0 463
nuclear@0 464 private:
nuclear@0 465 GLuint GLShader;
nuclear@0 466 };
nuclear@0 467
nuclear@0 468 typedef ShaderImpl<Shader_Vertex, GL_VERTEX_SHADER> VertexShader;
nuclear@0 469 typedef ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER> FragmentShader;
nuclear@0 470
nuclear@0 471
nuclear@0 472
nuclear@0 473 // Allows us to have independent OpenGL contexts for our systems.
nuclear@0 474 class Context
nuclear@0 475 {
nuclear@0 476 bool initialized;
nuclear@0 477 bool ownsContext;
nuclear@0 478 int incarnation;
nuclear@0 479 #if defined(OVR_OS_WIN32)
nuclear@0 480 HDC hdc;
nuclear@0 481 HGLRC systemContext;
nuclear@0 482 #elif defined(OVR_OS_LINUX)
nuclear@0 483 Display *x11Display;
nuclear@0 484 GLXDrawable x11Drawable;
nuclear@0 485 GLXContext systemContext;
nuclear@0 486 XVisualInfo x11Visual;
nuclear@0 487 #elif defined(OVR_OS_MAC)
nuclear@0 488 CGLContextObj systemContext;
nuclear@0 489 #endif
nuclear@0 490
nuclear@0 491 public:
nuclear@0 492
nuclear@0 493 Context();
nuclear@0 494 void InitFromCurrent();
nuclear@0 495 void CreateShared( Context & ctx );
nuclear@0 496 #if defined(OVR_OS_MAC)
nuclear@0 497 void SetSurface( Context & ctx );
nuclear@0 498 #endif
nuclear@0 499 void Destroy();
nuclear@0 500 void Bind();
nuclear@0 501 void Unbind();
nuclear@0 502 int GetIncarnation() const { return incarnation; }
nuclear@0 503
nuclear@0 504 };
nuclear@0 505
nuclear@0 506
nuclear@0 507 // AutoContext
nuclear@0 508 //
nuclear@0 509 // Implements a common sequence of function calls with the Context class.
nuclear@0 510 // See the AutoContext constructor below for what it does.
nuclear@0 511 //
nuclear@0 512 // Example usage:
nuclear@0 513 // void SomeClass::Draw()
nuclear@0 514 // {
nuclear@0 515 // AutoContext autoContext(someClassContext);
nuclear@0 516 //
nuclear@0 517 // <draw calls>
nuclear@0 518 // }
nuclear@0 519
nuclear@0 520 struct AutoContext
nuclear@0 521 {
nuclear@0 522 Context savedCurrentContext;
nuclear@0 523 Context& ourContext;
nuclear@0 524
nuclear@0 525 AutoContext(Context& context) :
nuclear@0 526 savedCurrentContext(), ourContext(context)
nuclear@0 527 {
nuclear@0 528 // We use a member savedCurrentContext which is initialized here, as opposed to having the user pass in a
nuclear@0 529 // pre-existing Context (which the user could declare as a global or C++ member variable). We have to do this
nuclear@0 530 // because if we were to use some pre-existing Context the app might delete its underlying GL context behind our back
nuclear@0 531 // or associate it with another thread, which would cause our bind of it in our dtor to be a bad operation.
nuclear@0 532 savedCurrentContext.InitFromCurrent();
nuclear@0 533 if(ourContext.GetIncarnation() == 0) // If not yet initialized...
nuclear@0 534 ourContext.CreateShared(savedCurrentContext);
nuclear@0 535 ourContext.Bind();
nuclear@0 536 #if defined(OVR_OS_MAC) // To consider: merge the following into the Bind function.
nuclear@0 537 ourContext.SetSurface(savedCurrentContext);
nuclear@0 538 #endif
nuclear@0 539 }
nuclear@0 540
nuclear@0 541 ~AutoContext()
nuclear@0 542 {
nuclear@0 543 savedCurrentContext.Bind();
nuclear@0 544 }
nuclear@0 545
nuclear@0 546 OVR_NON_COPYABLE(AutoContext)
nuclear@0 547 };
nuclear@0 548
nuclear@0 549
nuclear@0 550 }}} // namespace OVR::CAPI::GL
nuclear@0 551
nuclear@0 552
nuclear@0 553 #endif // INC_OVR_CAPI_GL_Util_h