Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
	}