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,
|
||||
(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
|
||||
|
@ -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<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