Esempio n. 1
0
//-----------------------------------------------------------------------------
// Generate spheremap based on the current images (only works for cubemaps)
// The look dir indicates the direction of the center of the sphere
//-----------------------------------------------------------------------------
void CVTFTexture::GenerateSpheremap( LookDir_t lookDir )
{
	if (!IsCubeMap())
		return;

	Assert( m_Format == IMAGE_FORMAT_RGBA8888 );

	// We'll be doing our work in IMAGE_FORMAT_RGBA8888 mode 'cause it's easier
	unsigned char *pCubeMaps[6];

	// Allocate the bits for the spheremap
	int iMemRequired = ImageLoader::GetMemRequired( m_nWidth, m_nHeight, IMAGE_FORMAT_RGBA8888, false );
	unsigned char *pSphereMapBits = (unsigned char *)MemAllocScratch(iMemRequired);

	// Generate a spheremap for each frame of the cubemap
	for (int iFrame = 0; iFrame < m_nFrameCount; ++iFrame)
	{
		// Point to our own textures (highest mip level)
		for (int iFace = 0; iFace < 6; ++iFace)
		{
			pCubeMaps[iFace] = ImageData( iFrame, iFace, 0 );
		}

		// Compute the spheremap of the top LOD
		ComputeSpheremapFrame( pCubeMaps, pSphereMapBits, lookDir );

		// Compute the mip levels of the spheremap, converting from RGBA8888 to our format
		unsigned char *pFinalSphereMapBits = ImageData( iFrame, CUBEMAP_FACE_SPHEREMAP, 0 );
		ImageLoader::GenerateMipmapLevels( pSphereMapBits, pFinalSphereMapBits, 
			m_nWidth, m_nHeight, m_Format, 2.2, 2.2 );
	}

	// Free memory
	MemFreeScratch();
}
Esempio n. 2
0
//-----------------------------------------------------------------------------
// Gets the texture all internally consistent assuming you've loaded
// mip 0 of all faces of all frames
//-----------------------------------------------------------------------------
void CVTFTexture::PostProcess(bool bGenerateSpheremap, LookDir_t lookDir)
{
	Assert( m_Format == IMAGE_FORMAT_RGBA8888 );

	// Set up the cube map faces
	if (IsCubeMap())
	{
		// Rotate the cubemaps so they're appropriate for the material system
		FixCubemapFaceOrientation();

		// FIXME: We could theoretically not compute spheremap mip levels
		// in generate spheremaps; should we? The trick is when external
		// clients can be expected to call it

		// Compute the spheremap fallback for cubemaps if we weren't able to load up one...
		if (bGenerateSpheremap)
			GenerateSpheremap(lookDir);
	}

	// Generate mipmap levels
	GenerateMipmaps();

	if( Flags() & TEXTUREFLAGS_ONEOVERMIPLEVELINALPHA )
	{
		PutOneOverMipLevelInAlpha();
	}
	
	// Compute reflectivity
	ComputeReflectivity();

	// Are we 8-bit or 1-bit alpha?
	// NOTE: We have to do this *after*	computing the spheremap fallback for
	// cubemaps or it'll throw the flags off
	ComputeAlphaFlags();
}
Esempio n. 3
0
void CDxtexDoc::OnFormatChangeSurfaceFmt() 
{
    CChangeFmtDlg changeFmtDlg;
    LPDIRECT3DBASETEXTURE9 ptex;

    ptex = (m_ptexNew == NULL ? m_ptexOrig : m_ptexNew);

    if (IsVolumeMap())
    {
        D3DVOLUME_DESC vd;
        ((LPDIRECT3DVOLUMETEXTURE9)ptex)->GetLevelDesc(0, &vd);
        changeFmtDlg.m_fmt = vd.Format;
    }
    else if (IsCubeMap())
    {
        D3DSURFACE_DESC sd;
        ((LPDIRECT3DCUBETEXTURE9)ptex)->GetLevelDesc(0, &sd);
        changeFmtDlg.m_fmt = sd.Format;
    }
    else
    {
        D3DSURFACE_DESC sd;
        ((LPDIRECT3DTEXTURE9)ptex)->GetLevelDesc(0, &sd);
        changeFmtDlg.m_fmt = sd.Format;
    }

    changeFmtDlg.m_bVolume = IsVolumeMap();

    if (IDCANCEL == changeFmtDlg.DoModal())
        return;

    Compress(changeFmtDlg.m_fmt, TRUE);
}
Esempio n. 4
0
D3DFORMAT CDxtexDoc::GetFormat(LPDIRECT3DBASETEXTURE9 ptex)
{
    LPDIRECT3DTEXTURE9 pmiptex = NULL;
    LPDIRECT3DCUBETEXTURE9 pcubetex = NULL;
    LPDIRECT3DVOLUMETEXTURE9 pvoltex = NULL;
    D3DFORMAT fmt = D3DFMT_UNKNOWN;

    if (IsVolumeMap())
        pvoltex = (LPDIRECT3DVOLUMETEXTURE9)ptex;
    else if (IsCubeMap())
        pcubetex = (LPDIRECT3DCUBETEXTURE9)ptex;
    else
        pmiptex = (LPDIRECT3DTEXTURE9)ptex;

    if (pvoltex != NULL)
    {
        D3DVOLUME_DESC vd;
        pvoltex->GetLevelDesc(0, &vd);
        fmt = vd.Format;
    }
    else if (pcubetex != NULL)
    {
        D3DSURFACE_DESC sd;
        pcubetex->GetLevelDesc(0, &sd);
        fmt = sd.Format;
    }
    else if( pmiptex != NULL )
    {
        D3DSURFACE_DESC sd;
        pmiptex->GetLevelDesc(0, &sd);
        fmt = sd.Format;
    }
    return fmt;
}
Esempio n. 5
0
void CDxtexDoc::OpenAlphaCubeFace(D3DCUBEMAP_FACES FaceType)
{
    HRESULT hr;
    CString fileName;
    LPDIRECT3DSURFACE9 psurfOrig = NULL;
    LPDIRECT3DSURFACE9 psurfNew = NULL;
    D3DSURFACE_DESC sd;

    if (!IsCubeMap())
        return;

    hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetCubeMapSurface(FaceType, 0, &psurfOrig);
    ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetLevelDesc(0, &sd);
    if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
    {
        AfxMessageBox(ID_ERROR_PREMULTALPHA);
        return;
    }
    if (m_ptexNew != NULL)
    {
        hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetCubeMapSurface(FaceType, 0, &psurfNew);
    }

    if (!PromptForBmp(&fileName))
        return;

    if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
        return;

    if (psurfNew != NULL)
    {
        if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfNew)))
            return;
    }

    if (m_numMips > 1)
    {
        hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9)m_ptexOrig, NULL, 0, D3DX_DEFAULT);
    }


    if (psurfNew != NULL)
    {
        hr = D3DXLoadSurfaceFromSurface(psurfNew, NULL, NULL, psurfOrig, NULL, NULL, D3DX_DEFAULT, 0);

        if (m_numMips > 1)
        {
            hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9)m_ptexNew, NULL, 0, D3DX_DEFAULT);
        }
    }

    ReleasePpo(&psurfOrig);
    ReleasePpo(&psurfNew);

    SetModifiedFlag(TRUE);
    UpdateAllViews(NULL, 1);
}
Esempio n. 6
0
//-----------------------------------------------------------------------------
// Unserialization of image data
//-----------------------------------------------------------------------------
bool CVTFTexture::LoadImageData( CUtlBuffer &buf, const VTFFileHeader_t &header, int nSkipMipLevels )
{
	// Fix up the mip count + size based on how many mip levels we skip...
	if (nSkipMipLevels > 0)
	{
		Assert( m_nMipCount > nSkipMipLevels );
		if (header.numMipLevels < nSkipMipLevels)
		{
			// NOTE: This can only happen with older format .vtf files
			Warning("Warning! Encountered old format VTF file; please rebuild it!\n");
			return false;
		}

		ComputeMipLevelDimensions( nSkipMipLevels, &m_nWidth, &m_nHeight );
		m_nMipCount -= nSkipMipLevels;
	}

	// read the texture image (including mipmaps if they are there and needed.)
	int iImageSize = ComputeFaceSize( );
	iImageSize *= m_nFaceCount * m_nFrameCount;

	// For backwards compatibility, we don't read in the spheremap fallback on
	// older format .VTF files...
	int nFacesToRead = m_nFaceCount;
	if (IsCubeMap())
	{
		if ((header.version[0] == 7) && (header.version[1] < 1))
			nFacesToRead = 6;
	}

	// NOTE: We load the bits this way because we store the bits in memory
	// differently that the way they are stored on disk; we store on disk
	// differently so we can only load up 
	// NOTE: The smallest mip levels are stored first!!
	AllocateImageData( iImageSize );
	for (int iMip = m_nMipCount; --iMip >= 0; )
	{
		// NOTE: This is for older versions...
		if (header.numMipLevels - nSkipMipLevels <= iMip)
			continue;

		int iMipSize = ComputeMipSize( iMip );

		for (int iFrame = 0; iFrame < m_nFrameCount; ++iFrame)
		{
			for (int iFace = 0; iFace < nFacesToRead; ++iFace)
			{
				unsigned char *pMipBits = ImageData( iFrame, iFace, iMip );
				buf.Get( pMipBits, iMipSize );
			}
		}
	}

	return buf.IsValid();
}
Esempio n. 7
0
void CDxtexDoc::OpenCubeFace(D3DCUBEMAP_FACES FaceType)
{
    HRESULT hr;
    CString fileName;
    LPDIRECT3DSURFACE9 psurfOrig = NULL;
    LPDIRECT3DSURFACE9 psurfNew = NULL;

    if (!IsCubeMap())
        return;

    hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetCubeMapSurface(FaceType, 0, &psurfOrig);
    if (m_ptexNew != NULL)
        hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetCubeMapSurface(FaceType, 0, &psurfNew);

    if (!PromptForBmp(&fileName))
        return;

    hr = D3DXLoadSurfaceFromFile(psurfOrig, NULL, NULL, fileName, NULL, D3DX_DEFAULT, 0, NULL);

    // Look for "foo_a.bmp" for alpha channel
    int i = fileName.ReverseFind('.');
    fileName = fileName.Left(i) + "_a.bmp";
    CFileStatus status;
    if (CFile::GetStatus(fileName, status))
    {
        if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
            return;
    }

    if (m_numMips > 1)
    {
        hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9)m_ptexOrig, NULL, 0, D3DX_DEFAULT);
    }


    if (psurfNew != NULL)
    {
        hr = D3DXLoadSurfaceFromSurface(psurfNew, NULL, NULL, psurfOrig, NULL, NULL, D3DX_DEFAULT, 0);

        if (m_numMips > 1)
        {
            hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9)m_ptexNew, NULL, 0, D3DX_DEFAULT);
        }
    }

    ReleasePpo(&psurfOrig);
    ReleasePpo(&psurfNew);

    SetModifiedFlag(TRUE);
    UpdateAllViews(NULL, 1);
}
Esempio n. 8
0
bool
WebGLTexture::BindTexture(TexTarget texTarget)
{
    if (IsDeleted()) {
        mContext->ErrorInvalidOperation("bindTexture: Cannot bind a deleted object.");
        return false;
    }

    const bool isFirstBinding = !HasEverBeenBound();
    if (!isFirstBinding && mTarget != texTarget) {
        mContext->ErrorInvalidOperation("bindTexture: This texture has already been bound"
                                        " to a different target.");
        return false;
    }

    mTarget = texTarget;

    mContext->gl->fBindTexture(mTarget.get(), mGLName);

    if (isFirstBinding) {
        mFaceCount = IsCubeMap() ? 6 : 1;

        gl::GLContext* gl = mContext->gl;

        // Thanks to the WebKit people for finding this out: GL_TEXTURE_WRAP_R
        // is not present in GLES 2, but is present in GL and it seems as if for
        // cube maps we need to set it to GL_CLAMP_TO_EDGE to get the expected
        // GLES behavior.
        // If we are WebGL 2 though, we'll want to leave it as REPEAT.
        const bool hasWrapR = gl->IsSupported(gl::GLFeature::texture_3D);
        if (IsCubeMap() && hasWrapR && !mContext->IsWebGL2()) {
            gl->fTexParameteri(texTarget.get(), LOCAL_GL_TEXTURE_WRAP_R,
                               LOCAL_GL_CLAMP_TO_EDGE);
        }
    }

    return true;
}
Esempio n. 9
0
void CVTFTexture::ImageFileInfo( int nFrame, int nFace, int nMipLevel, int *pStartLocation, int *pSizeInBytes) const
{
	int i;
	int iMipWidth;
	int iMipHeight;

	// The image data starts after the low-res image
	int iLowResSize;
	int nOffset;
	LowResFileInfo( &nOffset, &iLowResSize );
	nOffset += iLowResSize;

	// get to the right miplevel
	for( i = m_nMipCount - 1; i > nMipLevel; --i )
	{
		ComputeMipLevelDimensions( i, &iMipWidth, &iMipHeight );
		int iMipLevelSize = ImageLoader::GetMemRequired( iMipWidth, iMipHeight, m_Format, false );
		nOffset += iMipLevelSize * m_nFrameCount * m_nFaceCount;
	}

	// get to the right frame
	ComputeMipLevelDimensions( nMipLevel, &iMipWidth, &iMipHeight );
	int nFaceSize = ImageLoader::GetMemRequired( iMipWidth, iMipHeight, m_Format, false );

	// For backwards compatibility, we don't read in the spheremap fallback on
	// older format .VTF files...
	int nFacesToRead = m_nFaceCount;
	if (IsCubeMap())
	{
		if ((m_pVersion[0] == 7) && (m_pVersion[1] < 1))
		{
			nFacesToRead = 6;
			if (nFace == CUBEMAP_FACE_SPHEREMAP)
				--nFace;
		}
	}

	int nFrameSize = nFacesToRead * nFaceSize;
	nOffset += nFrameSize * nFrame;
	
	// get to the right face
	nOffset += nFace * nFaceSize;
	
	*pStartLocation = nOffset;
	*pSizeInBytes = nFaceSize;
}
Esempio n. 10
0
HRESULT CDxtexDoc::LoadAlphaBmp(CString& strPath)
{
    HRESULT hr;
    LPDIRECT3DTEXTURE9 pmiptex;
    LPDIRECT3DSURFACE9 psurf;

    if (IsCubeMap())
        return E_FAIL;

    pmiptex = (LPDIRECT3DTEXTURE9)m_ptexOrig;
    hr = pmiptex->GetSurfaceLevel(0, &psurf);
    if (FAILED(hr))
        return hr;

    hr = LoadAlphaIntoSurface(strPath, psurf);
    ReleasePpo(&psurf);
    if (FAILED(hr))
        return hr;
    
    UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
    return S_OK;
}
Esempio n. 11
0
//-----------------------------------------------------------------------------
// Fixes the cubemap faces orientation from our standard to what the material system needs
//-----------------------------------------------------------------------------
void CVTFTexture::FixCubemapFaceOrientation( )
{
	if (!IsCubeMap())
		return;

	Assert( m_Format == IMAGE_FORMAT_RGBA8888 );

	for (int iMipLevel = 0; iMipLevel < m_nMipCount; ++iMipLevel)
	{
		int iMipSize, iTemp;
		ComputeMipLevelDimensions( iMipLevel, &iMipSize, &iTemp );
		Assert( iMipSize == iTemp );

		for (int iFrame = 0; iFrame < m_nFrameCount; ++iFrame)
		{
			for (int iFace = 0; iFace < 6; ++iFace)
			{
				FixCubeMapFacing( ImageData( iFrame, iFace, iMipLevel ), iFace, iMipSize, m_Format );
			}
		}
	}
}
Esempio n. 12
0
void CDxtexDoc::OnUpdateFileOpenAlpha(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(!IsCubeMap() && !IsVolumeMap()); 
}
Esempio n. 13
0
void CDxtexDoc::OpenAlphaSubsurface(D3DCUBEMAP_FACES FaceType, LONG lwMip, LONG lwSlice)
{
    HRESULT hr;
    CString fileName;
    LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
    LPDIRECT3DTEXTURE9 ptexOrig = NULL;
    LPDIRECT3DTEXTURE9 ptexNew = NULL;
    LPDIRECT3DSURFACE9 psurfOrig = NULL;
    LPDIRECT3DSURFACE9 psurfNew = NULL;
    LPDIRECT3DVOLUME9 pvolOrig = NULL;
    LPDIRECT3DVOLUME9 pvolNew = NULL;
    D3DSURFACE_DESC sd;
    DWORD dwWidth = m_dwWidth;
    DWORD dwHeight = m_dwHeight;

    if (IsVolumeMap())
    {
        for (int i = 0; i < lwMip; i++)
        {
            dwWidth /= 2;
            dwHeight /= 2;
        }
        hr = pd3ddev->CreateTexture(dwWidth, dwHeight, 1, 
             0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &ptexOrig, NULL);
        hr = ptexOrig->GetSurfaceLevel(0, &psurfOrig);
        hr = ((LPDIRECT3DVOLUMETEXTURE9)m_ptexOrig)->GetVolumeLevel(lwMip, &pvolOrig);
        hr = LoadSurfaceFromVolumeSlice(pvolOrig, lwSlice, psurfOrig);
        if (m_ptexNew != NULL)
        {
            hr = pd3ddev->CreateTexture(dwWidth, dwHeight, 1, 
                 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &ptexNew, NULL);
            hr = ptexNew->GetSurfaceLevel(0, &psurfOrig);
            hr = ((LPDIRECT3DVOLUMETEXTURE9)m_ptexOrig)->GetVolumeLevel(lwMip, &pvolNew);
            hr = LoadSurfaceFromVolumeSlice(pvolNew, lwSlice, psurfOrig);
        }
    }
    else if (IsCubeMap())
    {
        hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetCubeMapSurface(FaceType, lwMip, &psurfOrig);
        ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetLevelDesc(lwMip, &sd);
        if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
        {
            AfxMessageBox(ID_ERROR_PREMULTALPHA);
            goto LCleanup;
        }
        if (m_ptexNew != NULL)
        {
            hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetCubeMapSurface(FaceType, lwMip, &psurfNew);
            ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetLevelDesc(lwMip, &sd);
            if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
            {
                AfxMessageBox(ID_ERROR_PREMULTALPHA);
                goto LCleanup;
            }
        }
    }
    else
    {
        BOOL bAlphaFound = FALSE;
        hr = ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetSurfaceLevel(lwMip, &psurfOrig);
        ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetLevelDesc(lwMip, &sd);
        if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
        {
            AfxMessageBox(ID_ERROR_PREMULTALPHA);
            goto LCleanup;
        }

        // Check if the original has alpha
        if( FormatContainsAlpha(sd.Format) )
        {
            bAlphaFound = TRUE;
        }

        if (m_ptexNew != NULL)
        {
            hr = ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetSurfaceLevel(lwMip, &psurfNew);
            ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(lwMip, &sd);
            if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
            {
                AfxMessageBox(ID_ERROR_PREMULTALPHA);
                goto LCleanup;
            }
            // Check if the new has alpha
            if( FormatContainsAlpha(sd.Format) )
            {
                bAlphaFound = TRUE;
            }
        }

        if( bAlphaFound == FALSE )
        {
            AfxMessageBox(ID_ERROR_NEEDALPHA);
            goto LCleanup;
        }
    }

    if (!PromptForBmp(&fileName))
        goto LCleanup;

    if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
        goto LCleanup;

    if (psurfNew != NULL)
    {
        if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfNew)))
            goto LCleanup;
    }

    if (pvolOrig != NULL)
    {
        hr = LoadVolumeSliceFromSurface(pvolOrig, lwSlice, psurfOrig);
    }
    if (pvolNew != NULL)
    {
        hr = LoadVolumeSliceFromSurface(pvolNew, lwSlice, psurfNew);
    }

    SetModifiedFlag(TRUE);
    UpdateAllViews(NULL, 1);

