コード例 #1
0
ファイル: N3Texture.cpp プロジェクト: VincentKO/KnightOnline
bool CN3Texture::CreateFromSurface(LPDIRECT3DSURFACE8 lpSurf, D3DFORMAT Format, BOOL bGenerateMipMap)
{
	if(lpSurf == NULL) return false;

	D3DSURFACE_DESC sd;
	lpSurf->GetDesc(&sd);

	if(this->Create(sd.Width, sd.Height, Format, bGenerateMipMap) == false) return false;
	if(bGenerateMipMap)
	{
		this->GenerateMipMap(lpSurf);
	}
	
	return true;
}
コード例 #2
0
ファイル: main2.cpp プロジェクト: wrybri/comp4995Research
void SimpleBitmapDraw(char* PathName, LPDIRECT3DSURFACE8 pBackSurf, int dpx, int dpy){
	LPDIRECT3DSURFACE8 pSurface = 0;

	LoadBitmapToSurface(PathName, &pSurface, g_pDevice);

	D3DSURFACE_DESC d3dsd;
	pSurface->GetDesc(&d3dsd);//get info about surface

	POINT DestPoint = {dpx, dpy};
	RECT rect = {0,0, d3dsd.Width, d3dsd.Height};//source dimensions

	g_pDevice->CopyRects(pSurface, &rect, 1, pBackSurf, &DestPoint);//copy surface to buffer (like a bitblt)

//	pSurface->Release();
//	pSurface = 0;

//	pBackSurf->Release();
//	pBackSurf = 0;
//
//	g_pDevice->Present(NULL, NULL, NULL, NULL);//put it on the primary surface
}
コード例 #3
0
ファイル: XBMCTex.cpp プロジェクト: Avoidnf8/xbmc-fork
// Converts any fully transparent pixels to black so that the mse calcs work for dxt
void FixTransparency(LPDIRECT3DSURFACE8 pSrcSurf)
{
	D3DSURFACE_DESC desc;
	pSrcSurf->GetDesc(&desc);

	D3DLOCKED_RECT slr;
	if (FAILED(pSrcSurf->LockRect(&slr, NULL, 0)))
		return;

	DWORD* pix = (DWORD*)slr.pBits;
	for (UINT y = 0; y < desc.Width; ++y)
	{
		for (UINT x = 0; x < desc.Height; ++x)
		{
			if (!(*pix & 0xff000000))
				*pix = 0;
			++pix;
		}
	}

	pSrcSurf->UnlockRect();
}
コード例 #4
0
ファイル: main2.cpp プロジェクト: wrybri/comp4995Research
int Render(){
	HRESULT r;
//	D3DLOCKED_RECT LockedRect;//locked area of display memory(buffer really) we are drawing to
	LPDIRECT3DSURFACE8 pBackSurf = 0;
	if(!g_pDevice){
		SetError("Cannot render because there is no device");
		return E_FAIL;
	}

	//clear the display arera with colour black, ignore stencil buffer
	g_pDevice->Clear(0,0,D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,25), 1.0f, 0);

	//get pointer to backbuffer
	r=g_pDevice->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO, &pBackSurf);
	if(FAILED(r)){
		SetError("Couldn't get backbuffer");
	}
/*
	//get a lock on the surface
	r=pBackSurf->LockRect(&LockedRect, NULL, 0);
	if(FAILED(r)){
		SetError("Could not lock the back buffer");
	}

	DWORD* pData = (DWORD*)(LockedRect.pBits);
	//DRAW CODE GOES HERE - use pData
	Draw(LockedRect.Pitch, pData);

 */
	LPDIRECT3DSURFACE8 pSurface = 0;

	r=LoadBitmapToSurface("baboon.bmp",
		&pSurface, g_pDevice);
	if(FAILED(r)){
		SetError("could not load bitmap surface");
	}

	D3DSURFACE_DESC d3dsd;
	pSurface->GetDesc(&d3dsd);//get info about surface

	POINT DestPoint = {0, 0};
	RECT rect = {0,0, d3dsd.Width, d3dsd.Height};//source dimensions

