mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
implement copy_texture
This commit is contained in:
parent
e9857b36b9
commit
72e396f06d
@ -397,7 +397,7 @@ read_vertex_shader(string &filename) {
|
|||||||
hr = scrn.pD3DDevice->CreateVertexShader((DWORD*)ShaderDeclHeader,
|
hr = scrn.pD3DDevice->CreateVertexShader((DWORD*)ShaderDeclHeader,
|
||||||
(DWORD*) ((pD3DXBuf_CompiledShader!=NULL) ? pD3DXBuf_CompiledShader->GetBufferPointer() : pShaderBytes),
|
(DWORD*) ((pD3DXBuf_CompiledShader!=NULL) ? pD3DXBuf_CompiledShader->GetBufferPointer() : pShaderBytes),
|
||||||
&hShader, UsageFlags);
|
&hShader, UsageFlags);
|
||||||
if (FAILED(hr)) {
|
if(FAILED(hr)) {
|
||||||
dxgsg_cat.error() << "CreateVertexShader failed for '"<< filename << "' " << D3DERRORSTRING(hr);
|
dxgsg_cat.error() << "CreateVertexShader failed for '"<< filename << "' " << D3DERRORSTRING(hr);
|
||||||
hShader=NULL;
|
hShader=NULL;
|
||||||
}
|
}
|
||||||
@ -3237,68 +3237,50 @@ release_texture(TextureContext *tc) {
|
|||||||
delete gtc;
|
delete gtc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
// copies current display region in framebuffer to the texture
|
||||||
|
|
||||||
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
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void DXGraphicsStateGuardian::
|
void DXGraphicsStateGuardian::
|
||||||
copy_texture(TextureContext *tc, const DisplayRegion *dr) {
|
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
|
IDirect3DSurface8 *pTexSurfaceLev0,*pCurRenderTarget;
|
||||||
// If the requested region is not a power of two, grab a region that is
|
hr = dtc->_pD3DTexture8->GetSurfaceLevel(0,&pTexSurfaceLev0);
|
||||||
// a power of two that contains the requested region
|
if(FAILED(hr)) {
|
||||||
int xo, yo, req_w, req_h;
|
dxgsg_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr);
|
||||||
dr->get_region_pixels(xo, yo, req_w, req_h);
|
exit(1);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
PixelBuffer *pb = tex->_pbuffer;
|
hr = scrn.pD3DDevice->GetRenderTarget(&pCurRenderTarget);
|
||||||
|
if(FAILED(hr)) {
|
||||||
pb->set_xorg(xo);
|
dxgsg_cat.error() << "GetRenderTgt failed in copy_texture" << D3DERRORSTRING(hr);
|
||||||
pb->set_yorg(yo);
|
exit(1);
|
||||||
pb->set_xsize(w);
|
}
|
||||||
pb->set_ysize(h);
|
|
||||||
|
|
||||||
|
|
||||||
bind_texture(tc);
|
RECT SrcRect;
|
||||||
glCopyTexImage2D( GL_TEXTURE_2D, tex->get_level(),
|
|
||||||
get_internal_image_format(pb->get_format()),
|
SrcRect.left = xo;
|
||||||
pb->get_xorg(), pb->get_yorg(),
|
SrcRect.right = xo+w;
|
||||||
pb->get_xsize(), pb->get_ysize(), pb->get_border() );
|
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
|
// Function: DXGraphicsStateGuardian::copy_texture
|
||||||
|
@ -1530,248 +1530,6 @@ FillDDSurfTexturePixels(void) {
|
|||||||
}
|
}
|
||||||
RELEASE(pMipLevel0,dxgsg,"texture",RELEASE_ONCE);
|
RELEASE(pMipLevel0,dxgsg,"texture",RELEASE_ONCE);
|
||||||
return hr;
|
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<ddsd.dwMipMapCount;i++) {
|
|
||||||
oldcurxsize=curxsize; oldcurysize=curysize;
|
|
||||||
curysize = max(curysize>>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; y<curysize; y++,pSrcLineStart+=two_src_row_bytelength) {
|
|
||||||
pSrcWord=pSrcLineStart;
|
|
||||||
for(x=0; x<curxsize; x++,pSrcWord+=x_srcptr_inc,pDstWord+=cPixelSize) {
|
|
||||||
// fetches, stores byte at a time.
|
|
||||||
// inefficient, but works for all channel sizes
|
|
||||||
|
|
||||||
for(int c=0;c<cPixelSize;c++) {
|
|
||||||
DWORD colr;
|
|
||||||
colr = *(pSrcWord+c);
|
|
||||||
if(oldcurxsize>1) // 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: "<<msg<<"\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
res = StretchBlt(hScreenDC,curx,ddsd_cur.dwHeight+cury,ddsd_cur.dwWidth,-((int)ddsd_cur.dwHeight), hTexDC,0,0,ddsd_cur.dwWidth,ddsd_cur.dwHeight,SRCCOPY);
|
|
||||||
if(!res) {
|
|
||||||
PrintLastError(msg);
|
|
||||||
dxgsg_cat.error() << "StretchBLT failed: "<<msg<<"\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// SetBkMode(hScreenDC, TRANSPARENT);
|
|
||||||
sprintf(msg,"%d",i);
|
|
||||||
TextOut(hScreenDC,curx+(ddsd_cur.dwWidth)/2,5+cury+ddsd_cur.dwHeight,msg,strlen(msg));
|
|
||||||
|
|
||||||
curx+=max(20,ddsd_cur.dwWidth+10);
|
|
||||||
|
|
||||||
if(curx>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 "<<i<<" hr = " << D3DERRORSTRING(hr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i==ddsd.dwMipMapCount-1) {
|
|
||||||
pTexturePrev->Release();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DDSCAPS2 ddsCaps;
|
|
||||||
ZeroMemory(&ddsCaps,sizeof(DDSCAPS2));
|
|
||||||
ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
|
|
||||||
ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
|
|
||||||
hr = pTexturePrev->GetAttachedSurface(&ddsCaps, &pTextureCurrent);
|
|
||||||
if(FAILED(hr)) {
|
|
||||||
dxgsg_cat.error() << " failed displaying mipmaps: GetAttachedSurf hr = " << D3DERRORSTRING(hr);
|
|
||||||
}
|
|
||||||
// done with the previous texture
|
|
||||||
pTexturePrev->Release();
|
|
||||||
pTexturePrev = pTextureCurrent;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseDC(0,hScreenDC);
|
|
||||||
|
|
||||||
HANDLE hArr[1];
|
|
||||||
MSG winmsg;
|
|
||||||
hArr[0]=GetStdHandle(STD_INPUT_HANDLE);
|
|
||||||
GetMessage(&winmsg,NULL,0,0);
|
|
||||||
|
|
||||||
int val=MsgWaitForMultipleObjects(1,hArr,TRUE,INFINITE,QS_KEY);
|
|
||||||
if(val==-1) {
|
|
||||||
PrintLastError(msg);
|
|
||||||
dxgsg_cat.error() << " MsgWaitForMultipleObjects returns " << val << " " <<msg << endl;
|
|
||||||
} else {
|
|
||||||
dxgsg_cat.error() << " MsgWaitForMultipleObjects returns " << val << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user