LCleanup:
    ReleasePpo(&psurfOrig);
    ReleasePpo(&psurfNew);
    ReleasePpo(&ptexOrig);
    ReleasePpo(&ptexNew);
    ReleasePpo(&pvolOrig);
    ReleasePpo(&pvolNew);
}
Esempio n. 14
0
void CDxtexDoc::OnUpdateFormatChangeCubeMapFaces(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(!IsCubeMap() && !IsVolumeMap()); 
}
Esempio n. 15
0
void CDxtexDoc::OpenSubsurface(D3DCUBEMAP_FACES FaceType, LONG lwMip, LONG lwSlice)
{
    HRESULT hr;
    CString fileName;
    LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
    LPDIRECT3DTEXTURE9 ptex = NULL;
    LPDIRECT3DSURFACE9 psurfOrig = NULL;
    LPDIRECT3DSURFACE9 psurfNew = NULL;

    if (!PromptForBmp(&fileName))
        return;

    if (IsVolumeMap())
    {
        hr = D3DXCreateTextureFromFile(pd3ddev, fileName, &ptex);
        hr = ptex->GetSurfaceLevel(0, &psurfOrig);
    }
    else if (IsCubeMap())
    {
        hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetCubeMapSurface(FaceType, lwMip, &psurfOrig);
        if (m_ptexNew != NULL)
            hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetCubeMapSurface(FaceType, lwMip, &psurfNew);
        hr = D3DXLoadSurfaceFromFile(psurfOrig, NULL, NULL, fileName, NULL, D3DX_DEFAULT, 0, NULL);
    }
    else
    {
        hr = ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetSurfaceLevel(lwMip, &psurfOrig);
        if (m_ptexNew != NULL)
            hr = ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetSurfaceLevel(lwMip, &psurfNew);
        hr = D3DXLoadSurfaceFromFile(psurfOrig, NULL, NULL, fileName, NULL, D3DX_DEFAULT, 0, NULL);
    }

    // Look for "foo_a.bmp" for alpha channel
    int i = fileName.ReverseFind('.');
    fileName = fileName.Left(i) + "_a.bmp";
    CFileStatus status;
    if (CFile::GetStatus(fileName, status))
    {
        if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
            return;
    }

    if (IsVolumeMap())
    {
        LPDIRECT3DVOLUME9 pvol;
        hr = ((LPDIRECT3DVOLUMETEXTURE9)m_ptexOrig)->GetVolumeLevel(lwMip, &pvol);
        hr = LoadVolumeSliceFromSurface(pvol, lwSlice, psurfOrig);
        ReleasePpo(&pvol);
        if (m_ptexNew)
        {
            hr = ((LPDIRECT3DVOLUMETEXTURE9)m_ptexNew)->GetVolumeLevel(lwMip, &pvol);
            hr = LoadVolumeSliceFromSurface(pvol, lwSlice, psurfOrig);
            ReleasePpo(&pvol);
        }
    }
    else if (psurfNew != NULL)
    {
        hr = D3DXLoadSurfaceFromSurface(psurfNew, NULL, NULL, psurfOrig, NULL, NULL, D3DX_DEFAULT, 0);
    }

    ReleasePpo(&psurfOrig);
    ReleasePpo(&psurfNew);
    ReleasePpo(&ptex);

    SetModifiedFlag(TRUE);
    UpdateAllViews(NULL, 1);
}
Esempio n. 16
0
void CDxtexDoc::OnFileOpenAlpha() 
{
    HRESULT hr;
    CString fileName;
    LPDIRECT3DTEXTURE9 pmiptex;

    if (IsCubeMap() || IsVolumeMap())
        return;

    // Premultiplied-alpha files don't support this feature:
    D3DSURFACE_DESC sd;
    ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetLevelDesc(0, &sd);
    if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
    {
        AfxMessageBox(ID_ERROR_PREMULTALPHA);
        return;
    }

    // Check if the original has alpha
    if( !FormatContainsAlpha(sd.Format)  )
    {
        // If it doesn't then see if the new does
        if (m_ptexNew != NULL)
        {
            ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
            if( !FormatContainsAlpha(sd.Format) )
            {
                AfxMessageBox(ID_ERROR_NEEDALPHA);
                return;
            }
            else
            {
                ReleasePpo(&m_ptexOrig);
                m_ptexOrig = m_ptexNew;
                m_ptexNew  = NULL;
                CWnd* Wnd = AfxGetMainWnd();
                if( Wnd != NULL )
                    Wnd->PostMessage(WM_COMMAND, ID_VIEW_ORIGINAL, 0);
            }
        }
        else
        {
                AfxMessageBox(ID_ERROR_NEEDALPHA);
                return;
        }
    }

    pmiptex = (LPDIRECT3DTEXTURE9)m_ptexOrig;

    if (!PromptForBmp(&fileName))
        return;

    LPDIRECT3DSURFACE9 psurf;
    if (FAILED(hr = pmiptex->GetSurfaceLevel(0, &psurf)))
        return;

    if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurf)))
        return;
    if (m_numMips > 1)
        OnGenerateMipMaps();
    else if (m_ptexNew != NULL)
    {
        ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
        Compress(sd.Format, FALSE);
    }
    UpdateAllViews(NULL, 1);
}
Esempio n. 17
0
void CDxtexDoc::OnUpdateFormatMakeIntoVolumeMap(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(!IsCubeMap() && !IsVolumeMap());
}
Esempio n. 18
0
bool
WebGLTexture::IsComplete(uint32_t texUnit, const char** const out_reason) const
{
    // Texture completeness is established at GLES 3.0.4, p160-161.
    // "[A] texture is complete unless any of the following conditions hold true:"

    // "* Any dimension of the `level_base` array is not positive."
    const ImageInfo& baseImageInfo = BaseImageInfo();
    if (!baseImageInfo.IsDefined()) {
        // In case of undefined texture image, we don't print any message because this is
        // a very common and often legitimate case (asynchronous texture loading).
        *out_reason = nullptr;
        return false;
    }

    if (!baseImageInfo.mWidth || !baseImageInfo.mHeight || !baseImageInfo.mDepth) {
        *out_reason = "The dimensions of `level_base` are not all positive.";
        return false;
    }

    // "* The texture is a cube map texture, and is not cube complete."
    if (IsCubeMap() && !IsCubeComplete()) {
        *out_reason = "Cubemaps must be \"cube complete\".";
        return false;
    }

    WebGLSampler* sampler = mContext->mBoundSamplers[texUnit];
    TexMinFilter minFilter = sampler ? sampler->mMinFilter : mMinFilter;
    TexMagFilter magFilter = sampler ? sampler->mMagFilter : mMagFilter;

    // "* The minification filter requires a mipmap (is neither NEAREST nor LINEAR) and
    //    the texture is not mipmap complete."
    const bool requiresMipmap = (minFilter != LOCAL_GL_NEAREST &&
                                 minFilter != LOCAL_GL_LINEAR);
    if (requiresMipmap && !IsMipmapComplete(texUnit)) {
        *out_reason = "Because the minification filter requires mipmapping, the texture"
                      " must be \"mipmap complete\".";
        return false;
    }

    const bool isMinFilteringNearest = (minFilter == LOCAL_GL_NEAREST ||
                                        minFilter == LOCAL_GL_NEAREST_MIPMAP_NEAREST);
    const bool isMagFilteringNearest = (magFilter == LOCAL_GL_NEAREST);
    const bool isFilteringNearestOnly = (isMinFilteringNearest && isMagFilteringNearest);
    if (!isFilteringNearestOnly) {
        auto formatUsage = baseImageInfo.mFormat;
        auto format = formatUsage->format;

        // "* The effective internal format specified for the texture arrays is a sized
        //    internal color format that is not texture-filterable, and either the
        //    magnification filter is not NEAREST or the minification filter is neither
        //    NEAREST nor NEAREST_MIPMAP_NEAREST."
        // Since all (GLES3) unsized color formats are filterable just like their sized
        // equivalents, we don't have to care whether its sized or not.
        if (format->isColorFormat && !formatUsage->isFilterable) {
            *out_reason = "Because minification or magnification filtering is not NEAREST"
                          " or NEAREST_MIPMAP_NEAREST, and the texture's format is a"
                          " color format, its format must be \"texture-filterable\".";
            return false;
        }

        // "* The effective internal format specified for the texture arrays is a sized
        //    internal depth or depth and stencil format, the value of
        //    TEXTURE_COMPARE_MODE is NONE[1], and either the magnification filter is not
        //    NEAREST, or the minification filter is neither NEAREST nor
        //    NEAREST_MIPMAP_NEAREST."
        // [1]: This sounds suspect, but is explicitly noted in the change log for GLES
        //      3.0.1:
        //      "* Clarify that a texture is incomplete if it has a depth component, no
        //         shadow comparison, and linear filtering (also Bug 9481)."
        // As of OES_packed_depth_stencil rev #3, the sample code explicitly samples from
        // a DEPTH_STENCIL_OES texture with a min-filter of LINEAR. Therefore we relax
        // this restriction if WEBGL_depth_texture is enabled.
        if (!mContext->IsExtensionEnabled(WebGLExtensionID::WEBGL_depth_texture)) {
            if (format->hasDepth && mTexCompareMode != LOCAL_GL_NONE) {
                *out_reason = "A depth or depth-stencil format with TEXTURE_COMPARE_MODE"
                              " of NONE must have minification or magnification filtering"
                              " of NEAREST or NEAREST_MIPMAP_NEAREST.";
                return false;
            }
        }
    }

    // Texture completeness is effectively (though not explicitly) amended for GLES2 by
    // the "Texture Access" section under $3.8 "Fragment Shaders". This also applies to
    // vertex shaders, as noted on GLES 2.0.25, p41.
    if (!mContext->IsWebGL2()) {
        // GLES 2.0.25, p87-88:
        // "Calling a sampler from a fragment shader will return (R,G,B,A)=(0,0,0,1) if
        //  any of the following conditions are true:"

        // "* A two-dimensional sampler is called, the minification filter is one that
        //    requires a mipmap[...], and the sampler's associated texture object is not
        //    complete[.]"
        // (already covered)

        // "* A two-dimensional sampler is called, the minification filter is not one that
        //    requires a mipmap (either NEAREST nor[sic] LINEAR), and either dimension of
        //    the level zero array of the associated texture object is not positive."
        // (already covered)

        // "* A two-dimensional sampler is called, the corresponding texture image is a
        //    non-power-of-two image[...], and either the texture wrap mode is not
        //    CLAMP_TO_EDGE, or the minification filter is neither NEAREST nor LINEAR."

        // "* A cube map sampler is called, any of the corresponding texture images are
        //    non-power-of-two images, and either the texture wrap mode is not
        //    CLAMP_TO_EDGE, or the minification filter is neither NEAREST nor LINEAR."
        if (!baseImageInfo.IsPowerOfTwo()) {
            TexWrap wrapS = sampler ? sampler->mWrapS : mWrapS;
            TexWrap wrapT = sampler ? sampler->mWrapT : mWrapT;
            // "either the texture wrap mode is not CLAMP_TO_EDGE"
            if (wrapS != LOCAL_GL_CLAMP_TO_EDGE ||
                wrapT != LOCAL_GL_CLAMP_TO_EDGE)
            {
                *out_reason = "Non-power-of-two textures must have a wrap mode of"
                              " CLAMP_TO_EDGE.";
                return false;
            }

            // "or the minification filter is neither NEAREST nor LINEAR"
            if (requiresMipmap) {
                *out_reason = "Mipmapping requires power-of-two textures.";
                return false;
            }
        }

        // "* A cube map sampler is called, and either the corresponding cube map texture
        //    image is not cube complete, or TEXTURE_MIN_FILTER is one that requires a
        //    mipmap and the texture is not mipmap cube complete."
        // (already covered)
    }

    return true;
}
Esempio n. 19
0
void CDxtexDoc::OnUpdateFormatResize(CCmdUI* pCmdUI) 
{
    pCmdUI->Enable(!IsCubeMap() && !IsVolumeMap());
}
Esempio n. 20
0
HRESULT CDxtexDoc::ChangeFormat(LPDIRECT3DBASETEXTURE9 ptexCur, D3DFORMAT fmtTo, 
                                LPDIRECT3DBASETEXTURE9* pptexNew)
{
    HRESULT hr;
    LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
    LPDIRECT3DTEXTURE9 pmiptex;
    LPDIRECT3DCUBETEXTURE9 pcubetex;
    LPDIRECT3DVOLUMETEXTURE9 pvoltex;
    D3DFORMAT fmtFrom;
    LPDIRECT3DTEXTURE9 pmiptexNew;
    LPDIRECT3DCUBETEXTURE9 pcubetexNew;
    LPDIRECT3DVOLUMETEXTURE9 pvoltexNew;

    if (IsVolumeMap())
    {
        pvoltex = (LPDIRECT3DVOLUMETEXTURE9)ptexCur;
        D3DVOLUME_DESC vd;
        pvoltex->GetLevelDesc(0, &vd);
        fmtFrom = vd.Format;
    }
    else if (IsCubeMap())
    {
        pcubetex = (LPDIRECT3DCUBETEXTURE9)ptexCur;
        D3DSURFACE_DESC sd;
        pcubetex->GetLevelDesc(0, &sd);
        fmtFrom = sd.Format;
    }
    else
    {
        pmiptex = (LPDIRECT3DTEXTURE9)ptexCur;
        D3DSURFACE_DESC sd;
        pmiptex->GetLevelDesc(0, &sd);
        fmtFrom = sd.Format;
    }

    if (fmtFrom == D3DFMT_DXT2 || fmtFrom == D3DFMT_DXT4)
    {
        if (fmtTo == D3DFMT_DXT1)
        {
            AfxMessageBox(ID_ERROR_PREMULTTODXT1);
        }
        else if (fmtTo != D3DFMT_DXT2 && fmtTo != D3DFMT_DXT4)
        {
            AfxMessageBox(ID_ERROR_PREMULTALPHA);
            return S_OK;
        }
    }

    if (IsVolumeMap())
    {
        hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, m_numMips,
            0, fmtTo, D3DPOOL_SYSTEMMEM, &pvoltexNew, NULL);
        if (FAILED(hr))
            return hr;
        *pptexNew = pvoltexNew;
        if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD, ptexCur, *pptexNew)))
            return hr;
    }
    else if (IsCubeMap())
    {
        hr = pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips, 
             0, fmtTo, D3DPOOL_MANAGED, &pcubetexNew, NULL);
        if (FAILED(hr))
            return hr;
        *pptexNew = pcubetexNew;
        if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_X, ptexCur, *pptexNew)))
            return hr;
        if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_X, ptexCur, *pptexNew)))
            return hr;
        if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_Y, ptexCur, *pptexNew)))
            return hr;
        if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_Y, ptexCur, *pptexNew)))
            return hr;
        if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_Z, ptexCur, *pptexNew)))
            return hr;
        if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_Z, ptexCur, *pptexNew)))
            return hr;
    }
    else
    {
        if ((fmtTo == D3DFMT_DXT1 || fmtTo == D3DFMT_DXT2 ||
            fmtTo == D3DFMT_DXT3 || fmtTo == D3DFMT_DXT4 ||
            fmtTo == D3DFMT_DXT5) && (m_dwWidth % 4 != 0 || m_dwHeight % 4 != 0))
        {
            AfxMessageBox(ID_ERROR_NEEDMULTOF4);
            return E_FAIL;
        }

        hr = pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips, 
             0, fmtTo, D3DPOOL_MANAGED, &pmiptexNew, NULL);
        if (FAILED(hr))
            return hr;
        *pptexNew = pmiptexNew;
        if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD, ptexCur, *pptexNew)))
            return hr;
    }
    return S_OK;
}
Esempio n. 21
0
void CDxtexDoc::GenerateMipMaps() 
{
    LONG lwTempH;
    LONG lwTempW;
    LONG lwPowsW;
    LONG lwPowsH;
    LPDIRECT3DTEXTURE9 pddsNew = NULL;
    D3DFORMAT fmt;
    HRESULT hr;
    LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
    LPDIRECT3DTEXTURE9 pmiptex = NULL;
    LPDIRECT3DCUBETEXTURE9 pcubetex = NULL;
    LPDIRECT3DVOLUMETEXTURE9 pvoltex = NULL;
    LPDIRECT3DTEXTURE9 pmiptexNew = NULL;
    LPDIRECT3DCUBETEXTURE9 pcubetexNew = NULL;
    LPDIRECT3DVOLUMETEXTURE9 pvoltexNew = NULL;
    LPDIRECT3DSURFACE9 psurfSrc;
    LPDIRECT3DSURFACE9 psurfDest;
    LPDIRECT3DVOLUME9 pvolSrc;
    LPDIRECT3DVOLUME9 pvolDest;

    if (IsVolumeMap())
        pvoltex = (LPDIRECT3DVOLUMETEXTURE9)m_ptexOrig;
    else if (IsCubeMap())
        pcubetex = (LPDIRECT3DCUBETEXTURE9)m_ptexOrig;
    else
        pmiptex = (LPDIRECT3DTEXTURE9)m_ptexOrig;

    if (pvoltex != NULL)
    {
        D3DVOLUME_DESC vd;
        pvoltex->GetLevelDesc(0, &vd);
        fmt = vd.Format;
    }
    else if (pcubetex != NULL)
    {
        D3DSURFACE_DESC sd;
        pcubetex->GetLevelDesc(0, &sd);
        fmt = sd.Format;
    }
    else
    {
        D3DSURFACE_DESC sd;
        pmiptex->GetLevelDesc(0, &sd);
        fmt = sd.Format;
    }

    lwTempW = m_dwWidth;
    lwTempH = m_dwHeight;
    lwPowsW = 0;
    lwPowsH = 0;
    while (lwTempW > 0)
    {
        lwPowsW++;
        lwTempW = lwTempW / 2;
    }
    while (lwTempH > 0)
    {
        lwPowsH++;
        lwTempH = lwTempH / 2;
    }
    m_numMips = lwPowsW > lwPowsH ? lwPowsW : lwPowsH;

    // Create destination mipmap surface - same format as source
    if (pvoltex != NULL)
    {
        if (FAILED(hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, 
            m_numMips, 0, fmt, D3DPOOL_SYSTEMMEM, &pvoltexNew, NULL)))
        {
            goto LFail;
        }
        hr = pvoltex->GetVolumeLevel(0, &pvolSrc);
        hr = pvoltexNew->GetVolumeLevel(0, &pvolDest);
        hr = D3DXLoadVolumeFromVolume(pvolDest, NULL, NULL, pvolSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&pvolSrc);
        ReleasePpo(&pvolDest);
        hr = D3DXFilterVolumeTexture(pvoltexNew, NULL, 0, D3DX_DEFAULT);
    }
    else if (pmiptex != NULL)
    {
        if (FAILED(hr = pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips, 
             0, fmt, D3DPOOL_MANAGED, &pmiptexNew, NULL)))
        {
            goto LFail;
        }
        hr = pmiptex->GetSurfaceLevel(0, &psurfSrc);
        hr = pmiptexNew->GetSurfaceLevel(0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = D3DXFilterTexture(pmiptexNew, NULL, 0, D3DX_DEFAULT);
    }
    else
    {
        if (FAILED(hr = pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips, 
             0, fmt, D3DPOOL_MANAGED, &pcubetexNew, NULL)))
        {
            goto LFail;
        }
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z, 0, &psurfSrc);
        hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z, 0, &psurfDest);
        hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
            D3DX_DEFAULT, 0);
        ReleasePpo(&psurfSrc);
        ReleasePpo(&psurfDest);
        hr = D3DXFilterCubeTexture(pcubetexNew, NULL, 0, D3DX_DEFAULT);
    }

    ReleasePpo(&m_ptexOrig);
    if (pvoltexNew != NULL)
        m_ptexOrig = pvoltexNew;
    else if (pcubetexNew != NULL)
        m_ptexOrig = pcubetexNew;
    else
        m_ptexOrig = pmiptexNew;

    if (m_ptexNew != NULL)
    {
        // Rather than filtering down the (probably-compressed) m_ptexNew 
        // top level, compress each mip level from the (probably-uncompressed)
        // m_ptexOrig levels.
        if (pvoltexNew != NULL)
        {
            D3DVOLUME_DESC vd;
            ((LPDIRECT3DVOLUMETEXTURE9)m_ptexNew)->GetLevelDesc(0, &vd);
            fmt = vd.Format;
        }
        else if (pcubetexNew != NULL)
        {
            D3DSURFACE_DESC sd;
            ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
            fmt = sd.Format;
        }
        else
        {
            D3DSURFACE_DESC sd;
            ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
            fmt = sd.Format;
        }
        Compress(fmt, FALSE);
    }

    m_bTitleModsChanged = TRUE; // Generate title bar update
    UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
    SetModifiedFlag();
    return;