//	SetError("size x=%d size y=%d format=%d",d3dsd.Width, d3dsd.Height, d3dsd.Format);

//	r=g_pDevice->CopyRects(pSurface, &rect, 1, pBackSurf, &DestPoint);//copy surface to buffer (like a bitblt)

	r=D3DXLoadSurfaceFromSurface(pBackSurf, NULL, NULL, pSurface, NULL, &rect, D3DX_FILTER_TRIANGLE,0);
//	r=D3DXLoadSurfaceFromSurface(pBackSurf, NULL, NULL, pSurface, NULL, &rect, D3DX_FILTER_POINT, 0);
	if(ERROR(r))
		SetError("did not copy surface");

//	SimpleBitmapDraw("baboon.bmp", pBackSurf, 10,10);
	pSurface->Release();
	pSurface = 0;

//	pBackSurf->UnlockRect();
//	pData = 0;

//	pBackSurf->Release();//release lock
//	pBackSurf = 0;

	g_pDevice->Present(NULL, NULL, NULL, NULL);//swap over buffer to primary surface
	return S_OK;
}
コード例 #5
0
void CApplicationRenderer::Process()
{
#ifndef HAS_SDL
  int iWidth = 0;
  int iHeight = 0;
  int iLeft = 0;
  int iTop = 0;
  LPDIRECT3DSURFACE8 lpSurfaceBack = NULL;
  LPDIRECT3DSURFACE8 lpSurfaceFront = NULL;
  while (!m_bStop)
  {
    if (!m_enabled || g_graphicsContext.IsFullScreenVideo())
    {
      Sleep(50);
      continue;
    }

    if (!m_pWindow || iWidth == 0 || iHeight == 0 || m_Resolution != g_graphicsContext.GetVideoResolution())
    {
      m_pWindow = (CGUIDialogBusy*)m_gWindowManager.GetWindow(WINDOW_DIALOG_BUSY);
      if (m_pWindow)
      {
        m_pWindow->Initialize();//need to load the window to determine size.
        if (m_pWindow->GetID() == WINDOW_INVALID)
        {
          //busywindow couldn't be loaded so stop this thread.
          m_pWindow = NULL;
          m_bStop = true;
          break;
        }

        SAFE_RELEASE(m_lpSurface);
        FRECT rect = m_pWindow->GetScaledBounds();
        m_pWindow->ClearAll(); //unload

        iLeft = (int)floor(rect.left);
        iTop =  (int)floor(rect.top);
        iWidth = (int)ceil(rect.right - rect.left);
        iHeight = (int)ceil(rect.bottom - rect.top);
        m_Resolution = g_graphicsContext.GetVideoResolution();
      }
    }

    float t0 = (1000.0f/g_graphicsContext.GetFPS());
    float t1 = m_time + t0; //time when we expect a new render
    float t2 = (float)timeGetTime();
    if (t1 < t2) //we're late rendering
    {
      try
      {
        if (timeGetTime() >= (m_time + g_advancedSettings.m_busyDialogDelay))
        {
          CSingleLock lockg (g_graphicsContext);
          if (m_prevbusycount != m_busycount)
          {
            Sleep(1);
            continue;
          }
          if (!m_pWindow || iWidth == 0 || iHeight == 0)
          {
            Sleep(1000);
            continue;
          }
          if (m_Resolution != g_graphicsContext.GetVideoResolution())
          {
            continue;
          }
          if (m_busycount > 0) m_busycount--;
          //no busy indicator if a progress dialog is showing
          if ((m_gWindowManager.HasModalDialog() && (m_gWindowManager.GetTopMostModalDialogID() != WINDOW_VIDEO_INFO) && (m_gWindowManager.GetTopMostModalDialogID() != WINDOW_MUSIC_INFO)) || (m_gWindowManager.GetTopMostModalDialogID() == WINDOW_DIALOG_PROGRESS))
          {
            //TODO: render progress dialog here instead of in dialog::Progress
            m_time = timeGetTime();
            lockg.Leave();
            Sleep(1);
            continue;
          }
          if (m_lpSurface == NULL)
          {
            D3DSURFACE_DESC desc;
            g_application.RenderNoPresent();
            HRESULT result = g_graphicsContext.Get3DDevice()->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &lpSurfaceFront);
            if (SUCCEEDED(result))
            {
              lpSurfaceFront->GetDesc( &desc );
              iLeft = 0;
              iTop = 0;
              iWidth = desc.Width;
              iHeight = desc.Height;
            }
            else
            {
              lockg.Leave();
              Sleep(1000);
              continue;
            }
            if (!SUCCEEDED(g_graphicsContext.Get3DDevice()->CreateImageSurface(iWidth, iHeight, desc.Format, &m_lpSurface)))
            {
              SAFE_RELEASE(lpSurfaceFront);
              lockg.Leave();
              Sleep(1000);
              continue;
            }
            //copy part underneeth busy dialog
            const RECT rc = { iLeft, iTop, iLeft + iWidth, iTop + iHeight  };
            const RECT rcDest = { 0, 0, iWidth, iHeight  };
            if (!CopySurface(lpSurfaceFront, &rc, m_lpSurface, &rcDest))
            {
                SAFE_RELEASE(lpSurfaceFront);
                SAFE_RELEASE(m_lpSurface);
                lockg.Leave();
                Sleep(1000);
                continue;
            }

            //copy front buffer to backbuffer(s) to avoid jumping
            bool bBufferCopied = true;
            for (int i = 0; i < g_graphicsContext.GetBackbufferCount(); i++)
            {
              if (!SUCCEEDED(g_graphicsContext.Get3DDevice()->GetBackBuffer( i, D3DBACKBUFFER_TYPE_MONO, &lpSurfaceBack)))
              {
                bBufferCopied = false;
                break;
              }
              if (!CopySurface(lpSurfaceFront, NULL, lpSurfaceBack, NULL))
              {
                bBufferCopied = false;
                break;
              }
              SAFE_RELEASE(lpSurfaceBack);
            }
            if (!bBufferCopied)
            {
              SAFE_RELEASE(lpSurfaceFront);
              SAFE_RELEASE(lpSurfaceBack);
              SAFE_RELEASE(m_lpSurface);
              lockg.Leave();
              Sleep(1000);
              continue;
            }
            SAFE_RELEASE(lpSurfaceFront);
          }
          if (!SUCCEEDED(g_graphicsContext.Get3DDevice()->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &lpSurfaceBack)))
          {
              lockg.Leave();
              Sleep(1000);
              continue;
          }
          g_graphicsContext.Get3DDevice()->BeginScene();
          //copy dialog background to backbuffer
          const RECT rc = { 0, 0, iWidth, iHeight };
          const RECT rcDest = { iLeft, iTop, iLeft + iWidth, iTop + iHeight };
          const D3DRECT rc2 = { iLeft, iTop, iLeft + iWidth, iTop + iHeight };
          g_graphicsContext.Get3DDevice()->Clear(1, &rc2, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00010001, 1.0f, 0L);
          if (!CopySurface(m_lpSurface, &rc, lpSurfaceBack, &rcDest))
          {
              SAFE_RELEASE(lpSurfaceBack);
              g_graphicsContext.Get3DDevice()->EndScene();
              lockg.Leave();
              Sleep(1000);
              continue;
          }
          SAFE_RELEASE(lpSurfaceBack);
          if (!m_busyShown)
          {
            m_pWindow->Show();
            m_busyShown = true;
          }
          m_pWindow->Render();

          g_graphicsContext.Get3DDevice()->EndScene();
          //D3DSWAPEFFECT_DISCARD is used so we can't just present the busy rect but can only present the entire screen.
          g_graphicsContext.Get3DDevice()->Present( NULL, NULL, NULL, NULL );
        }
        m_busycount++;
        m_prevbusycount = m_busycount;
      }
      catch (...)
      {
        CLog::Log(LOGERROR, __FUNCTION__" - Exception caught when  busy rendering");
        SAFE_RELEASE(lpSurfaceFront);
        SAFE_RELEASE(lpSurfaceBack);
        SAFE_RELEASE(m_lpSurface);
      }
    }
    Sleep(1);
  }
