int RE_InitOpenGlSubsystems(void) { #ifndef FEATURE_RENDERER_GLES GLenum glewResult; #endif #if !defined(FEATURE_RENDERER_GLES) #if defined(FEATURE_RENDERER2) glewExperimental = GL_TRUE; #endif glewResult = glewInit(); if (GLEW_OK != glewResult) { // glewInit failed, something is seriously wrong Ren_Fatal("GLW_StartOpenGL() - could not load OpenGL subsystem: %s", glewGetErrorString(glewResult)); } else { Com_Printf("Using GLEW %s\n", glewGetString(GLEW_VERSION)); } #endif if (!GLimp_InitOpenGLContext()) { return qfalse; } return qtrue; }
static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder) { int perChannelColorBits; int colorBits, depthBits, stencilBits; int samples; int i = 0; SDL_Surface *icon = NULL; SDL_DisplayMode desktopMode; int display = 0; int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED; Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_GRABBED; #ifndef FEATURE_RENDERER_GLES GLenum glewResult; #endif Ren_Print("Initializing OpenGL display\n"); if (r_allowResize->integer && !fullscreen) { flags |= SDL_WINDOW_RESIZABLE; } icon = SDL_CreateRGBSurfaceFrom( (void *)CLIENT_WINDOW_ICON.pixel_data, CLIENT_WINDOW_ICON.width, CLIENT_WINDOW_ICON.height, CLIENT_WINDOW_ICON.bytes_per_pixel * 8, CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width, #ifdef Q3_LITTLE_ENDIAN 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #else 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF #endif ); // If a window exists, note its display index if (main_window != NULL) { display = SDL_GetWindowDisplayIndex(main_window); } if (SDL_GetDesktopDisplayMode(display, &desktopMode) == 0) { displayAspect = (float)desktopMode.w / (float)desktopMode.h; Ren_Print("Estimated display aspect: %.3f\n", displayAspect); } else { Com_Memset(&desktopMode, 0, sizeof(SDL_DisplayMode)); Ren_Print("Cannot estimate display aspect, assuming 1.333\n"); } Ren_Print("...setting mode %d: ", mode); if (mode == -2) { // use desktop video resolution if (desktopMode.h > 0) { glConfig.vidWidth = desktopMode.w; glConfig.vidHeight = desktopMode.h; } else { glConfig.vidWidth = 640; glConfig.vidHeight = 480; Ren_Print("Cannot determine display resolution, assuming 640x480\n"); } glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight; } else if (!R_GetModeInfo(&glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode)) { Ren_Print("invalid mode\n"); return RSERR_INVALID_MODE; } Ren_Print("%dx%d\n", glConfig.vidWidth, glConfig.vidHeight); // Center window if (r_centerWindow->integer && !fullscreen) { x = (desktopMode.w / 2) - (glConfig.vidWidth / 2); y = (desktopMode.h / 2) - (glConfig.vidHeight / 2); } // Destroy existing state if it exists if (SDL_glContext != NULL) { SDL_GL_DeleteContext(SDL_glContext); SDL_glContext = NULL; } if (main_window != NULL) { SDL_GetWindowPosition(main_window, &x, &y); Ren_Developer("Existing window at %dx%d before being destroyed\n", x, y); SDL_DestroyWindow(main_window); main_window = NULL; } if (fullscreen) { if (r_mode->integer == -2) { flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } else { flags |= SDL_WINDOW_FULLSCREEN; } glConfig.isFullscreen = qtrue; } else { if (noborder) { flags |= SDL_WINDOW_BORDERLESS; } glConfig.isFullscreen = qfalse; } colorBits = r_colorbits->value; if ((!colorBits) || (colorBits >= 32)) { colorBits = 24; } if (!r_depthbits->value) { depthBits = 24; } else { depthBits = r_depthbits->value; } stencilBits = r_stencilbits->value; samples = r_ext_multisample->value; for (i = 0; i < 16; i++) { int testColorBits, testDepthBits, testStencilBits; // 0 - default // 1 - minus colorBits // 2 - minus depthBits // 3 - minus stencil if ((i % 4) == 0 && i) { // one pass, reduce switch (i / 4) { case 2: if (colorBits == 24) { colorBits = 16; } break; case 1: if (depthBits == 32) { depthBits = 24; } else if (depthBits == 24) { depthBits = 16; } else if (depthBits == 16) { depthBits = 8; } case 3: // fall through if (stencilBits == 24) { stencilBits = 16; } else if (stencilBits == 16) { stencilBits = 8; } } } testColorBits = colorBits; testDepthBits = depthBits; testStencilBits = stencilBits; if ((i % 4) == 3) // reduce colorbits { if (testColorBits == 24) { testColorBits = 16; } } if ((i % 4) == 2) // reduce depthbits { if (testDepthBits == 24) { testDepthBits = 16; } else if (testDepthBits == 16) { testDepthBits = 8; } } if ((i % 4) == 1) // reduce stencilbits { if (testStencilBits == 24) { testStencilBits = 16; } else if (testStencilBits == 16) { testStencilBits = 8; } else { testStencilBits = 0; } } if (testColorBits == 24) { perChannelColorBits = 8; } else { perChannelColorBits = 4; } #ifdef __sgi // Fix for SGIs grabbing too many bits of color if (perChannelColorBits == 4) { perChannelColorBits = 0; /* Use minimum size for 16-bit color */ } // Need alpha or else SGIs choose 36+ bit RGB mode SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 1); #endif SDL_GL_SetAttribute(SDL_GL_RED_SIZE, perChannelColorBits); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, perChannelColorBits); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, perChannelColorBits); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, testDepthBits); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, testStencilBits); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples); // SDL2 uses opengl by default, if we want opengl es we need to set this attribute //SDL_GL_SetAttribute(SDL_GL_CONTEXT_EGL, 1); if (r_stereoEnabled->integer) { glConfig.stereoEnabled = qtrue; SDL_GL_SetAttribute(SDL_GL_STEREO, 1); } else { glConfig.stereoEnabled = qfalse; SDL_GL_SetAttribute(SDL_GL_STEREO, 0); } SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // If not allowing software GL, demand accelerated if (!r_allowSoftwareGL->integer) { SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); } main_window = SDL_CreateWindow(CLIENT_WINDOW_TITLE, x, y, glConfig.vidWidth, glConfig.vidHeight, flags | SDL_WINDOW_SHOWN); if (!main_window) { Ren_Developer("SDL_CreateWindow failed: %s\n", SDL_GetError()); continue; } //This is disabled since at least now we have no use for this /* if (!Glimp_Create2DRenderer(main_window)) { continue; } */ if (fullscreen) { SDL_DisplayMode mode; switch (testColorBits) { case 16: mode.format = SDL_PIXELFORMAT_RGB565; break; case 24: mode.format = SDL_PIXELFORMAT_RGB24; break; default: Ren_Developer("testColorBits is %d, can't fullscreen\n", testColorBits); continue; } mode.w = glConfig.vidWidth; mode.h = glConfig.vidHeight; mode.refresh_rate = glConfig.displayFrequency = ri.Cvar_VariableIntegerValue("r_displayRefresh"); mode.driverdata = NULL; if (SDL_SetWindowDisplayMode(main_window, &mode) < 0) { Ren_Developer("SDL_SetWindowDisplayMode failed: %s\n", SDL_GetError()); continue; } } SDL_SetWindowIcon(main_window, icon); #if defined(FEATURE_RENDERER2) glewExperimental = GL_TRUE; SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); #endif if ((SDL_glContext = SDL_GL_CreateContext(main_window)) == NULL) { Ren_Developer("SDL_GL_CreateContext failed: %s\n", SDL_GetError()); continue; } SDL_GL_MakeCurrent(main_window, SDL_glContext); SDL_GL_SetSwapInterval(r_swapInterval->integer); glConfig.colorBits = testColorBits; glConfig.depthBits = testDepthBits; glConfig.stencilBits = testStencilBits; ri.Printf(PRINT_ALL, "Using %d color bits, %d depth, %d stencil display.\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits); break; } GLimp_DetectAvailableModes(); #if !defined(FEATURE_RENDERER_GLES) glewResult = glewInit(); if (GLEW_OK != glewResult) { // glewInit failed, something is seriously wrong Ren_Fatal("GLW_StartOpenGL() - could not load OpenGL subsystem: %s", glewGetErrorString(glewResult)); } else { Ren_Print("Using GLEW %s\n", glewGetString(GLEW_VERSION)); } #endif if (!GLimp_InitOpenGLContext()) { return RSERR_OLD_GL; } if (!main_window) //|| !main_renderer) { Ren_Print("Couldn't get a visual\n"); return RSERR_INVALID_MODE; } SDL_FreeSurface(icon); return RSERR_OK; }