LFail:
    ReleasePpo(&pddsNew);
}
Esempio n. 22
0
void
WebGLTexture::GenerateMipmap(TexTarget texTarget)
{
    // GLES 3.0.4 p160:
    // "Mipmap generation replaces texel array levels level base + 1 through q with arrays
    //  derived from the level base array, regardless of their previous contents. All
    //  other mipmap arrays, including the level base array, are left unchanged by this
    //  computation."
    const ImageInfo& baseImageInfo = BaseImageInfo();
    if (!baseImageInfo.IsDefined()) {
        mContext->ErrorInvalidOperation("generateMipmap: The base level of the texture is"
                                        " not defined.");
        return;
    }

    if (IsCubeMap() && !IsCubeComplete()) {
      mContext->ErrorInvalidOperation("generateMipmap: Cube maps must be \"cube"
                                      " complete\".");
      return;
    }

    if (!mContext->IsWebGL2() && !baseImageInfo.IsPowerOfTwo()) {
        mContext->ErrorInvalidOperation("generateMipmap: The base level of the texture"
                                        " does not have power-of-two dimensions.");
        return;
    }

    auto format = baseImageInfo.mFormat->format;
    if (format->compression) {
        mContext->ErrorInvalidOperation("generateMipmap: Texture data at base level is"
                                        " compressed.");
        return;
    }

    if (format->hasDepth) {
        mContext->ErrorInvalidOperation("generateMipmap: Depth textures are not"
                                        " supported.");
        return;
    }

    // OpenGL ES 3.0.4 p160:
    // If the level base array was not specified with an unsized internal format from
    // table 3.3 or a sized internal format that is both color-renderable and
    // texture-filterable according to table 3.13, an INVALID_OPERATION error
    // is generated.
    const auto usage = baseImageInfo.mFormat;
    bool canGenerateMipmap = (usage->isRenderable && usage->isFilterable);
    switch (usage->format->effectiveFormat) {
    case webgl::EffectiveFormat::Luminance8:
    case webgl::EffectiveFormat::Alpha8:
    case webgl::EffectiveFormat::Luminance8Alpha8:
        // Non-color-renderable formats from Table 3.3.
        canGenerateMipmap = true;
        break;
    default:
        break;
    }

    if (!canGenerateMipmap) {
        mContext->ErrorInvalidOperation("generateMipmap: Texture at base level is not unsized"
                                        " internal format or is not"
                                        " color-renderable or texture-filterable.");
        return;
    }

    // Done with validation. Do the operation.

    mContext->MakeContextCurrent();
    gl::GLContext* gl = mContext->gl;

    if (gl->WorkAroundDriverBugs()) {
        // bug 696495 - to work around failures in the texture-mips.html test on various drivers, we
        // set the minification filter before calling glGenerateMipmap. This should not carry a significant performance
        // overhead so we do it unconditionally.
        //
        // note that the choice of GL_NEAREST_MIPMAP_NEAREST really matters. See Chromium bug 101105.
        gl->fTexParameteri(texTarget.get(), LOCAL_GL_TEXTURE_MIN_FILTER,
                           LOCAL_GL_NEAREST_MIPMAP_NEAREST);
        gl->fGenerateMipmap(texTarget.get());
        gl->fTexParameteri(texTarget.get(), LOCAL_GL_TEXTURE_MIN_FILTER,
                           mMinFilter.get());
    } else {
        gl->fGenerateMipmap(texTarget.get());
    }

    // Record the results.
    // Note that we don't use MaxEffectiveMipmapLevel() here, since that returns
    // mBaseMipmapLevel if the min filter doesn't require mipmaps.
    const uint32_t lastLevel = mBaseMipmapLevel + baseImageInfo.MaxMipmapLevels() - 1;
    PopulateMipChain(mBaseMipmapLevel, lastLevel);
}
Esempio n. 23
0
HRESULT CDxtexDoc::BltAllLevels(D3DCUBEMAP_FACES FaceType, 
    LPDIRECT3DBASETEXTURE9 ptexSrc, LPDIRECT3DBASETEXTURE9 ptexDest)
{
    HRESULT hr;
    LPDIRECT3DTEXTURE9 pmiptexSrc;
    LPDIRECT3DTEXTURE9 pmiptexDest;
    LPDIRECT3DCUBETEXTURE9 pcubetexSrc;
    LPDIRECT3DCUBETEXTURE9 pcubetexDest;
    LPDIRECT3DVOLUMETEXTURE9 pvoltexSrc;
    LPDIRECT3DVOLUMETEXTURE9 pvoltexDest;
    DWORD iLevel;

    if (IsVolumeMap())
    {
        pvoltexSrc = (LPDIRECT3DVOLUMETEXTURE9)ptexSrc;
        pvoltexDest = (LPDIRECT3DVOLUMETEXTURE9)ptexDest;
    }
    else if (IsCubeMap())
    {
        pcubetexSrc = (LPDIRECT3DCUBETEXTURE9)ptexSrc;
        pcubetexDest = (LPDIRECT3DCUBETEXTURE9)ptexDest;
    }
    else
    {
        pmiptexSrc = (LPDIRECT3DTEXTURE9)ptexSrc;
        pmiptexDest = (LPDIRECT3DTEXTURE9)ptexDest;
    }

    for (iLevel = 0; iLevel < m_numMips; iLevel++)
    {
        if (IsVolumeMap())
        {
            LPDIRECT3DVOLUME9 pvolSrc = NULL;
            LPDIRECT3DVOLUME9 pvolDest = NULL;
            hr = pvoltexSrc->GetVolumeLevel(iLevel, &pvolSrc);
            hr = pvoltexDest->GetVolumeLevel(iLevel, &pvolDest);
            hr = D3DXLoadVolumeFromVolume(pvolDest, NULL, NULL, 
                pvolSrc, NULL, NULL, D3DX_DEFAULT, 0);
            ReleasePpo(&pvolSrc);
            ReleasePpo(&pvolDest);
        }
        else if (IsCubeMap())
        {
            LPDIRECT3DSURFACE9 psurfSrc = NULL;
            LPDIRECT3DSURFACE9 psurfDest = NULL;
            hr = pcubetexSrc->GetCubeMapSurface(FaceType, iLevel, &psurfSrc);
            hr = pcubetexDest->GetCubeMapSurface(FaceType, iLevel, &psurfDest);
            hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, 
                psurfSrc, NULL, NULL, D3DX_DEFAULT, 0);
            ReleasePpo(&psurfSrc);
            ReleasePpo(&psurfDest);
        }
        else
        {
            LPDIRECT3DSURFACE9 psurfSrc = NULL;
            LPDIRECT3DSURFACE9 psurfDest = NULL;
            hr = pmiptexSrc->GetSurfaceLevel(iLevel, &psurfSrc);
            hr = pmiptexDest->GetSurfaceLevel(iLevel, &psurfDest);
            hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, 
                psurfSrc, NULL, NULL, D3DX_DEFAULT, 0);
            ReleasePpo(&psurfSrc);
            ReleasePpo(&psurfDest);
        }
    }

    return S_OK;
}