#endif
}
コード例 #6
0
ファイル: XBMCTex.cpp プロジェクト: Avoidnf8/xbmc-fork
// Converts to P8 format is colours <= 256
bool ConvertP8(LPDIRECT3DSURFACE8 pSrcSurf, LPDIRECT3DSURFACE8& pDstSurf, DWORD* pal, D3DXIMAGE_INFO &info)
{
	pDstSurf = 0;

	D3DSURFACE_DESC desc;
	pSrcSurf->GetDesc(&desc);

	// convert to p8
  UINT Width = PadPow2(desc.Width);
  UINT Height = PadPow2(desc.Height);
	HRESULT hr = pD3DDevice->CreateImageSurface(Width, Height, D3DFMT_A8R8G8B8, &pDstSurf);
	CheckHR(hr);

	D3DLOCKED_RECT slr, dlr;
	hr = pDstSurf->LockRect(&dlr, NULL, 0);
	CheckHR(hr);
	hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
	CheckHR(hr);

	DWORD* src = (DWORD*)slr.pBits;
	BYTE* dst = (BYTE*)dlr.pBits;
	int n = 0, i;
	for (UINT y = 0; y < info.Height; ++y)
	{
		for (UINT x = 0; x < info.Width; ++x)
		{
			for (i = 0; i < n; ++i)
			{
				if (pal[i] == *src)
					break;
			}
			if (i == n)
			{
				if (n >= 256)
				{
					TRACE0(" Too many colours for P8\n");
					pSrcSurf->UnlockRect();
					pDstSurf->UnlockRect();
					pDstSurf->Release();
					return false;
				}
				pal[n++] = *src;
			}
			*dst++ = i;
			++src;
		}
		for (UINT x = info.Width; x < Width; ++x)
		{
			*dst++ = 0; // we don't care about the colour outside of our real image
			++src;
    }
	}
  for (UINT y = info.Height; y < Height; ++y)
  {
		for (UINT x = 0; x < Width; ++x)
		{
			*dst++ = 0; // we don't care about the colour outside of our real image
			++src;
    }
  }
	TRACE1(" Colours Used: %d\n", n);

	pDstSurf->UnlockRect();
	pSrcSurf->UnlockRect();

	return true;
}
コード例 #7
0
ファイル: XBMCTex.cpp プロジェクト: Avoidnf8/xbmc-fork
void AppendXPRImage(const D3DXIMAGE_INFO& info, LPDIRECT3DSURFACE8 pSrcSurf, XB_D3DFORMAT fmt)
{
	D3DSURFACE_DESC desc;
	pSrcSurf->GetDesc(&desc);

	HRESULT hr;
	UINT Pitch;
	UINT Size;

	if (fmt == XB_D3DFMT_DXT1 || fmt == XB_D3DFMT_DXT3 || fmt == XB_D3DFMT_DXT5)
	{
		if (fmt == XB_D3DFMT_DXT1)
			Pitch = desc.Width / 2;
		else
			Pitch = desc.Width;
		Size = ((Pitch * desc.Height) + 127) & ~127; // must be 128-byte aligned for any following images
		Pitch *= 4;

		VirtualAlloc(XPRFile.Data, Size, MEM_COMMIT, PAGE_READWRITE);

		D3DLOCKED_RECT slr;
		hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
		if (FAILED(hr))
		{
			printf("ERROR: %08x\n", hr);
			return;
		}

    hr = CompressRect(XPRFile.Data, fmt, Pitch, desc.Width, desc.Height, slr.pBits, XB_D3DFMT_LIN_A8R8G8B8, slr.Pitch, 0.5f, 0);
    if (FAILED(hr))
		{
			printf("ERROR: %08x\n", hr);
			return;
		}

		pSrcSurf->UnlockRect();
	}
	else
	{
		UINT bpp = BytesPerPixelFromFormat(fmt);
		Pitch = desc.Width * bpp;
		Size = ((Pitch * desc.Height) + 127) & ~127; // must be 128-byte aligned for any following images

		VirtualAlloc(XPRFile.Data, Size, MEM_COMMIT, PAGE_READWRITE);

		D3DLOCKED_RECT slr;
		hr = pSrcSurf->LockRect(&slr, NULL, D3DLOCK_READONLY);
		if (FAILED(hr))
		{
			printf("ERROR: %08x\n", hr);
			return;
		}

		if (IsSwizzledFormat(fmt))
		{
			// Swizzle for xbox
			SwizzleRect(slr.pBits, 0, NULL, XPRFile.Data, desc.Width, desc.Height, NULL, bpp);
		}
		else
		{
			// copy
			BYTE* src = (BYTE*)slr.pBits;
			BYTE* dst = (BYTE*)XPRFile.Data;
			for (UINT y = 0; y < desc.Height; ++y)
			{
				memcpy(dst, src, desc.Width * bpp);
				src += slr.Pitch;
				dst += Pitch;
			}
		}

		pSrcSurf->UnlockRect();
	}

	SetTextureHeader(desc.Width, desc.Height, 1, 0, fmt, D3DPOOL_DEFAULT, 
		&XPRFile.Texture[XPRFile.nImages].D3DTex, XPRFile.Data - XPRFile.DataStart, Pitch);
	if (!(*XPRFile.flags & XPRFLAG_ANIM))
		XPRFile.Texture[XPRFile.nImages].RealSize = (info.Width & 0xffff) | ((info.Height & 0xffff) << 16);
	++XPRFile.nImages;

	XPRFile.Data += Size;
	CompressedSize += Size;
}
コード例 #8
0
ファイル: xbutil.cpp プロジェクト: dpaladin/openbor
//-----------------------------------------------------------------------------
// Name: XBUtil_DumpSurface()
// Desc: Writes the contents of a surface (32-bit only) to a .tga file. This
//       could be a backbuffer, texture, or any other 32-bit surface.
//-----------------------------------------------------------------------------
HRESULT XBUtil_DumpSurface( LPDIRECT3DSURFACE8 pSurface, const CHAR* strFileName,
                            BOOL bSurfaceIsTiled )
{
    // Get the surface description. Make sure it's a 32-bit format
    D3DSURFACE_DESC desc;
    pSurface->GetDesc( &desc );
    if( desc.Size != ( desc.Width * desc.Height * sizeof(DWORD) ) )
        return E_NOTIMPL;

    // Lock the surface
    D3DLOCKED_RECT lock;
    if( FAILED( pSurface->LockRect( &lock, 0, bSurfaceIsTiled ? D3DLOCK_TILED : 0 ) ) )
        return E_FAIL;

    // Allocate memory for storing the surface bits
    VOID* pBits = (VOID*)new DWORD[desc.Width*desc.Height];

    // Unswizzle the bits, if necessary
    if( XGIsSwizzledFormat( desc.Format ) )
        XGUnswizzleRect( lock.pBits, desc.Width, desc.Height, NULL,
                         pBits, lock.Pitch, NULL, sizeof(DWORD) );
    else
        memcpy( pBits, lock.pBits, desc.Size );
    
    // Unlock the surface
    pSurface->UnlockRect();

    // Setup the TGA file header
    struct TargaHeader
    {
        BYTE IDLength;
        BYTE ColormapType;
        BYTE ImageType;
        BYTE ColormapSpecification[5];
        WORD XOrigin;
        WORD YOrigin;
        WORD ImageWidth;
        WORD ImageHeight;
        BYTE PixelDepth;
        BYTE ImageDescriptor;
    } tgaHeader;

    ZeroMemory( &tgaHeader, sizeof(tgaHeader) );
    tgaHeader.IDLength        = 0;
    tgaHeader.ImageType       = 2;
    tgaHeader.ImageWidth      = (WORD)desc.Width;
    tgaHeader.ImageHeight     = (WORD)desc.Height;
    tgaHeader.PixelDepth      = 32;
    tgaHeader.ImageDescriptor = 0x28;

    // Create a new file
    FILE* file = fopen( strFileName, "wb" );
    if( NULL == file )
    {
        pSurface->UnlockRect();
        return E_FAIL;
    }

    // Write the Targa header and the surface pixels to the file
    fwrite( &tgaHeader, sizeof(TargaHeader), 1, file );
    fwrite( pBits, sizeof(BYTE), desc.Size, file );
    fclose( file );

    // Cleanup and return
    delete[] pBits;

    return S_OK;
}
コード例 #9
0
ファイル: CWaterApp.cpp プロジェクト: grakidov/Render3D
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    HRESULT hr;

    // Restore the font
    m_pFont->RestoreDeviceObjects();
    m_pFontSmall->RestoreDeviceObjects();

    // Create light
    D3DLIGHT8 light;
    ZeroMemory(&light, sizeof(light));

    light.Type        = D3DLIGHT_DIRECTIONAL;
    light.Diffuse.r   = m_colorLight.r;
    light.Diffuse.g   = m_colorLight.g;
    light.Diffuse.b   = m_colorLight.b;
    light.Diffuse.a   = m_colorLight.a;
    light.Specular.r  = 1.0f;
    light.Specular.g  = 1.0f;
    light.Specular.b  = 1.0f;
    light.Specular.a  = 0.0f;
    light.Direction.x = m_vecLight.x;
    light.Direction.y = m_vecLight.y;
    light.Direction.z = m_vecLight.z;

    m_pd3dDevice->SetLight(0, &light);
    m_pd3dDevice->LightEnable(0, TRUE);


    // Create material
    D3DMATERIAL8 material;
    ZeroMemory(&material, sizeof(material));

    material.Diffuse.a  = 1.0f;
    material.Specular.r = 0.5f;
    material.Specular.g = 0.5f;
    material.Specular.b = 0.5f;
    material.Power      = 20.0f;

    m_pd3dDevice->SetMaterial(&material);

    // Setup render states
    m_pd3dDevice->SetVertexShader(D3DFVF_XYZ);

    m_pd3dDevice->SetTransform(D3DTS_VIEW,  &m_matView);
    m_pd3dDevice->SetTransform(D3DTS_WORLD, &m_matIdentity);

    m_pd3dDevice->SetRenderState(D3DRS_LIGHTING,       FALSE);
    m_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);

    m_pd3dDevice->SetRenderState(D3DRS_ZFUNC,     D3DCMP_LESSEQUAL);
    m_pd3dDevice->SetRenderState(D3DRS_CULLMODE,  D3DCULL_CW);
    m_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
    m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ONE);
    m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

    m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_DISABLE);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_DISABLE);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
    m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);

    m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP,   D3DTOP_DISABLE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
    m_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);




    // Create caustic texture
    D3DDISPLAYMODE mode;
    m_pd3dDevice->GetDisplayMode(&mode);

    if(FAILED(hr = D3DXCreateTexture(m_pd3dDevice, WATER_CAUSTICS_SIZE, WATER_CAUSTICS_SIZE, 1, D3DUSAGE_RENDERTARGET, mode.Format, D3DPOOL_DEFAULT, &m_pCausticTex)) &&
       FAILED(hr = D3DXCreateTexture(m_pd3dDevice, WATER_CAUSTICS_SIZE, WATER_CAUSTICS_SIZE, 1, 0, mode.Format, D3DPOOL_DEFAULT, &m_pCausticTex)))
    {
        return hr;
    }

    D3DSURFACE_DESC desc;
    m_pCausticTex->GetSurfaceLevel(0, &m_pCausticSurf);
    m_pCausticSurf->GetDesc(&desc);

    if(FAILED(hr = D3DXCreateRenderToSurface(m_pd3dDevice, desc.Width, desc.Height, 
        desc.Format, FALSE, D3DFMT_UNKNOWN, &m_pRenderToSurface)))
    {
        return hr;
    }



    // Shader
    TCHAR sz[512];
    DXUtil_FindMediaFile(sz, _T("water.sha"));

    if(FAILED(hr = D3DXCreateEffectFromFile(m_pd3dDevice, sz, &m_pEffect, NULL)))
        return hr;

    m_pEffect->SetMatrix("mID",  &m_matIdentity);
    m_pEffect->SetMatrix("mENV", &m_matIdentity);

    m_pEffect->SetTexture("tFLR", m_pFloorTex);
    m_pEffect->SetTexture("tCAU", m_pCausticTex);
    m_pEffect->SetTexture("tENV", m_pSkyCubeTex);

    if(FAILED(hr = GetNextTechnique(0, FALSE)))
        return hr;


    // Set surfaces
    if(FAILED(hr = m_Environment.SetSurfaces(
        m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_X], m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_X], 
        m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_Y], m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_Y],
        m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_Z], m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_Z])))
    {
        return hr;
    }


    // OnResetDevice
    if(FAILED(hr = m_Water.OnResetDevice()))
        return hr;

    if(FAILED(hr = m_Environment.OnResetDevice()))
        return hr;

    return S_OK;
}
コード例 #10
0
// read depth buffer and update visibility flag of depth points
static void UpdateDepthPointsVisibility( const CDrawPort *pdp, const INDEX iMirrorLevel,
                                         DepthInfo *pdi, const INDEX ctCount)
{
  const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  ASSERT(GfxValidApi(eAPI));
  ASSERT( pdp!=NULL && ctCount>0);
  const CRaster *pra = pdp->dp_Raster;

  // OpenGL
  if( eAPI==GAT_OGL)
  { 
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    FLOAT fPointOoK;
    // for each stored point
    for( INDEX idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      // skip if not in required mirror level or was already checked in this iteration
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest) continue;
      const PIX pixJ = pra->ra_Height-1 - di.di_pixJ; // OpenGL has Y-inversed buffer!
      pglReadPixels( di.di_pixI, pixJ, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fPointOoK);
      OGL_CHECKERROR;
      // it is visible if there is nothing nearer in z-buffer already
      di.di_bVisible = (di.di_fOoK<fPointOoK);
    }
    // done
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    return;
  }

  // Direct3D
