ovr_sdk

annotate 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
rev   line source
nuclear@0 1 /************************************************************************************
nuclear@0 2
nuclear@0 3 Filename : CAPI_GL_Util.cpp
nuclear@0 4 Content : RenderDevice implementation for OpenGL
nuclear@0 5 Created : September 10, 2012
nuclear@0 6 Authors : David Borel, Andrew Reisse
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 #include "CAPI_GL_Util.h"
nuclear@0 28 #include "../../Kernel/OVR_Log.h"
nuclear@0 29 #include <string.h>
nuclear@0 30
nuclear@0 31 #if defined(OVR_OS_LINUX)
nuclear@0 32 #include "../../Displays/OVR_Linux_SDKWindow.h"
nuclear@0 33 #endif
nuclear@0 34
nuclear@0 35 #if defined(OVR_OS_MAC)
nuclear@0 36 #include <CoreGraphics/CGDirectDisplay.h>
nuclear@0 37 #include <OpenGL/OpenGL.h>
nuclear@0 38
nuclear@0 39 typedef void *CGSConnectionID;
nuclear@0 40 typedef int32_t CGSWindowID;
nuclear@0 41 typedef int32_t CGSSurfaceID;
nuclear@0 42
nuclear@0 43 extern "C" CGLError CGLGetSurface(CGLContextObj ctx, CGSConnectionID *cid, CGSWindowID *wid, CGSSurfaceID *sid);
nuclear@0 44 extern "C" CGLError CGLSetSurface(CGLContextObj ctx, CGSConnectionID cid, CGSWindowID wid, CGSSurfaceID sid);
nuclear@0 45 #endif
nuclear@0 46
nuclear@0 47
nuclear@0 48
nuclear@0 49
nuclear@0 50 namespace OVR {
nuclear@0 51
nuclear@0 52
nuclear@0 53 OVR::GLEContext gleContext;
nuclear@0 54
nuclear@0 55
nuclear@0 56 OVR::GLEContext* GetGLEContext()
nuclear@0 57 {
nuclear@0 58 return &gleContext;
nuclear@0 59 }
nuclear@0 60
nuclear@0 61
nuclear@0 62 namespace CAPI { namespace GL {
nuclear@0 63
nuclear@0 64
nuclear@0 65 void InitGLExtensions()
nuclear@0 66 {
nuclear@0 67 if(!gleContext.IsInitialized())
nuclear@0 68 {
nuclear@0 69 gleContext.SetCurrentContext(&gleContext);
nuclear@0 70 gleContext.Init();
nuclear@0 71 }
nuclear@0 72 }
nuclear@0 73
nuclear@0 74
nuclear@0 75 Buffer::Buffer(RenderParams* rp) : pParams(rp), Size(0), Use(0), GLBuffer(0)
nuclear@0 76 {
nuclear@0 77 }
nuclear@0 78
nuclear@0 79 Buffer::~Buffer()
nuclear@0 80 {
nuclear@0 81 if (GLBuffer)
nuclear@0 82 glDeleteBuffers(1, &GLBuffer);
nuclear@0 83 }
nuclear@0 84
nuclear@0 85 bool Buffer::Data(int use, const void* buffer, size_t size)
nuclear@0 86 {
nuclear@0 87 Size = size;
nuclear@0 88
nuclear@0 89 switch (use & Buffer_TypeMask)
nuclear@0 90 {
nuclear@0 91 case Buffer_Index: Use = GL_ELEMENT_ARRAY_BUFFER; break;
nuclear@0 92 default: Use = GL_ARRAY_BUFFER; break;
nuclear@0 93 }
nuclear@0 94
nuclear@0 95 if (!GLBuffer)
nuclear@0 96 glGenBuffers(1, &GLBuffer);
nuclear@0 97
nuclear@0 98 int mode = GL_DYNAMIC_DRAW;
nuclear@0 99 if (use & Buffer_ReadOnly)
nuclear@0 100 mode = GL_STATIC_DRAW;
nuclear@0 101
nuclear@0 102 glBindBuffer(Use, GLBuffer);
nuclear@0 103 glBufferData(Use, size, buffer, mode);
nuclear@0 104 return 1;
nuclear@0 105 }
nuclear@0 106
nuclear@0 107 void* Buffer::Map(size_t, size_t, int)
nuclear@0 108 {
nuclear@0 109 int mode = GL_WRITE_ONLY;
nuclear@0 110 //if (flags & Map_Unsynchronized)
nuclear@0 111 // mode |= GL_MAP_UNSYNCHRONIZED;
nuclear@0 112
nuclear@0 113 glBindBuffer(Use, GLBuffer);
nuclear@0 114 void* v = glMapBuffer(Use, mode);
nuclear@0 115 return v;
nuclear@0 116 }
nuclear@0 117
nuclear@0 118 bool Buffer::Unmap(void*)
nuclear@0 119 {
nuclear@0 120 glBindBuffer(Use, GLBuffer);
nuclear@0 121 int r = glUnmapBuffer(Use);
nuclear@0 122 return r != 0;
nuclear@0 123 }
nuclear@0 124
nuclear@0 125 ShaderSet::ShaderSet() :
nuclear@0 126 //Shaders[],
nuclear@0 127 UniformInfo(),
nuclear@0 128 //Prog(0)
nuclear@0 129 ProjLoc(0),
nuclear@0 130 ViewLoc(0),
nuclear@0 131 //TexLoc[],
nuclear@0 132 UsesLighting(false),
nuclear@0 133 LightingVer(0)
nuclear@0 134 {
nuclear@0 135 memset(TexLoc, 0, sizeof(TexLoc));
nuclear@0 136 Prog = glCreateProgram();
nuclear@0 137 }
nuclear@0 138 ShaderSet::~ShaderSet()
nuclear@0 139 {
nuclear@0 140 glDeleteProgram(Prog);
nuclear@0 141 }
nuclear@0 142
nuclear@0 143 GLint ShaderSet::GetGLShader(Shader* s)
nuclear@0 144 {
nuclear@0 145 switch (s->Stage)
nuclear@0 146 {
nuclear@0 147 case Shader_Vertex: {
nuclear@0 148 ShaderImpl<Shader_Vertex, GL_VERTEX_SHADER>* gls = (ShaderImpl<Shader_Vertex, GL_VERTEX_SHADER>*)s;
nuclear@0 149 return gls->GLShader;
nuclear@0 150 } break;
nuclear@0 151 case Shader_Fragment: {
nuclear@0 152 ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER>* gls = (ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER>*)s;
nuclear@0 153 return gls->GLShader;
nuclear@0 154 } break;
nuclear@0 155 default: break;
nuclear@0 156 }
nuclear@0 157
nuclear@0 158 return -1;
nuclear@0 159 }
nuclear@0 160
nuclear@0 161 void ShaderSet::SetShader(Shader *s)
nuclear@0 162 {
nuclear@0 163 Shaders[s->Stage] = s;
nuclear@0 164 GLint GLShader = GetGLShader(s);
nuclear@0 165 glAttachShader(Prog, GLShader);
nuclear@0 166 if (Shaders[Shader_Vertex] && Shaders[Shader_Fragment])
nuclear@0 167 Link();
nuclear@0 168 }
nuclear@0 169
nuclear@0 170 void ShaderSet::UnsetShader(int stage)
nuclear@0 171 {
nuclear@0 172 if (Shaders[stage] == NULL)
nuclear@0 173 return;
nuclear@0 174
nuclear@0 175 GLint GLShader = GetGLShader(Shaders[stage]);
nuclear@0 176 glDetachShader(Prog, GLShader);
nuclear@0 177
nuclear@0 178 Shaders[stage] = NULL;
nuclear@0 179 }
nuclear@0 180
nuclear@0 181 bool ShaderSet::SetUniform(const char* name, int n, const float* v)
nuclear@0 182 {
nuclear@0 183 for (unsigned int i = 0; i < UniformInfo.GetSize(); i++)
nuclear@0 184 if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
nuclear@0 185 {
nuclear@0 186 OVR_ASSERT(UniformInfo[i].Location >= 0);
nuclear@0 187 glUseProgram(Prog);
nuclear@0 188 switch (UniformInfo[i].Type)
nuclear@0 189 {
nuclear@0 190 case 1: glUniform1fv(UniformInfo[i].Location, n, v); break;
nuclear@0 191 case 2: glUniform2fv(UniformInfo[i].Location, n/2, v); break;
nuclear@0 192 case 3: glUniform3fv(UniformInfo[i].Location, n/3, v); break;
nuclear@0 193 case 4: glUniform4fv(UniformInfo[i].Location, n/4, v); break;
nuclear@0 194 case 12: glUniformMatrix3fv(UniformInfo[i].Location, 1, 1, v); break;
nuclear@0 195 case 16: glUniformMatrix4fv(UniformInfo[i].Location, 1, 1, v); break;
nuclear@0 196 default: OVR_ASSERT(0);
nuclear@0 197 }
nuclear@0 198 return 1;
nuclear@0 199 }
nuclear@0 200
nuclear@0 201 OVR_DEBUG_LOG(("Warning: uniform %s not present in selected shader", name));
nuclear@0 202 return 0;
nuclear@0 203 }
nuclear@0 204
nuclear@0 205 bool ShaderSet::Link()
nuclear@0 206 {
nuclear@0 207 glLinkProgram(Prog);
nuclear@0 208 GLint r;
nuclear@0 209 glGetProgramiv(Prog, GL_LINK_STATUS, &r);
nuclear@0 210 if (!r)
nuclear@0 211 {
nuclear@0 212 GLchar msg[1024];
nuclear@0 213 glGetProgramInfoLog(Prog, sizeof(msg), 0, msg);
nuclear@0 214 OVR_DEBUG_LOG(("Linking shaders failed: %s\n", msg));
nuclear@0 215 if (!r)
nuclear@0 216 return 0;
nuclear@0 217 }
nuclear@0 218 glUseProgram(Prog);
nuclear@0 219
nuclear@0 220 UniformInfo.Clear();
nuclear@0 221 LightingVer = 0;
nuclear@0 222 UsesLighting = 0;
nuclear@0 223
nuclear@0 224 GLint uniformCount = 0;
nuclear@0 225 glGetProgramiv(Prog, GL_ACTIVE_UNIFORMS, &uniformCount);
nuclear@0 226 OVR_ASSERT(uniformCount >= 0);
nuclear@0 227
nuclear@0 228 for(GLuint i = 0; i < (GLuint)uniformCount; i++)
nuclear@0 229 {
nuclear@0 230 GLsizei namelen;
nuclear@0 231 GLint size = 0;
nuclear@0 232 GLenum type;
nuclear@0 233 GLchar name[32];
nuclear@0 234 glGetActiveUniform(Prog, i, sizeof(name), &namelen, &size, &type, name);
nuclear@0 235
nuclear@0 236 if (size)
nuclear@0 237 {
nuclear@0 238 int l = glGetUniformLocation(Prog, name);
nuclear@0 239 char *np = name;
nuclear@0 240 while (*np)
nuclear@0 241 {
nuclear@0 242 if (*np == '[')
nuclear@0 243 *np = 0;
nuclear@0 244 np++;
nuclear@0 245 }
nuclear@0 246 Uniform u;
nuclear@0 247 u.Name = name;
nuclear@0 248 u.Location = l;
nuclear@0 249 u.Size = size;
nuclear@0 250 switch (type)
nuclear@0 251 {
nuclear@0 252 case GL_FLOAT: u.Type = 1; break;
nuclear@0 253 case GL_FLOAT_VEC2: u.Type = 2; break;
nuclear@0 254 case GL_FLOAT_VEC3: u.Type = 3; break;
nuclear@0 255 case GL_FLOAT_VEC4: u.Type = 4; break;
nuclear@0 256 case GL_FLOAT_MAT3: u.Type = 12; break;
nuclear@0 257 case GL_FLOAT_MAT4: u.Type = 16; break;
nuclear@0 258 default:
nuclear@0 259 continue;
nuclear@0 260 }
nuclear@0 261 UniformInfo.PushBack(u);
nuclear@0 262 if (!strcmp(name, "LightCount"))
nuclear@0 263 UsesLighting = 1;
nuclear@0 264 }
nuclear@0 265 else
nuclear@0 266 break;
nuclear@0 267 }
nuclear@0 268
nuclear@0 269 ProjLoc = glGetUniformLocation(Prog, "Proj");
nuclear@0 270 ViewLoc = glGetUniformLocation(Prog, "View");
nuclear@0 271 for (int i = 0; i < 8; i++)
nuclear@0 272 {
nuclear@0 273 char texv[32];
nuclear@0 274 OVR_sprintf(texv, 10, "Texture%d", i);
nuclear@0 275 TexLoc[i] = glGetUniformLocation(Prog, texv);
nuclear@0 276 if (TexLoc[i] < 0)
nuclear@0 277 break;
nuclear@0 278
nuclear@0 279 glUniform1i(TexLoc[i], i);
nuclear@0 280 }
nuclear@0 281 if (UsesLighting)
nuclear@0 282 OVR_ASSERT(ProjLoc >= 0 && ViewLoc >= 0);
nuclear@0 283 return 1;
nuclear@0 284 }
nuclear@0 285
nuclear@0 286 bool ShaderBase::SetUniform(const char* name, int n, const float* v)
nuclear@0 287 {
nuclear@0 288 for(unsigned i = 0; i < UniformReflSize; i++)
nuclear@0 289 {
nuclear@0 290 if (!strcmp(UniformRefl[i].Name, name))
nuclear@0 291 {
nuclear@0 292 memcpy(UniformData + UniformRefl[i].Offset, v, n * sizeof(float));
nuclear@0 293 return 1;
nuclear@0 294 }
nuclear@0 295 }
nuclear@0 296 return 0;
nuclear@0 297 }
nuclear@0 298
nuclear@0 299 bool ShaderBase::SetUniformBool(const char* name, int n, const bool* v)
nuclear@0 300 {
nuclear@0 301 OVR_UNUSED(n);
nuclear@0 302 for(unsigned i = 0; i < UniformReflSize; i++)
nuclear@0 303 {
nuclear@0 304 if (!strcmp(UniformRefl[i].Name, name))
nuclear@0 305 {
nuclear@0 306 memcpy(UniformData + UniformRefl[i].Offset, v, UniformRefl[i].Size);
nuclear@0 307 return 1;
nuclear@0 308 }
nuclear@0 309 }
nuclear@0 310 return 0;
nuclear@0 311 }
nuclear@0 312
nuclear@0 313 void ShaderBase::InitUniforms(const Uniform* refl, size_t reflSize)
nuclear@0 314 {
nuclear@0 315 if(!refl)
nuclear@0 316 {
nuclear@0 317 UniformRefl = NULL;
nuclear@0 318 UniformReflSize = 0;
nuclear@0 319
nuclear@0 320 UniformsSize = 0;
nuclear@0 321 if (UniformData)
nuclear@0 322 {
nuclear@0 323 OVR_FREE(UniformData);
nuclear@0 324 UniformData = 0;
nuclear@0 325 }
nuclear@0 326 return; // no reflection data
nuclear@0 327 }
nuclear@0 328
nuclear@0 329 UniformRefl = refl;
nuclear@0 330 UniformReflSize = reflSize;
nuclear@0 331
nuclear@0 332 UniformsSize = UniformRefl[UniformReflSize-1].Offset + UniformRefl[UniformReflSize-1].Size;
nuclear@0 333 UniformData = (unsigned char*)OVR_ALLOC(UniformsSize);
nuclear@0 334 }
nuclear@0 335
nuclear@0 336 Texture::Texture(RenderParams* rp, int w, int h) : IsUserAllocated(false), pParams(rp), TexId(0), Width(w), Height(h)
nuclear@0 337 {
nuclear@0 338 if (w && h)
nuclear@0 339 glGenTextures(1, &TexId);
nuclear@0 340 }
nuclear@0 341
nuclear@0 342 Texture::~Texture()
nuclear@0 343 {
nuclear@0 344 if (TexId && !IsUserAllocated)
nuclear@0 345 glDeleteTextures(1, &TexId);
nuclear@0 346 }
nuclear@0 347
nuclear@0 348 void Texture::Set(int slot, ShaderStage) const
nuclear@0 349 {
nuclear@0 350 glActiveTexture(GL_TEXTURE0 + slot);
nuclear@0 351 glBindTexture(GL_TEXTURE_2D, TexId);
nuclear@0 352 }
nuclear@0 353
nuclear@0 354 void Texture::SetSampleMode(int sm)
nuclear@0 355 {
nuclear@0 356 glBindTexture(GL_TEXTURE_2D, TexId);
nuclear@0 357 switch (sm & Sample_FilterMask)
nuclear@0 358 {
nuclear@0 359 case Sample_Linear:
nuclear@0 360 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
nuclear@0 361 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@0 362 if(GLE_EXT_texture_filter_anisotropic)
nuclear@0 363 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
nuclear@0 364 break;
nuclear@0 365
nuclear@0 366 case Sample_Anisotropic:
nuclear@0 367 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
nuclear@0 368 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@0 369 if(GLE_EXT_texture_filter_anisotropic)
nuclear@0 370 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8);
nuclear@0 371 break;
nuclear@0 372
nuclear@0 373 case Sample_Nearest:
nuclear@0 374 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
nuclear@0 375 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
nuclear@0 376 if(GLE_EXT_texture_filter_anisotropic)
nuclear@0 377 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
nuclear@0 378 break;
nuclear@0 379 }
nuclear@0 380
nuclear@0 381 switch (sm & Sample_AddressMask)
nuclear@0 382 {
nuclear@0 383 case Sample_Repeat:
nuclear@0 384 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
nuclear@0 385 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
nuclear@0 386 break;
nuclear@0 387
nuclear@0 388 case Sample_Clamp:
nuclear@0 389 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
nuclear@0 390 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
nuclear@0 391 break;
nuclear@0 392
nuclear@0 393 case Sample_ClampBorder:
nuclear@0 394 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
nuclear@0 395 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
nuclear@0 396 break;
nuclear@0 397 }
nuclear@0 398 }
nuclear@0 399
nuclear@0 400 void Texture::UpdatePlaceholderTexture(GLuint texId, const Sizei& textureSize)
nuclear@0 401 {
nuclear@0 402 if (!IsUserAllocated && TexId && texId != TexId)
nuclear@0 403 glDeleteTextures(1, &TexId);
nuclear@0 404
nuclear@0 405 TexId = texId;
nuclear@0 406 Width = textureSize.w;
nuclear@0 407 Height = textureSize.h;
nuclear@0 408
nuclear@0 409 IsUserAllocated = true;
nuclear@0 410 }
nuclear@0 411
nuclear@0 412
nuclear@0 413
nuclear@0 414
nuclear@0 415
nuclear@0 416 Context::Context() : initialized(false), ownsContext(true), incarnation(0)
nuclear@0 417 {
nuclear@0 418 #if defined(OVR_OS_MAC)
nuclear@0 419 systemContext = 0;
nuclear@0 420 #elif defined(OVR_OS_WIN32)
nuclear@0 421 hdc = 0;
nuclear@0 422 systemContext = 0;
nuclear@0 423 #elif defined(OVR_OS_LINUX)
nuclear@0 424 x11Display = NULL;
nuclear@0 425 x11Drawable = 0;
nuclear@0 426 systemContext = 0;
nuclear@0 427 memset(&x11Visual, 0, sizeof(x11Visual));
nuclear@0 428 #endif
nuclear@0 429
nuclear@0 430 }
nuclear@0 431
nuclear@0 432 void Context::InitFromCurrent()
nuclear@0 433 {
nuclear@0 434 Destroy();
nuclear@0 435
nuclear@0 436 initialized = true;
nuclear@0 437 ownsContext = false;
nuclear@0 438 incarnation++;
nuclear@0 439
nuclear@0 440 #if defined(OVR_OS_MAC)
nuclear@0 441 systemContext = CGLGetCurrentContext();
nuclear@0 442 {
nuclear@0 443 CGSConnectionID cid;
nuclear@0 444 CGSWindowID wid;
nuclear@0 445 CGSSurfaceID sid;
nuclear@0 446 CGLError e = kCGLNoError;
nuclear@0 447 e = CGLGetSurface(systemContext, &cid, &wid, &sid);
nuclear@0 448 OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e);
nuclear@0 449 }
nuclear@0 450
nuclear@0 451 #elif defined(OVR_OS_WIN32)
nuclear@0 452 hdc = wglGetCurrentDC();
nuclear@0 453 systemContext = wglGetCurrentContext();
nuclear@0 454 #elif defined(OVR_OS_LINUX)
nuclear@0 455 x11Display = glXGetCurrentDisplay();
nuclear@0 456 x11Drawable = glXGetCurrentDrawable();
nuclear@0 457 systemContext = glXGetCurrentContext();
nuclear@0 458 if (!SDKWindow::getVisualFromDrawable(x11Drawable, &x11Visual))
nuclear@0 459 {
nuclear@0 460 OVR::LogError("[Context] Unable to obtain x11 visual from context");
nuclear@0 461 memset(&x11Visual, 0, sizeof(x11Visual));
nuclear@0 462 }
nuclear@0 463 #endif
nuclear@0 464 }
nuclear@0 465
nuclear@0 466
nuclear@0 467 void Context::CreateShared( Context & ctx )
nuclear@0 468 {
nuclear@0 469 Destroy();
nuclear@0 470 OVR_ASSERT( ctx.initialized == true );
nuclear@0 471 if( ctx.initialized == false )
nuclear@0 472 {
nuclear@0 473 return;
nuclear@0 474 }
nuclear@0 475
nuclear@0 476 initialized = true;
nuclear@0 477 ownsContext = true;
nuclear@0 478 incarnation++;
nuclear@0 479
nuclear@0 480 #if defined(OVR_OS_MAC)
nuclear@0 481 CGLPixelFormatObj pixelFormat = CGLGetPixelFormat( ctx.systemContext );
nuclear@0 482 CGLError e = CGLCreateContext( pixelFormat, ctx.systemContext, &systemContext );
nuclear@0 483 OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e);
nuclear@0 484 SetSurface(ctx);
nuclear@0 485 #elif defined(OVR_OS_WIN32)
nuclear@0 486 hdc = ctx.hdc;
nuclear@0 487 systemContext = wglCreateContext( ctx.hdc );
nuclear@0 488 BOOL success = wglShareLists(ctx.systemContext, systemContext );
nuclear@0 489 OVR_ASSERT( success == TRUE );
nuclear@0 490 OVR_UNUSED(success);
nuclear@0 491 #elif defined(OVR_OS_LINUX)
nuclear@0 492 x11Display = ctx.x11Display;
nuclear@0 493 x11Drawable = ctx.x11Drawable;
nuclear@0 494 x11Visual = ctx.x11Visual;
nuclear@0 495 systemContext = glXCreateContext( ctx.x11Display, &x11Visual, ctx.systemContext, True );
nuclear@0 496 OVR_ASSERT( systemContext != NULL );
nuclear@0 497 #endif
nuclear@0 498 }
nuclear@0 499
nuclear@0 500 #if defined(OVR_OS_MAC)
nuclear@0 501 void Context::SetSurface( Context & ctx ) {
nuclear@0 502 CGLError e = kCGLNoError;
nuclear@0 503 CGSConnectionID cid, cid2;
nuclear@0 504 CGSWindowID wid, wid2;
nuclear@0 505 CGSSurfaceID sid, sid2;
nuclear@0 506
nuclear@0 507 e = CGLGetSurface(ctx.systemContext, &cid, &wid, &sid);
nuclear@0 508 OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e);
nuclear@0 509 e = CGLGetSurface(systemContext, &cid2, &wid2, &sid2);
nuclear@0 510 OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e);
nuclear@0 511 if( sid && sid != sid2 ) {
nuclear@0 512 e = CGLSetSurface(systemContext, cid, wid, sid);
nuclear@0 513 OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e);
nuclear@0 514 }
nuclear@0 515 }
nuclear@0 516 #endif
nuclear@0 517
nuclear@0 518 void Context::Destroy()
nuclear@0 519 {
nuclear@0 520 if( initialized == false )
nuclear@0 521 {
nuclear@0 522 return;
nuclear@0 523 }
nuclear@0 524
nuclear@0 525 if (systemContext)
nuclear@0 526 {
nuclear@0 527 #if defined(OVR_OS_MAC)
nuclear@0 528 CGLDestroyContext( systemContext );
nuclear@0 529 #elif defined(OVR_OS_WIN32)
nuclear@0 530 BOOL success = wglDeleteContext( systemContext );
nuclear@0 531 OVR_ASSERT( success == TRUE );
nuclear@0 532 OVR_UNUSED( success );
nuclear@0 533 #elif defined(OVR_OS_LINUX)
nuclear@0 534 glXDestroyContext( x11Display, systemContext );
nuclear@0 535 #endif
nuclear@0 536
nuclear@0 537 systemContext = NULL;
nuclear@0 538 }
nuclear@0 539
nuclear@0 540 initialized = false;
nuclear@0 541 ownsContext = true;
nuclear@0 542 }
nuclear@0 543
nuclear@0 544 void Context::Bind()
nuclear@0 545 {
nuclear@0 546 if(systemContext)
nuclear@0 547 {
nuclear@0 548 #if defined(OVR_OS_MAC)
nuclear@0 549 glFlush(); //Apple doesn't automatically flush within CGLSetCurrentContext, unlike other platforms.
nuclear@0 550 CGLSetCurrentContext( systemContext );
nuclear@0 551 #elif defined(OVR_OS_WIN32)
nuclear@0 552 wglMakeCurrent( hdc, systemContext );
nuclear@0 553 #elif defined(OVR_OS_LINUX)
nuclear@0 554 glXMakeCurrent( x11Display, x11Drawable, systemContext );
nuclear@0 555 #endif
nuclear@0 556 }
nuclear@0 557 }
nuclear@0 558
nuclear@0 559 void Context::Unbind()
nuclear@0 560 {
nuclear@0 561 #if defined(OVR_OS_MAC)
nuclear@0 562 glFlush(); //Apple doesn't automatically flush within CGLSetCurrentContext, unlike other platforms.
nuclear@0 563 CGLSetCurrentContext( NULL );
nuclear@0 564 #elif defined(OVR_OS_WIN32)
nuclear@0 565 wglMakeCurrent( hdc, NULL );
nuclear@0 566 #elif defined(OVR_OS_LINUX)
nuclear@0 567 glXMakeCurrent( x11Display, None, NULL );
nuclear@0 568 #endif
nuclear@0 569 }
nuclear@0 570
nuclear@0 571 }}} // namespace OVR::CAPI::GL