Пример #1
0
result CMuli3DRenderTarget::SetDepthBuffer( CMuli3DSurface *i_pDepthBuffer )
{
    if( i_pDepthBuffer )
    {
        if( i_pDepthBuffer->fmtGetFormat() != m3dfmt_r32f )
        {
            FUNC_FAILING( "CMuli3DRenderTarget::SetDepthBuffer: invalid texture format.\n" );
            return e_invalidformat;
        }

        if( m_pColorBuffer )
        {
            if( i_pDepthBuffer->iGetWidth() != m_pColorBuffer->iGetWidth() ||
                    i_pDepthBuffer->iGetHeight() != m_pColorBuffer->iGetHeight() )
            {
                FUNC_FAILING( "CMuli3DDevice::SetDepthBuffer: depthbuffer and framebuffer dimensions are not equal.\n" );
                return e_invalidformat;
            }
        }
    }

    SAFE_RELEASE( m_pDepthBuffer );
    m_pDepthBuffer = i_pDepthBuffer;
    if( m_pDepthBuffer ) m_pDepthBuffer->AddRef();
    return s_ok;
}
result CMuli3DVolumeTexture::Create( uint32 i_iWidth, uint32 i_iHeight, uint32 i_iDepth, uint32 i_iMipLevels, m3dformat i_fmtFormat )
{
	if( !i_iWidth || !i_iHeight || !i_iDepth )
	{
		FUNC_FAILING( "CMuli3DVolumeTexture::Create: texture dimensions are invalid.\n" );
		return e_invalidparameters;
	}
	
	if( i_fmtFormat < m3dfmt_r32f || i_fmtFormat > m3dfmt_r32g32b32a32f )
	{
		FUNC_FAILING( "CMuli3DVolumeTexture::Create: invalid format specified.\n" );
		return e_invalidformat;
	}

	m_fSquaredWidth = (float32)(i_iWidth * i_iWidth);
	m_fSquaredHeight = (float32)(i_iHeight * i_iHeight);
	m_fSquaredDepth = (float32)(i_iDepth * i_iDepth);

	if( !i_iMipLevels )
	{
		// Create a full chain ...
		uint32 iWidth = i_iWidth, iHeight = i_iHeight, iDepth = i_iDepth;
		do
		{
			++i_iMipLevels;
			iWidth >>= 1; iHeight >>= 1; iDepth >>= 1;
		}
		while( iWidth && iHeight && iDepth );
	}
Пример #3
0
result CMuli3DPresentTargetAmigaOS4::Create()
{
	m3ddeviceparameters DeviceParameters = m_pParent->GetDeviceParameters();

	if( !DeviceParameters.iBackbufferWidth || !DeviceParameters.iBackbufferHeight )
	{
		FUNC_FAILING( "CMuli3DPresentTargetAmigaOS4::Create: invalid backbuffer dimensions have been supplied.\n" );
		return e_invalidparameters;
	}

	// Allocate buffer:
	if ( !( m_pBitMap = IP96->p96AllocBitMap(
		DeviceParameters.iBackbufferWidth,
		DeviceParameters.iBackbufferHeight,
		24,
		BMF_CLEAR|BMF_DISPLAYABLE,
		0,
		RGBFB_R8G8B8 ) ) )
	{
		FUNC_FAILING( "CMuli3dPresentTargetAmigaOS4::Create: couldn't allocate bitmap.\n");
		return e_unknown;
	}

	return s_ok;
}
Пример #4
0
result CMuli3DIndexBuffer::GetVertexIndex( uint32 i_iArrayIndex, uint32 &o_iValue )
{
	switch( m_fmtFormat )
	{
	case m3dfmt_index16:
		{
			if( i_iArrayIndex >= m_iLength / 2 )
			{
				FUNC_FAILING( "CMuli3DIndexBuffer::GetVertexIndex: parameter i_iArrayIndex exceeds vertex buffer size.\n" );
				return e_invalidparameters;
			}

			const uint16 *pData = (const uint16 *)m_pData;
			o_iValue = pData[i_iArrayIndex];
			return s_ok;
		}
	case m3dfmt_index32:
		{
			if( i_iArrayIndex >= m_iLength / 4 )
			{
				FUNC_FAILING( "CMuli3DIndexBuffer::GetVertexIndex: parameter i_iArrayIndex exceeds vertex buffer size.\n" );
				return e_invalidparameters;
			}

			const uint32 *pData = (const uint32 *)m_pData;
			o_iValue = pData[i_iArrayIndex];
			return s_ok;
		}
	default:
		// cannot happen
		FUNC_FAILING( "CMuli3DIndexBuffer::GetVertexIndex: invalid format.\n" );
		return e_invalidformat;
	}
}
Пример #5
0
result CMuli3DIndexBuffer::Create( uint32 i_iLength, m3dformat i_fmtFormat )
{
	if( !i_iLength )
	{
		FUNC_FAILING( "CMuli3DIndexBuffer::Create: parameter i_iLength is 0.\n" );
		return e_invalidparameters;
	}

	if( i_fmtFormat != m3dfmt_index16 && i_fmtFormat != m3dfmt_index32 )
	{
		FUNC_FAILING( "CMuli3DIndexBuffer::Create: invalid format specified.\n" );
		return e_invalidformat;
	}

	m_iLength = i_iLength;
	m_fmtFormat = i_fmtFormat;

	m_pData = new byte[i_iLength];
	if( !m_pData )
	{
		FUNC_FAILING( "CMuli3DIndexBuffer::Create: out of memory, cannot create index buffer.\n" );
		return e_outofmemory;
	}

	return s_ok;
}
Пример #6
0
result CMuli3DIndexBuffer::GetPointer( uint32 i_iOffset, void **o_ppData )
{
	if( !o_ppData )
	{
		FUNC_FAILING( "CMuli3DIndexBuffer::GetPointer: parameter o_ppData points to null.\n" );
		return e_invalidparameters;
	}

	if( i_iOffset >= m_iLength )
	{
		*o_ppData = 0;
		FUNC_FAILING( "CMuli3DIndexBuffer::GetPointer: i_iOffset is larger than index buffer length.\n" );
		return e_invalidparameters;
	}

	*o_ppData = &m_pData[i_iOffset];
	return s_ok;
}
Пример #7
0
result CMuli3DRenderTarget::ClearDepthBuffer( float32 i_fDepth, const m3drect *i_pRect )
{
    if( !m_pDepthBuffer )
    {
        FUNC_FAILING( "CMuli3DRenderTarget::ClearDepthBuffer: no depthbuffer has been set.\n" );
        return e_invalidstate;
    }

    return m_pDepthBuffer->Clear( vector4( i_fDepth, 0, 0, 0 ), i_pRect );
}
Пример #8
0
result CMuli3DRenderTarget::ClearColorBuffer( const vector4 &i_vColor, const m3drect *i_pRect )
{
    if( !m_pColorBuffer )
    {
        FUNC_FAILING( "CMuli3DRenderTarget::ClearColorBuffer: no framebuffer has been set.\n" );
        return e_invalidstate;
    }

    return m_pColorBuffer->Clear( i_vColor, i_pRect );
}
Пример #9
0
result CMuli3DPresentTargetWin32::Create()
{
	m3ddeviceparameters DeviceParameters = m_pParent->GetDeviceParameters();

	if( !DeviceParameters.iBackbufferWidth || !DeviceParameters.iBackbufferHeight )
	{
		FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: invalid backbuffer dimensions have been supplied.\n" );
		return e_invalidparameters;
	}

	if( FAILED( DirectDrawCreateEx( 0, (void **)&m_pDirectDraw, IID_IDirectDraw7, 0 ) ) )
	{
		FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: couldn't create DirectDraw 7 instance.\n" );
		return e_unknown;
	}

	uint32 iDDFlags = DeviceParameters.bWindowed ? DDSCL_NORMAL : DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN|DDSCL_ALLOWREBOOT;
    if( FAILED( m_pDirectDraw->SetCooperativeLevel( DeviceParameters.hDeviceWindow, iDDFlags ) ) )
	{
		FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: couldn't set cooperative level.\n" );
		return e_unknown;
	}

	if( !DeviceParameters.bWindowed )
	{
		switch( DeviceParameters.iFullscreenColorBits )
		{
		case 16:
		case 24:
		case 32:
			break;

		default:
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: invalid backbuffer bit-depth specified.\n" );
			return e_unknown;
		}

		// Go to fullscreen mode
		if( FAILED( m_pDirectDraw->SetDisplayMode( DeviceParameters.iBackbufferWidth, DeviceParameters.iBackbufferHeight, DeviceParameters.iFullscreenColorBits, 0, 0 ) ) )
		{
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: couldn't set display mode.\n" );
			return e_unknown;
		}
	}
	else
	{
		// Determine display mode.
		DDSURFACEDESC2 descSurface;
		descSurface.dwSize = sizeof( descSurface );
		if( FAILED( m_pDirectDraw->GetDisplayMode( &descSurface ) ) )
		{
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: couldn't get display mode.\n" );
			return e_unknown;
		}

		switch( descSurface.ddpfPixelFormat.dwRGBBitCount )
		{
		case 16: // also handles formats 555(15-bit) and 444(12-bit)
			{
				uint16 iNumRedBits, iNumGreenBits, iNumBlueBits;
				ProcessBits( descSurface.ddpfPixelFormat.dwRBitMask, m_i16bitShift[0], iNumRedBits );
				ProcessBits( descSurface.ddpfPixelFormat.dwGBitMask, m_i16bitShift[1], iNumGreenBits );
				ProcessBits( descSurface.ddpfPixelFormat.dwBBitMask, m_i16bitShift[2], iNumBlueBits );

				m_i16bitMaxVal[0] = (uint16)(( 1 << iNumRedBits ) - 1);
				m_i16bitMaxVal[1] = (uint16)(( 1 << iNumGreenBits ) - 1);
				m_i16bitMaxVal[2] = (uint16)(( 1 << iNumBlueBits ) - 1);
			}
			break;

		case 24:
		case 32:
			break;

		default:
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: display modes with colors other than 16-, 24- or 32-bit are not supported!\n" );
			return e_unknown;
		}
	}

	if( DeviceParameters.bWindowed )
	{
		// Create a primary surface without a backbuffer - a secondary surface will be used as backbuffer.
		DDSURFACEDESC2 descSurface;
		ZeroMemory( &descSurface, sizeof( descSurface ) );
		descSurface.dwSize = sizeof( descSurface );
		descSurface.dwFlags = DDSD_CAPS;
		descSurface.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
		if( FAILED( m_pDirectDraw->CreateSurface( &descSurface, &m_pDirectDrawSurfaces[0], 0 ) ) )
		{
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: couldn't create primary surface.\n" );
			return e_unknown;
		}

		// Create the secondary surface
		descSurface.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
		descSurface.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
		descSurface.dwWidth = DeviceParameters.iBackbufferWidth;
		descSurface.dwHeight = DeviceParameters.iBackbufferHeight;
		if( FAILED( m_pDirectDraw->CreateSurface( &descSurface, &m_pDirectDrawSurfaces[1], 0 ) ) )
		{
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: couldn't create secondary surface.\n" );
			return e_unknown;
		}

		// Create clipper
		if( FAILED( m_pDirectDraw->CreateClipper( 0, &m_pDirectDrawClipper, 0 ) ) )
		{
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: couldn't create clipper.\n" );
			return e_unknown;
		}

		// Set clipper to window
		if( FAILED( m_pDirectDrawClipper->SetHWnd( 0, DeviceParameters.hDeviceWindow ) ) )
		{
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: couldn't set clipper window handle.\n" );
			return e_unknown;
		}

		// Attach clipper object to primary surface
		if( FAILED( m_pDirectDrawSurfaces[0]->SetClipper( m_pDirectDrawClipper ) ) )
		{
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: couldn't attach clipper to primary surface.\n" );
			return e_unknown;
		}
	}
	else
	{
		// Create a primary surface with one backbuffer if in fullscreen mode.
		DDSURFACEDESC2 descSurface;
		ZeroMemory( &descSurface, sizeof( descSurface ) );
		descSurface.dwSize = sizeof( descSurface );
		descSurface.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
		descSurface.dwBackBufferCount = 1;
		descSurface.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP;
		if( FAILED( m_pDirectDraw->CreateSurface( &descSurface, &m_pDirectDrawSurfaces[0], 0 ) ) )
		{
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: couldn't create primary surface.\n" );
			return e_unknown;
		}

		// Get DD backbuffer
		DDSCAPS2 capsDirectDraw = { DDSCAPS_BACKBUFFER };
		if( FAILED( m_pDirectDrawSurfaces[0]->GetAttachedSurface( &capsDirectDraw, &m_pDirectDrawSurfaces[1] ) ) )
		{
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Create: couldn't access secondary surface.\n" );
			return e_unknown;
		}
	}

	return s_ok;
}
Пример #10
0
result CMuli3DPresentTargetLinuxX11::Create()
{
	m3ddeviceparameters DeviceParameters = m_pParent->GetDeviceParameters();

	if( !DeviceParameters.iBackbufferWidth || !DeviceParameters.iBackbufferHeight )
	{
		FUNC_FAILING( "CMuli3DPresentTargetLinuxX11::Create: invalid backbuffer dimensions have been supplied.\n" );
		return e_invalidparameters;
	}

	m_pDisplay = XOpenDisplay( 0 );
	if( !m_pDisplay )
	{
		FUNC_FAILING( "CMuli3DPresentTargetLinuxX11::Create: couldn't open X-display.\n" );
		return e_unknown;
	}

	const int32 iScreen = DefaultScreen( m_pDisplay );
	const int32 iDepth = DefaultDepth( m_pDisplay, iScreen );

	m_iPixelBytes = 0;
	int32 iPixmapFormatCount = 0;
	XPixmapFormatValues *pPixmapFormats = XListPixmapFormats( m_pDisplay, &iPixmapFormatCount );
	for( int32 iPixmapFormat = 0; iPixmapFormat < iPixmapFormatCount && !m_iPixelBytes; ++iPixmapFormat )
    {
		if( pPixmapFormats[iPixmapFormat].depth == iDepth )
		{
			switch( pPixmapFormats[iPixmapFormat].bits_per_pixel )
			{
			case 12:
				m_iPixelBytes = 2;
				m_i16bitMaxVal[0] = 15; m_i16bitMaxVal[1] = 15; m_i16bitMaxVal[2] = 15;
				m_i16bitShift[0] = 8; m_i16bitShift[1] = 4; m_i16bitShift[2] = 0;
				break;

			case 15:
				m_iPixelBytes = 2;
				m_i16bitMaxVal[0] = 31; m_i16bitMaxVal[1] = 31; m_i16bitMaxVal[2] = 31;
				m_i16bitShift[0] = 10; m_i16bitShift[1] = 5; m_i16bitShift[2] = 0;
				break;

			case 16:
				m_iPixelBytes = 2;
				m_i16bitMaxVal[0] = 31; m_i16bitMaxVal[1] = 63; m_i16bitMaxVal[2] = 31;
				m_i16bitShift[0] = 11; m_i16bitShift[1] = 5; m_i16bitShift[2] = 0;
				break;

			case 24: m_iPixelBytes = 3; break;
			case 32: m_iPixelBytes = 4; break;
			default: break;
			}
		}
    }
	XFree( pPixmapFormats );

	if( !m_iPixelBytes )
	{
		XCloseDisplay( m_pDisplay ); m_pDisplay = 0;
		FUNC_FAILING( "CMuli3DPresentTargetLinuxX11::Create: invalid pixel-depth! Make sure you're running in 16-, 24- or 32bits color-mode.\n" );
		return e_unknown;
	}

	m_WindowGC = DefaultGC( m_pDisplay, iScreen );
	m_pXImage = XCreateImage( m_pDisplay, CopyFromParent, iDepth, ZPixmap, 0, 0,
		  DeviceParameters.iBackbufferWidth, DeviceParameters.iBackbufferHeight, 32,
		  DeviceParameters.iBackbufferWidth * m_iPixelBytes );

	if( !m_pXImage )
	{
		FUNC_FAILING( "CMuli3DPresentTargetLinuxX11::Create: couldn't create X-image.\n" );
		XCloseDisplay( m_pDisplay ); m_pDisplay = 0;
		return e_unknown;
	}

	m_pXImage->data = new char[DeviceParameters.iBackbufferWidth * DeviceParameters.iBackbufferHeight * m_iPixelBytes];
	if( !m_pXImage->data )
	{
		XDestroyImage( m_pXImage ); m_pXImage = 0;
		XCloseDisplay( m_pDisplay ); m_pDisplay = 0;
		FUNC_FAILING( "CMuli3DPresentTargetLinuxX11::Create: couldn't allocate memory for backbuffer.\n" );
		return e_outofmemory;
	}

	return s_ok;
}
Пример #11
0
result CMuli3DPresentTargetWin32::Present( const float32 *i_pSource, uint32 i_iFloats )
{
	m3ddeviceparameters DeviceParameters = m_pParent->GetDeviceParameters();

	// Check for lost DirectDraw surfaces -------------------------------------
	if( m_bDDSurfaceLost )
	{
		m_pDirectDrawSurfaces[0]->Restore();
		if( DeviceParameters.bWindowed )
			m_pDirectDrawSurfaces[1]->Restore();
		m_bDDSurfaceLost = false;
	}

    // Lock backbuffer-surface-------------------------------------------------
	DDSURFACEDESC2 descSurface;
    descSurface.dwSize = sizeof( DDSURFACEDESC2 );
    if( FAILED( m_pDirectDrawSurfaces[1]->Lock( 0, &descSurface, DDLOCK_WAIT|DDLOCK_NOSYSLOCK|DDLOCK_WRITEONLY, 0 ) ) )
	{
		FUNC_FAILING( "CMuli3DPresentTargetWin32::Present: couldn't lock secondary surface.\n" );
		return e_unknown;
	}

	const uint32 iDestBytes = descSurface.ddpfPixelFormat.dwRGBBitCount / 8;

    // Copy pixels to the backbuffer-surface ----------------------------------
	const uint32 iDestRowJump = descSurface.lPitch - iDestBytes * DeviceParameters.iBackbufferWidth;
	uint8 *pDestination = (uint8 *)descSurface.lpSurface;

	fpuTruncate();

	if( iDestBytes == 2 )
	{
		// 16-bit
		uint32 iHeight = DeviceParameters.iBackbufferHeight;
		while( iHeight-- )
		{
			uint32 iWidth = DeviceParameters.iBackbufferWidth;
			while( iWidth-- )
			{
				const int32 iR = iClamp( ftol( i_pSource[0] * m_i16bitMaxVal[0] ), 0, m_i16bitMaxVal[0] );
				const int32 iG = iClamp( ftol( i_pSource[1] * m_i16bitMaxVal[1] ), 0, m_i16bitMaxVal[1] );
				const int32 iB = iClamp( ftol( i_pSource[2] * m_i16bitMaxVal[2] ), 0, m_i16bitMaxVal[2] );
				i_pSource += i_iFloats;

				*((uint16 *)pDestination) = ( iR << m_i16bitShift[0] ) | ( iG << m_i16bitShift[1] ) | ( iB << m_i16bitShift[2] );
				pDestination += 2;
			}
			pDestination += iDestRowJump;
		}
	}
	else
	{
		// 24- or 32-bit
		uint32 iHeight = DeviceParameters.iBackbufferHeight;
		while( iHeight-- )
		{
			uint32 iWidth = DeviceParameters.iBackbufferWidth;
			while( iWidth-- )
			{
				pDestination[0] = iClamp( ftol( i_pSource[2] * 255.0f ), 0, 255 ); // b
				pDestination[1] = iClamp( ftol( i_pSource[1] * 255.0f ), 0, 255 ); // g
				pDestination[2] = iClamp( ftol( i_pSource[0] * 255.0f ), 0, 255 ); // r

				i_pSource += i_iFloats;
				pDestination += iDestBytes;
			}
			pDestination += iDestRowJump;
		}
	}

	fpuReset();

    // Unlock backbuffer-surface and surface
    m_pDirectDrawSurfaces[1]->Unlock( 0 );

	// Present the image to the screen ----------------------------------------
	if( DeviceParameters.bWindowed )
	{
		POINT pntTopLeft = { 0, 0 };
        ClientToScreen( DeviceParameters.hDeviceWindow, &pntTopLeft );

		RECT rctDestination;
        GetClientRect( DeviceParameters.hDeviceWindow, &rctDestination );
		OffsetRect( &rctDestination, pntTopLeft.x, pntTopLeft.y );

		RECT rctSource;
		SetRect( &rctSource, 0, 0, DeviceParameters.iBackbufferWidth, DeviceParameters.iBackbufferHeight );

        // Blt secondary to primary surface
        if( FAILED( m_pDirectDrawSurfaces[0]->Blt( &rctDestination, m_pDirectDrawSurfaces[1], &rctSource, DDBLT_WAIT, 0 ) ) )
		{
			m_bDDSurfaceLost = true;
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Present: primary surfaces have been lost!\n" );
			return e_unknown;
		}
	}
	else
	{
		if( FAILED( m_pDirectDrawSurfaces[0]->Flip( 0, DDFLIP_WAIT ) ) )
		{
			m_bDDSurfaceLost = true;
			FUNC_FAILING( "CMuli3DPresentTargetWin32::Present: surfaces have been lost!\n" );
			return e_unknown;
		}
	}

	return s_ok;
}