From 72e396f06dfa08bcdcc4bed80cce08433b3d0f28 Mon Sep 17 00:00:00 2001 From: cxgeorge <> Date: Thu, 12 Sep 2002 23:39:29 +0000 Subject: [PATCH] implement copy_texture --- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 90 +++---- panda/src/dxgsg8/dxTextureContext8.cxx | 242 ------------------ 2 files changed, 36 insertions(+), 296 deletions(-) diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index f354ebf124..71c7dc786b 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -397,7 +397,7 @@ read_vertex_shader(string &filename) { hr = scrn.pD3DDevice->CreateVertexShader((DWORD*)ShaderDeclHeader, (DWORD*) ((pD3DXBuf_CompiledShader!=NULL) ? pD3DXBuf_CompiledShader->GetBufferPointer() : pShaderBytes), &hShader, UsageFlags); - if (FAILED(hr)) { + if(FAILED(hr)) { dxgsg_cat.error() << "CreateVertexShader failed for '"<< filename << "' " << D3DERRORSTRING(hr); hShader=NULL; } @@ -3237,68 +3237,50 @@ release_texture(TextureContext *tc) { delete gtc; } -#if 1 - -void DXGraphicsStateGuardian:: -copy_texture(TextureContext *tc, const DisplayRegion *dr) { - dxgsg_cat.fatal() << "DX copy_texture unimplemented!!!"; -} - -#else -static int logs[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, - 4096, 0}; - -// This function returns the smallest power of two greater than or -// equal to x. -static int binary_log_cap(const int x) { - int i = 0; - for (; (x > logs[i]) && (logs[i] != 0); ++i); - if (logs[i] == 0) - return 4096; - return logs[i]; -} - -//////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian::copy_texture -// Access: Public, Virtual -// Description: Copy the pixel region indicated by the display -// region from the framebuffer into texture memory -//////////////////////////////////////////////////////////////////// +// copies current display region in framebuffer to the texture void DXGraphicsStateGuardian:: copy_texture(TextureContext *tc, const DisplayRegion *dr) { - nassertv(tc != NULL && dr != NULL); + HRESULT hr; + int xo, yo, w, h; + dr->get_region_pixels(xo, yo, w, h); - Texture *tex = tc->_texture; + DXTextureContext *dtc = DCAST(DXTextureContext, tc); + PixelBuffer *pb = dtc->_tex->_pbuffer; + pb->set_size(0,0,w-xo,h-yo); - // Determine the size of the grab from the given display region - // If the requested region is not a power of two, grab a region that is - // a power of two that contains the requested region - int xo, yo, req_w, req_h; - dr->get_region_pixels(xo, yo, req_w, req_h); - int w = binary_log_cap(req_w); - int h = binary_log_cap(req_h); - if (w != req_w || h != req_h) { - tex->_requested_w = req_w; - tex->_requested_h = req_h; - tex->_has_requested_size = true; - } + IDirect3DSurface8 *pTexSurfaceLev0,*pCurRenderTarget; + hr = dtc->_pD3DTexture8->GetSurfaceLevel(0,&pTexSurfaceLev0); + if(FAILED(hr)) { + dxgsg_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr); + exit(1); + } - PixelBuffer *pb = tex->_pbuffer; - - pb->set_xorg(xo); - pb->set_yorg(yo); - pb->set_xsize(w); - pb->set_ysize(h); + hr = scrn.pD3DDevice->GetRenderTarget(&pCurRenderTarget); + if(FAILED(hr)) { + dxgsg_cat.error() << "GetRenderTgt failed in copy_texture" << D3DERRORSTRING(hr); + exit(1); + } - bind_texture(tc); - glCopyTexImage2D( GL_TEXTURE_2D, tex->get_level(), - get_internal_image_format(pb->get_format()), - pb->get_xorg(), pb->get_yorg(), - pb->get_xsize(), pb->get_ysize(), pb->get_border() ); + RECT SrcRect; + + SrcRect.left = xo; + SrcRect.right = xo+w; + SrcRect.top = yo; + SrcRect.bottom = yo+h; + + // now copy from fb to tex + hr = scrn.pD3DDevice->CopyRects(pCurRenderTarget,&SrcRect,1,pTexSurfaceLev0,NULL); + if(FAILED(hr)) { + dxgsg_cat.error() << "CopyRects failed in copy_texture" << D3DERRORSTRING(hr); + exit(1); + } + + SAFE_RELEASE(pCurRenderTarget); + SAFE_RELEASE(pTexSurfaceLev0); } -#endif + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian::copy_texture diff --git a/panda/src/dxgsg8/dxTextureContext8.cxx b/panda/src/dxgsg8/dxTextureContext8.cxx index e5de994f4f..f95a0ce557 100644 --- a/panda/src/dxgsg8/dxTextureContext8.cxx +++ b/panda/src/dxgsg8/dxTextureContext8.cxx @@ -1530,248 +1530,6 @@ FillDDSurfTexturePixels(void) { } RELEASE(pMipLevel0,dxgsg,"texture",RELEASE_ONCE); return hr; - -/* old, custom conversion and mipmap-generation stuff - - - HRESULT hr = ConvertPixBuftoDDSurf((ConversionType)_PixBufConversionType,pbuf->_image.p(),_surface); - if(FAILED(hr)) { - return hr; - } - - DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd); - - _surface->GetSurfaceDesc(&ddsd); - - if(_bHasMipMaps) { - DWORD i,oldcurxsize,oldcurysize,curxsize,curysize,cMipMapCount=ddsd.dwMipMapCount; - assert(ddsd.dwMipMapCount<20); - - DWORD cNumColorChannels = pbuf->get_num_components(); - - curxsize=ddsd.dwWidth; curysize=ddsd.dwHeight; - - assert(pbuf->get_image_type()==PixelBuffer::T_unsigned_byte); // cant handle anything else now - - // all mipmap sublevels require 1/3 of total original space. alloc 1/2 for safety - BYTE *pMipMapPixBufSpace = new BYTE[((curxsize*curysize*cNumColorChannels)/2)+1024]; - - LPDIRECTDRAWSURFACE7 pCurDDSurf=_surface; - pCurDDSurf->AddRef(); // so final release doesnt release the surface - - BYTE *pDstWord = pMipMapPixBufSpace; - BYTE *pLastMipLevelStart = (BYTE *) pbuf->_image.p(); -// clock_t start1,finish1; -// start1=clock(); - for(i=1;i>1,1); - curxsize = max(curxsize>>1,1); - - assert(!((oldcurxsize==1)&&(oldcurysize==1))); - - BYTE *pSrcWord; - BYTE *pSrcLineStart=pLastMipLevelStart; - - // inc img start to DWORD boundary - while(((DWORD)pDstWord) & 0x11) - pDstWord++; - - pLastMipLevelStart = pDstWord; - - DWORD x,y,cPixelSize=cNumColorChannels; - DWORD src_row_bytelength=oldcurxsize*cPixelSize; - DWORD two_src_row_bytelength=2*src_row_bytelength; - - #define GENMIPMAP_DO_INTEGER_DIV // should be a little faster, but no rounding up - #ifdef GENMIPMAP_DO_INTEGER_DIV - DWORD DivShift=2; - if((oldcurxsize==1)||(oldcurysize==1)) - DivShift = 1; - #else - float numpixels_per_filter=4.0f; - if((oldcurxsize==1)||(oldcurysize==1)) - numpixels_per_filter=2.0f; - #endif - - DWORD x_srcptr_inc = ((oldcurxsize==1)? cPixelSize: (2*cPixelSize)); - - // box-filter shrink down, avg 4 pixels at a time - for(y=0; y1) // handle 1x[X], [X]x1 cases - colr += *(pSrcWord+cPixelSize+c); - if(oldcurysize>1) { - colr += *(pSrcWord+src_row_bytelength+c); - if(oldcurxsize>1) - colr += *(pSrcWord+src_row_bytelength+cPixelSize+c); - } - #ifdef GENMIPMAP_DO_INTEGER_DIV - colr >>= DivShift; - #else - colr = (DWORD) ((((float)colr)/numpixels_per_filter)+0.5f); - #endif - - *(pDstWord+c)=(BYTE)colr; - } - } - } - - // now copy pixbuf to final DD surf - - DDSCAPS2 ddsCaps; - LPDIRECTDRAWSURFACE7 pMipLevel_DDSurf; - ZeroMemory(&ddsCaps,sizeof(DDSCAPS2)); - ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP; - ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL; - - hr = pCurDDSurf->GetAttachedSurface(&ddsCaps, &pMipLevel_DDSurf); - if(FAILED(hr)) { - dxgsg_cat.error() << "CreateTexture failed creating mipmaps: GetAttachedSurf hr = " << D3DERRORSTRING(hr); - delete [] pMipMapPixBufSpace; - pCurDDSurf->Release(); - return hr; - } - - hr = ConvertPixBuftoDDSurf((ConversionType)_PixBufConversionType,pLastMipLevelStart,pMipLevel_DDSurf); - if(FAILED(hr)) { - delete [] pMipMapPixBufSpace; - pCurDDSurf->Release(); - return hr; - } - - pCurDDSurf->Release(); - pCurDDSurf=pMipLevel_DDSurf; - } - - // finish1=clock(); - // double elapsed_time = (double)(finish1 - start1) / CLOCKS_PER_SEC; - // cerr << "mipmap gen takes " << elapsed_time << " secs for this texture\n"; - - delete [] pMipMapPixBufSpace; - pCurDDSurf->Release(); - -#ifdef _DEBUG - if(dx_debug_view_mipmaps) { -#if 0 - if(!(ddcaps.dwCaps & DDCAPS_BLTSTRETCH)) { - dxgsg_cat.error() << "CreateTexture failed debug-viewing mipmaps, BLT stretching not supported! ( we need to do SW stretch) \n"; - return hr; - } -#endif - - // display mipmaps on primary surf - HDC hTexDC; - LPDIRECTDRAWSURFACE7 pTextureCurrent,pTexturePrev = _surface; - int cury,curx; - HDC hScreenDC; - RECT scrnrect; - hScreenDC=GetDC(NULL); - - scrnrect.left=scrnrect.top=0; - scrnrect.bottom=GetDeviceCaps(hScreenDC,VERTRES); - scrnrect.right=GetDeviceCaps(hScreenDC,HORZRES); - char msg[500]; - - pTexturePrev->AddRef(); - - for(i = 0,curx=scrnrect.left,cury=scrnrect.top; i < ddsd.dwMipMapCount; i++) { - - DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd_cur); - pTexturePrev->GetSurfaceDesc(&ddsd_cur); - - hr = pTexturePrev->GetDC(&hTexDC); - if(FAILED(hr)) { - dxgsg_cat.error() << "GetDC failed hr = " << D3DERRORSTRING(hr); - break; - } - - BOOL res; - // res = BitBlt(_dxgsg->_hdc,0,0,ddsd.dwWidth,ddsd.dwHeight, TexDC,0,0,SRCCOPY); - // loader inverts y, so use StretchBlt to re-invert it - // res = StretchBlt(_dxgsg->hdc,0,ddsd_cur.dwHeight+cury,ddsd_cur.dwWidth,-ddsd_cur.dwHeight, TexDC,0,0,ddsd_cur.dwWidth,ddsd_cur.dwHeight,SRCCOPY); -#if 0 - if(cNumAlphaBits>0) { - BLENDFUNCTION bf; - bf.BlendOp = AC_SRC_OVER; bf.BlendFlags=0; - bf.SourceConstantAlpha=255; bf.AlphaFormat=AC_SRC_ALPHA; - res = AlphaBlend(hScreenDC,curx,cury,ddsd_cur.dwWidth,ddsd_cur.dwHeight, TexDC,0,0,ddsd_cur.dwWidth,ddsd_cur.dwHeight,bf); - if(!res) { - PrintLastError(msg); - dxgsg_cat.error() << "AlphaBlend BLT failed: "<scrnrect.right) { - curx=0; cury+=(scrnrect.bottom-scrnrect.top)/2; - } - - hr = pTexturePrev->ReleaseDC(hTexDC); - - if(FAILED(hr)) { - dxgsg_cat.error() << "tex ReleaseDC failed for mip "<