#ifdef SE1_D3D
  if( eAPI==GAT_D3D)
  {
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    // ok, this will get really complicated ...
    // We'll have to do it thru back buffer because darn DX8 won't let us have values from z-buffer;
    // Anyway, we'll lock backbuffer, read color from the lens location and try to write little triangle there
    // with slightly modified color. Then we'll readout that color and see if triangle passes z-test. Voila! :)
    // P.S. To avoid lock-modify-lock, we need to batch all the locks in one. Uhhhh ... :(
    COLOR col;
    INDEX idi;
    SLONG slColSize;
    HRESULT hr;
    D3DLOCKED_RECT rectLocked;
    D3DSURFACE_DESC surfDesc;
    LPDIRECT3DSURFACE8 pBackBuffer;
    // fetch back buffer (different for full screen and windowed mode)
    const BOOL bFullScreen = _pGfx->gl_ulFlags & GLF_FULLSCREEN;
    if( bFullScreen) {
      hr = _pGfx->gl_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    } else {
      hr = pra->ra_pvpViewPort->vp_pSwapChain->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    }
    // what, cannot get a back buffer?
    if( hr!=D3D_OK) { 
      // to hell with it all
      _sfStats.StopTimer(CStatForm::STI_GFXAPI);
      return;
    }
    // keep format of back-buffer
    pBackBuffer->GetDesc(&surfDesc);
    const D3DFORMAT d3dfBack = surfDesc.Format;
    
    // prepare array that'll back-buffer colors from depth point locations
    _acolDelayed.Push(ctCount);
    // store all colors
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      // skip if not in required mirror level or was already checked in this iteration
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest) continue;
      // fetch pixel
      _acolDelayed[idi] = 0;
      const RECT rectToLock = { di.di_pixI, di.di_pixJ, di.di_pixI+1, di.di_pixJ+1 };
      hr = pBackBuffer->LockRect( &rectLocked, &rectToLock, D3DLOCK_READONLY);
      if( hr!=D3D_OK) continue; // skip if lock didn't make it
      // read, convert and store original color
      _acolDelayed[idi] = UnpackColor_D3D( (UBYTE*)rectLocked.pBits, d3dfBack, slColSize) | CT_OPAQUE;
      pBackBuffer->UnlockRect();
    }

    // prepare to draw little triangles there with slightly adjusted colors
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    gfxEnableDepthTest();
    gfxDisableDepthWrite();
    gfxDisableBlend();
    gfxDisableAlphaTest();
    gfxDisableTexture();
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    // prepare array and shader
    _avtxDelayed.Push(ctCount*3);
    d3dSetVertexShader(D3DFVF_CTVERTEX);

    // draw one trianle around each depth point
    INDEX ctVertex = 0;
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      col = _acolDelayed[idi];
      // skip if not in required mirror level or was already checked in this iteration, or wasn't fetched at all
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest || col==0) continue;
      const ULONG d3dCol = rgba2argb(col^0x20103000);
      const PIX pixI = di.di_pixI - pdp->dp_MinI; // convert raster loc to drawport loc
      const PIX pixJ = di.di_pixJ - pdp->dp_MinJ;
      // batch it and advance to next triangle
      CTVERTEX &vtx0 = _avtxDelayed[ctVertex++];
      CTVERTEX &vtx1 = _avtxDelayed[ctVertex++];
      CTVERTEX &vtx2 = _avtxDelayed[ctVertex++];
      vtx0.fX=pixI;   vtx0.fY=pixJ-2; vtx0.fZ=di.di_fOoK; vtx0.ulColor=d3dCol; vtx0.fU=vtx0.fV=0;
      vtx1.fX=pixI-2; vtx1.fY=pixJ+2; vtx1.fZ=di.di_fOoK; vtx1.ulColor=d3dCol; vtx1.fU=vtx0.fV=0;
      vtx2.fX=pixI+2; vtx2.fY=pixJ;   vtx2.fZ=di.di_fOoK; vtx2.ulColor=d3dCol; vtx2.fU=vtx0.fV=0;
    }
    // draw a bunch
    hr = _pGfx->gl_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, ctVertex/3, &_avtxDelayed[0], sizeof(CTVERTEX));
    D3D_CHECKERROR(hr);

    // readout colors again and compare to old ones
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      col = _acolDelayed[idi];
      // skip if not in required mirror level or was already checked in this iteration, or wasn't fetched at all
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest || col==0) continue;
      // fetch pixel
      const RECT rectToLock = { di.di_pixI, di.di_pixJ, di.di_pixI+1, di.di_pixJ+1 };
      hr = pBackBuffer->LockRect( &rectLocked, &rectToLock, D3DLOCK_READONLY);
      if( hr!=D3D_OK) continue; // skip if lock didn't make it
      // read new color
      const COLOR colNew = UnpackColor_D3D( (UBYTE*)rectLocked.pBits, d3dfBack, slColSize) | CT_OPAQUE;
      pBackBuffer->UnlockRect();
      // if we managed to write adjusted color, point is visible!
      di.di_bVisible = (col!=colNew);
    }
    // phew, done! :)
    D3DRELEASE( pBackBuffer, TRUE);
    _acolDelayed.PopAll();
    _avtxDelayed.PopAll();
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    return;
  }
#endif // SE1_D3D
}