//-------------------------------------------------------------- // initialize graphics BOOL mgLinuxGL33Support::initDisplay() { mgDebug("------ try to create OpenGL 3.3 context, fullscreen=%s, multiSample=%s", m_fullscreen?"true":"false", m_multiSample?"true":"false"); mgLinuxServices* platform = (mgLinuxServices*) mgPlatform; // =-= some drivers are failing this test. not clear we need it #ifdef WORKED int glxMajor, glxMinor; glXQueryVersion(platform->m_display, &glxMajor, &glxMinor); mgDebug("GLX version = %d.%d", glxMajor, glxMinor); int glxVersion = glxMajor * 100 + glxMinor; if (glxVersion < 103) { mgDebug("GLX version < 1.3"); termDisplay(); return false; } #endif PFNGLXCREATECONTEXTATTRIBSARBPROC fnCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte*) "glXCreateContextAttribsARB"); PFNGLGETSTRINGIPROC fnGetStringi = (PFNGLGETSTRINGIPROC)glXGetProcAddress((const GLubyte*) "glGetStringi"); if (fnCreateContextAttribsARB == NULL || fnGetStringi == NULL) { mgDebug("Could not locate OpenGL functions"); termDisplay(); return false; } platform->m_glrc = (*fnCreateContextAttribsARB) (platform->m_display, platform->m_bestFbc, NULL, true, GL33_CREATE_ATTRIBUTES); if (platform->m_glrc == NULL) { mgDebug("glXCreateContextAttribsARB 3.3 returns NULL. Trying 3.2"); platform->m_glrc = (*fnCreateContextAttribsARB) (platform->m_display, platform->m_bestFbc, NULL, true, GL32_CREATE_ATTRIBUTES); if (platform->m_glrc == NULL) { mgDebug("glXCreateContextAttribsARB 3.2 returns NULL. I give up."); termDisplay(); return false; } } glXMakeCurrent(platform->m_display, platform->m_window, platform->m_glrc); m_depthBits = 16; // default glXGetConfig(platform->m_display, platform->m_vi, GLX_DEPTH_SIZE, &m_depthBits); mgDebug("%d depth bits", m_depthBits); // build an extension list for glew with glGetStringi mgString extList; int i = 0; for (; ; i++) { const GLubyte* ext = (*fnGetStringi)(GL_EXTENSIONS, i); if (ext == NULL) break; extList += (const char*) ext; extList += " "; } mgDebug("glGetStringi returns %d extensions", i); checkError(); // clear error from requesting last extension // save extensions list for glew glExtensions = (GLubyte*) new char[1+extList.length()]; strcpy((char*) glExtensions, (const char*) extList); GLenum err = glewInit(); if (err != GLEW_OK) { mgDebug("Cannot initialize OpenGL - glewInit failed."); termDisplay(); return false; } // accept OpenGL 3.2, but need #version 330 shader mgString errorMsg; if (!checkVersion(302, 303, errorMsg)) { mgDebug("%s", (const char*) errorMsg); termDisplay(); return false; } if (m_swapImmediate) { PFNGLXSWAPINTERVALMESAPROC fnSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalMESA"); if (fnSwapIntervalMESA != NULL) (*fnSwapIntervalMESA) (0); else { PFNGLXSWAPINTERVALSGIPROC fnSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalSGI"); if (fnSwapIntervalSGI != NULL) (*fnSwapIntervalSGI) (0); else mgDebug("Cannot find glXSwapInterval"); } } if (m_multiSample) glEnable(GL_MULTISAMPLE); // compile the overlay shader mgDebug("compile overlay shader:"); const char* attrNames[] = {"vertPoint", "vertTexCoord0"}; const DWORD attrIndexes[] = {0, 1}; m_overlayShader = compileShaderPair(GL33_OVERLAY_VERTEX_SHADER, GL33_OVERLAY_FRAGMENT_SHADER, 2, attrNames, attrIndexes); if (m_overlayShader == 0) { mgDebug("Cannot compile overlay shader."); termDisplay(); return false; } const char* vendor = (const char*) glGetString(GL_VENDOR); if (vendor != NULL) mgDebug(":OpenGL device vendor: %s", (const char*) vendor); const char* renderer = (const char*) glGetString(GL_RENDERER); if (renderer != NULL) mgDebug(":OpenGL device renderer: %s", (const char*) renderer); const char* versionStr = (const char*) glGetString(GL_VERSION); if (versionStr != NULL) mgDebug(":OpenGL version: %s", (const char*) versionStr); const char* shaderVersionStr = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION); if (shaderVersionStr != NULL) mgDebug(":OpenGL shader version: %s", (const char*) shaderVersionStr); // report all the GL limits GLint value; #define GLREPORT(sym) value = INT_MAX; glGetIntegerv(sym, &value); if (value != INT_MAX) mgDebug(":%s: %d", #sym, value); GLREPORT(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS); GLREPORT(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS); GLREPORT(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS); GLREPORT(GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS); GLREPORT(GL_MAX_VARYING_COMPONENTS); GLREPORT(GL_MAX_COMBINED_UNIFORM_BLOCKS); GLREPORT(GL_MAX_CUBE_MAP_TEXTURE_SIZE); GLREPORT(GL_MAX_DRAW_BUFFERS); GLREPORT(GL_MAX_ELEMENTS_INDICES); GLREPORT(GL_MAX_ELEMENTS_VERTICES); GLREPORT(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS); GLREPORT(GL_MAX_FRAGMENT_UNIFORM_BLOCKS); GLREPORT(GL_MAX_FRAGMENT_INPUT_COMPONENTS); GLREPORT(GL_MIN_PROGRAM_TEXEL_OFFSET); GLREPORT(GL_MAX_PROGRAM_TEXEL_OFFSET); GLREPORT(GL_MAX_RECTANGLE_TEXTURE_SIZE); GLREPORT(GL_MAX_TEXTURE_IMAGE_UNITS); GLREPORT(GL_MAX_TEXTURE_LOD_BIAS); GLREPORT(GL_MAX_TEXTURE_SIZE); GLREPORT(GL_MAX_RENDERBUFFER_SIZE); GLREPORT(GL_MAX_ARRAY_TEXTURE_LAYERS); GLREPORT(GL_MAX_TEXTURE_BUFFER_SIZE); GLREPORT(GL_MAX_UNIFORM_BLOCK_SIZE); GLREPORT(GL_MAX_VARYING_FLOATS); GLREPORT(GL_MAX_VERTEX_ATTRIBS); GLREPORT(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); GLREPORT(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS); GLREPORT(GL_MAX_VERTEX_UNIFORM_COMPONENTS); GLREPORT(GL_MAX_VERTEX_OUTPUT_COMPONENTS); GLREPORT(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS); GLREPORT(GL_MAX_SAMPLE_MASK_WORDS); GLREPORT(GL_MAX_COLOR_TEXTURE_SAMPLES); GLREPORT(GL_MAX_DEPTH_TEXTURE_SAMPLES); GLREPORT(GL_MAX_DEPTH_TEXTURE_SAMPLES); GLREPORT(GL_MAX_INTEGER_SAMPLES); GLREPORT(GL_MAX_UNIFORM_BUFFER_BINDINGS); GLREPORT(GL_MAX_UNIFORM_BLOCK_SIZE); GLREPORT(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT); GLREPORT(GL_MAX_VERTEX_UNIFORM_BLOCKS); GLREPORT(GL_MAX_GEOMETRY_UNIFORM_BLOCKS); GLREPORT(GL_MAX_GEOMETRY_INPUT_COMPONENTS); GLREPORT(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS); #undef GLREPORT return true; }
//-------------------------------------------------------------- // initialize graphics BOOL mgWinGL21Support::initDisplay() { mgDebug("------ try to create OpenGL 2.1 context, fullscreen=%s, multiSample=%s", m_fullscreen?"true":"false", m_multiSample?"true":"false"); mgGLInit(); // save the GL_EXTENSIONS from the base driver as backup const GLubyte* defaultExtensions = glGetString(GL_EXTENSIONS); PFNWGLCHOOSEPIXELFORMATARBPROC fnChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); PFNWGLCREATECONTEXTATTRIBSARBPROC fnCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); PFNGLGETSTRINGIPROC fnGetStringi = (PFNGLGETSTRINGIPROC)wglGetProcAddress("glGetStringi"); PFNWGLGETPIXELFORMATATTRIBIVARBPROC fnGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) wglGetProcAddress("wglGetPixelFormatAttribivARB"); if (fnChoosePixelFormatARB == NULL || fnCreateContextAttribsARB == NULL || fnGetStringi == NULL) { mgDebug("GLCreate unable to locate OpenGL methods"); termDisplay(); return false; } int* formatAttribs; if (m_multiSample) formatAttribs = GL21_MULTISAMPLE_ATTRIBUTES; else formatAttribs = GL21_DEFAULT_ATTRIBUTES; float floatFormatAttribs[] = { 0.0f }; int formats[1]; UINT formatCount; (*fnChoosePixelFormatARB) (m_dc, formatAttribs, floatFormatAttribs, 1, formats, &formatCount); if (formatCount < 1) { // fall back to default, not multisample (*fnChoosePixelFormatARB) (m_dc, GL21_DEFAULT_ATTRIBUTES, floatFormatAttribs, 1, formats, &formatCount); if (formatCount < 1) { mgDebug("OpenGL: No available pixel formats"); termDisplay(); return false; } } if (fnGetPixelFormatAttribivARB != NULL) { // HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues int attribs[] = {WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB, WGL_BLUE_BITS_ARB, WGL_ALPHA_BITS_ARB, WGL_DEPTH_BITS_ARB, WGL_SAMPLES_ARB}; int values[6]; (*fnGetPixelFormatAttribivARB) (m_dc, formats[0], 0, 6, attribs, values); mgDebug("wglGetPixelFormatARB = R%dG%dB%dA%d, %d depth, %d multisample", values[0], values[1], values[2], values[3], values[4], values[5]); } PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(pfd)); m_pixelFormat = formats[0]; SetPixelFormat(m_dc, m_pixelFormat, &pfd); DescribePixelFormat(m_dc, m_pixelFormat, sizeof(pfd), &pfd); m_depthBits = 16; // assumed, since that's what we requested if (pfd.cDepthBits != 0) m_depthBits = pfd.cDepthBits; m_glrc = (*fnCreateContextAttribsARB)(m_dc, NULL, GL21_CREATE_ATTRIBUTES); if (m_glrc == NULL) { mgDebug("OpenGL wglCreateContextAttribsARB returns NUL"); termDisplay(); return false; } if (!wglMakeCurrent(m_dc, m_glrc)) { mgDebug("OpenGL: cannot make rc current."); termDisplay(); return false; } // get the extension list again now that we have chosen driver const GLubyte* extensions = glGetString(GL_EXTENSIONS); // if no extensions, try building them with glGetStringi if (extensions == NULL) { mgDebug("glGetString(GL_EXTENSIONS) returns NULL"); int listAlloc = 80; int listLen = 0; char* extList = new char[listAlloc]; int i = 0; for (; ; i++) { const GLubyte* ext = (*fnGetStringi)(GL_EXTENSIONS, i); if (ext == NULL) break; int extLen = strlen((const char*) ext); // reallocate the list if we need more room if (listLen + extLen+1 > listAlloc) { listAlloc = listAlloc + extLen + 512; char* newList = new char[listAlloc]; memcpy(newList, extList, listLen); delete extList; extList = newList; } strcpy(extList+listLen, (const char*) ext); listLen += extLen; extList[listLen++] = ' '; } extList[listLen] = '\0'; mgDebug("glGetStringi returns %d extensions", i); // if there were no individual extensions, use default list if (listLen != 0) glExtensions = (GLubyte*) extList; else glExtensions = (GLubyte*) defaultExtensions; } GLenum err = glewInit(); if (err != GLEW_OK) { mgDebug("Cannot initialize OpenGL - glewInit failed."); termDisplay(); return false; } mgString errorMsg; if (!checkVersion(201, 102, errorMsg)) { mgDebug("%s", (const char*) errorMsg); termDisplay(); return false; } if (m_multiSample) glEnable(GL_MULTISAMPLE); if (m_swapImmediate) wglSwapIntervalEXT(0); // compile the overlay shader mgDebug("compile overlay shader:"); const char* attrNames[] = {"vertPoint", "vertTexCoord0"}; const DWORD attrIndexes[] = {0, 1}; m_overlayShader = compileShaderPair(GL21_OVERLAY_VERTEX_SHADER, GL21_OVERLAY_FRAGMENT_SHADER, 2, attrNames, attrIndexes); return true; }
//-------------------------------------------------------------- // initialize graphics BOOL mgLinuxGL21Support::initDisplay() { mgDebug("------ try to create OpenGL 2.1 context, fullscreen=%s, multiSample=%s", m_fullscreen?"true":"false", m_multiSample?"true":"false"); mgLinuxServices* system = (mgLinuxServices*) mgPlatform; // =-= some drivers are failing this test. not clear we need it #ifdef WORKED int glxMajor, glxMinor; glXQueryVersion(system->m_display, &glxMajor, &glxMinor); mgDebug("GLX version = %d.%d", glxMajor, glxMinor); int glxVersion = glxMajor * 100 + glxMinor; if (glxVersion < 103) { mgDebug("GLX version < 1.3"); termDisplay(); return false; } #endif system->m_glrc = glXCreateContext(system->m_display, system->m_vi, NULL, true); if (system->m_glrc == NULL) { mgDebug("Could not glXCreateContext"); termDisplay(); return false; } glXMakeCurrent(system->m_display, system->m_window, system->m_glrc); m_depthBits = 16; // default glXGetConfig(system->m_display, system->m_vi, GLX_DEPTH_SIZE, &m_depthBits); mgDebug("%d depth bits", m_depthBits); // get the extension list again now that we have chosen driver GLenum err = glewInit(); if (err != GLEW_OK) { mgDebug("Cannot initialize OpenGL - glewInit failed."); termDisplay(); return false; } mgString errorMsg; if (!checkVersion(201, 102, errorMsg)) { mgDebug("%s", (const char*) errorMsg); termDisplay(); return false; } if (m_swapImmediate) { PFNGLXSWAPINTERVALMESAPROC fnSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalMESA"); if (fnSwapIntervalMESA != NULL) (*fnSwapIntervalMESA) (0); else { PFNGLXSWAPINTERVALSGIPROC fnSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalSGI"); if (fnSwapIntervalSGI != NULL) (*fnSwapIntervalSGI) (0); else mgDebug("Cannot find glXSwapInterval"); } } if (system->getMultiSample()) glEnable(GL_MULTISAMPLE); // compile the overlay shader mgDebug("compile overlay shader:"); const char* attrNames[] = {"vertPoint", "vertTexCoord0"}; const DWORD attrIndexes[] = {0, 1}; m_overlayShader = compileShaderPair(GL21_OVERLAY_VERTEX_SHADER, GL21_OVERLAY_FRAGMENT_SHADER, 2, attrNames, attrIndexes); return true; }