static int32_t texcache_loadmips(const texcacheheader *head, GLenum *glerr, int32_t *xsiz, int32_t *ysiz) { int32_t level; texcachepicture pict; char *pic = NULL, *packbuf = NULL; void *midbuf = NULL; int32_t alloclen=0; for (level = 0; level==0 || (pict.xdim > 1 || pict.ydim > 1); level++) { GLint format; if (texcache_readdata(&pict, sizeof(texcachepicture))) { TEXCACHE_FREEBUFS(); return TEXCACHERR_BUFFERUNDERRUN; } // external (little endian) -> native pict.size = B_LITTLE32(pict.size); pict.format = B_LITTLE32(pict.format); pict.xdim = B_LITTLE32(pict.xdim); pict.ydim = B_LITTLE32(pict.ydim); pict.border = B_LITTLE32(pict.border); pict.depth = B_LITTLE32(pict.depth); if (level == 0) { if (xsiz) *xsiz = pict.xdim; if (ysiz) *ysiz = pict.ydim; } if (alloclen < pict.size) { pic = (char *)Xrealloc(pic, pict.size); alloclen = pict.size; packbuf = (char *)Xrealloc(packbuf, alloclen+16); midbuf = (void *)Xrealloc(midbuf, pict.size); } if (dedxtfilter(texcache.filehandle, &pict, pic, midbuf, packbuf, (head->flags & CACHEAD_COMPRESSED)!=0)) { TEXCACHE_FREEBUFS(); return TEXCACHERR_DEDXT; } bglCompressedTexImage2DARB(GL_TEXTURE_2D,level,pict.format,pict.xdim,pict.ydim,pict.border,pict.size,pic); if ((*glerr=bglGetError()) != GL_NO_ERROR) { TEXCACHE_FREEBUFS(); return TEXCACHERR_COMPTEX; } bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_INTERNAL_FORMAT, &format); if ((*glerr = bglGetError()) != GL_NO_ERROR) { TEXCACHE_FREEBUFS(); return TEXCACHERR_GETTEXLEVEL; } if (pict.format != format) { OSD_Printf("gloadtile_cached: invalid texture cache file format %d %d\n", pict.format, format); TEXCACHE_FREEBUFS(); return -1; } } TEXCACHE_FREEBUFS(); return 0; }
BD_UINT32 LinuxWindow::Create( const BD_UINT32 p_Width, const BD_UINT32 p_Height, const BD_BOOL p_Fullscreen ) { m_pDisplay = XOpenDisplay( 0 ); if( !m_pDisplay ) { bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <ERROR> " "Failed to open X display\n" ); return BD_ERROR; } m_Fullscreen = p_Fullscreen; // HARDCODED! BD_SINT32 GLXAttribs[ ] = { GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, GLX_DOUBLEBUFFER, True, None }; // !HARDCODED // For now, we will only care about GLX 1.3 BD_SINT32 Major = 0, Minor = 0; if( !glXQueryVersion( m_pDisplay, &Major, &Minor ) || ( ( Major == 1 ) && ( Minor < 3 ) ) || ( Major < 1 ) ) { bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <ERROR> " "GLX Version not 1.3 or greater\n" ); return BD_ERROR; } bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> " "Attempting to retrieve framebuffer configurations\n" ); BD_SINT32 FBCount = 0; GLXFBConfig *pFBC = glXChooseFBConfig( m_pDisplay, DefaultScreen( m_pDisplay ), GLXAttribs, &FBCount ); if( !pFBC ) { bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <ERROR> " "Failed to create a GLXFBConfig\n" ); return BD_ERROR; } bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> " "Found %d matching framebuffer configurations\n", FBCount ); GLXFBConfig FBC = pFBC[ 0 ]; m_pXVI = glXGetVisualFromFBConfig( m_pDisplay, FBC ); XFree( pFBC ); bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> " "Visual ID in use: 0x%08X\n", m_pXVI->visualid ); XSetWindowAttributes WinAttribs; Colormap ColourMap = XCreateColormap( m_pDisplay, RootWindow( m_pDisplay, m_pXVI->screen ), m_pXVI->visual, AllocNone ); WinAttribs.colormap = ColourMap; WinAttribs.background_pixmap = None; WinAttribs.border_pixel = 0; WinAttribs.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; Screen *pScreen = DefaultScreenOfDisplay( m_pDisplay ); if( m_Fullscreen == BD_TRUE ) { m_Width = WidthOfScreen( pScreen ); m_Height = HeightOfScreen( pScreen ); } else { m_Width = p_Width; m_Height = p_Height; } BD::GLWSExtBind( m_pDisplay, m_pXVI->screen ); m_Window = XCreateWindow( m_pDisplay, RootWindow( m_pDisplay, m_pXVI->screen ), 0, 0, m_Width, m_Height, 0, m_pXVI->depth, InputOutput, m_pXVI->visual, CWEventMask | CWColormap | CWBorderPixel, &WinAttribs ); if( !m_Window ) { bdTrace( BD_NULL, "[BD::LinuxWindow::CreateWindow] <INFO> " "Failed to create window\n" ); return BD_ERROR; } bdTrace( BD_NULL, "[BD::LinuxWindow::CreateWindow] <INFO> " "m_Window: 0x%08X | Width: %d | Height %d | Fullscreen: %s\n", m_Window, m_Width, m_Height, ( m_Fullscreen ? "True" : "False" ) ); XMapWindow( m_pDisplay, m_Window ); XMapRaised( m_pDisplay, m_Window ); XStoreName( m_pDisplay, m_Window, "BrainDead" ); XMoveWindow( m_pDisplay, m_Window, 0, 0 ); XRaiseWindow( m_pDisplay, m_Window ); XSync( m_pDisplay, False ); // Install an X error handler so the application won't exit if // GL 3.0+ context allocation fails g_sContextError = BD_FALSE; int ( *pOldHandler )( Display *, XErrorEvent * ) = XSetErrorHandler( &ContextErrorHandler ); if( !bglwsCreateContextAttribsARB ) { // Create a GLX 1.3 context for GL <2.1 bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> " "Creating a GLX 1.3 context\n" ); m_GLXContext = glXCreateNewContext( m_pDisplay, FBC, GLX_RGBA_TYPE, 0, True ); } else { BD_SINT32 GLVersions [ ] = { 4, 3, 4, 2, 4, 1, 4, 0, 3, 3, 3, 2, 3, 1, 3, 0, 2, 1, 2, 0, 1, 5, 1, 4, 1, 3, 1, 2, 1, 1, 1, 0 }; int ContextAttribs [ ] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 0, GLX_CONTEXT_MINOR_VERSION_ARB, 0, #ifdef BUILD_DEBUG GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, #endif // Add forward-compatible and debug if debug None }; for( BD_MEMSIZE i = 0; i < ( sizeof( GLVersions ) / sizeof( BD_SINT32 ) / 2 ); ++i ) { bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> " "Attempting to create a GLX context for OpenGL " "%ld.%ld... ", GLVersions[ i*2 ], GLVersions[ i*2+1 ] ); ContextAttribs[ 1 ] = GLVersions[ i*2 ]; ContextAttribs[ 3 ] = GLVersions[ i*2+1 ]; m_GLXContext = bglwsCreateContextAttribsARB( m_pDisplay, FBC, 0, True, ContextAttribs ); XSync( m_pDisplay, False ); if( !g_sContextError && m_GLXContext ) { bdTrace( BD_NULL, "[ OK ]\n" ); break; } g_sContextError = BD_FALSE; bdTrace( BD_NULL, "\n" ); } } // Sync to make sure any errors are processed XSync( m_pDisplay, False ); // Restore the original error handler XSetErrorHandler( pOldHandler ); if( g_sContextError || !m_GLXContext ) { bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <ERROR> " "Failed to create an OpenGL context\n" ); return BD_ERROR; } if( !glXIsDirect( m_pDisplay, m_GLXContext ) ) { bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <WARN> " "Indirect GLX rendering context\n" ); } else { bdTrace( BD_NULL, "[BD::LinuxWindow::Create] <INFO> " "Direct GLX rendering context\n" ); } glXMakeCurrent( m_pDisplay, m_Window, m_GLXContext ); // Get the version information to initialise the GL Extensions GLint GLMajor = 0, GLMinor = 0; // Attempt to get the major and minor using the GL 3.0+ method bglGetIntegerv( GL_MAJOR_VERSION, &GLMajor ); bglGetIntegerv( GL_MINOR_VERSION, &GLMinor ); // The GL_*_VERSION parameters are not recognised GLenum GLErr = bglGetError( ); if( GLErr == GL_INVALID_ENUM ) { // Resort to using the <GL 3.0 method const char *pGLVersion = ( const char * )glGetString( GL_VERSION ); // The first number up to the first period /should/ be the major BD_MEMSIZE Separator = 0; BD_MEMSIZE StrCount = 0; BD_MEMSIZE StrLoc = 0; GLMajor = 0; GLMinor = 0; char *pNum = BD_NULL; for( BD_MEMSIZE i = 0; i < strlen( pGLVersion ); ++i ) { char c = pGLVersion[ i ]; if( c == '.' ) { pNum = new char[ StrCount+1 ]; strncpy( pNum, pGLVersion+StrLoc, StrCount ); pNum[ StrCount ] = '\0'; StrLoc = StrCount+1; StrCount = 0; // Skip the '.' ++i; if( GLMajor != 0 ) { GLMinor = atoi( pNum ); break; } if( GLMajor == 0 ) { GLMajor = atoi( pNum ); } } StrCount++; } delete [ ] pNum; } if( BD::GLExtBind( GLMajor, GLMinor ) != BD_OK ) { bdTrace( BD_NULL, "[BD::LinuxRenderer::Create] <ERROR> " "Failed to bind OpenGL %d.%d extensions\n", GLMajor, GLMinor ); bdTrace( BD_NULL, "[ FAIL ]\n" ); return BD_ERROR; } bdTrace( BD_NULL, "[BD::LinuxRenderer::Create] <INFO> " "Bound OpenGL %d.%d extensions\n", GLMajor, GLMinor ); bglViewport( 0, 0, m_Width, m_Height ); return BD_OK; }