diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 3ab9701cfb..c7854ff1b4 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -566,8 +566,7 @@ end_frame() { nassertv(has_texture()); DisplayRegion dr(this, _x_size, _y_size); RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type()); - TextureContext *tc = get_texture()->prepare_now(_gsg->get_prepared_objects(), _gsg); - _gsg->copy_texture(tc, &dr, buffer); + _gsg->copy_texture(get_texture(), &dr, buffer); } // If we're not single-buffered, we're now ready to flip. diff --git a/panda/src/distort/projectionScreen.cxx b/panda/src/distort/projectionScreen.cxx index 52a6d3fe0d..fc27fb5fed 100644 --- a/panda/src/distort/projectionScreen.cxx +++ b/panda/src/distort/projectionScreen.cxx @@ -677,6 +677,10 @@ make_mesh_geom(Geom *geom, Lens *lens, LMatrix4f &rel_mat) { // dimensions so the Z coordinate remains meaningful. LPoint3f film(0.0f, 0.0f, 0.0f); lens->project(vert * rel_mat, film); + + // This might be necessary to compensate for DX's weird near plane + // definition. Investigate further later. + //film[2] = ((film[2] + 1.0f) / 2.0f); new_coords.push_back(film); } diff --git a/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx b/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx index b49e3e4a47..d30e0586bf 100644 --- a/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx +++ b/panda/src/dxgsg7/dxGraphicsStateGuardian7.cxx @@ -3490,81 +3490,19 @@ release_texture(TextureContext *tc) { delete gtc; } -#if 1 - void DXGraphicsStateGuardian7:: -copy_texture(TextureContext *tc, const DisplayRegion *dr) { - dxgsg7_cat.fatal() << "DX copy_texture unimplemented!!!"; +copy_texture(Texture *tex, const DisplayRegion *dr) { + dxgsg7_cat.error() << "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: DXGraphicsStateGuardian7::copy_texture -// Access: Public, Virtual -// Description: Copy the pixel region indicated by the display -// region from the framebuffer into texture memory -//////////////////////////////////////////////////////////////////// -void DXGraphicsStateGuardian7:: -copy_texture(TextureContext *tc, const DisplayRegion *dr) { - - nassertv(tc != NULL && dr != NULL); - - Texture *tex = tc->_texture; - - // 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; - } - - PixelBuffer *pb = tex->_pbuffer; - - pb->set_xorg(xo); - pb->set_yorg(yo); - pb->set_xsize(w); - pb->set_ysize(h); - - - 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() ); -} -#endif - //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian7::copy_texture // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian7:: -copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) { - dxgsg7_cat.fatal() << "DX copy_texture unimplemented!!!"; - return; - - set_read_buffer(rb); - copy_texture(tc, dr); +copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb) { + dxgsg7_cat.error() << "DX copy_texture unimplemented!!!"; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/dxgsg7/dxGraphicsStateGuardian7.h b/panda/src/dxgsg7/dxGraphicsStateGuardian7.h index 17b3302662..66765bf1c0 100644 --- a/panda/src/dxgsg7/dxGraphicsStateGuardian7.h +++ b/panda/src/dxgsg7/dxGraphicsStateGuardian7.h @@ -98,8 +98,8 @@ public: virtual void apply_texture(TextureContext *tc); virtual void release_texture(TextureContext *tc); - virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr); - virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr, + virtual void copy_texture(Texture *tex, const DisplayRegion *dr); + virtual void copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb); virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index c9bda34d1f..b700c9cc96 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -29,6 +29,7 @@ #include "graphicsChannel.h" #include "lens.h" #include "perspectiveLens.h" +#include "orthographicLens.h" #include "ambientLight.h" #include "directionalLight.h" #include "pointLight.h" @@ -1040,17 +1041,17 @@ prepare_lens() { LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) * projection_mat; - float vfov = _current_lens->get_vfov(); float nearf = _current_lens->get_near(); float farf = _current_lens->get_far(); //dxgsg8_cat.debug() << new_projection_mat << endl; HRESULT hr; - if (_current_lens->get_type().get_name() == "PerspectiveLens") { -#if 0 + if (false && _current_lens->is_of_type(PerspectiveLens::get_class_type())) { + /* const LMatrix4f mat_temp; + float vfov = _current_lens->get_vfov(); float hfov = _current_lens->get_hfov(); float ar = _current_lens->get_aspect_ratio(); float nearf = _current_lens->get_near(); @@ -1063,25 +1064,32 @@ prepare_lens() { hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)mat_temp.get_data()); dxgsg8_cat.debug() << mat_temp << endl; -#endif - - ((D3DXMATRIX*)new_projection_mat.get_data())->_33 = farf / (farf-nearf); - ((D3DXMATRIX*)new_projection_mat.get_data())->_43 = -nearf * farf / (farf - nearf); + */ + + new_projection_mat(2, 2) = farf / (farf-nearf); + new_projection_mat(3, 2) = -nearf * farf / (farf - nearf); hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)new_projection_mat.get_data()); //dxgsg8_cat.debug() << new_projection_mat << endl; //dxgsg8_cat.debug() << "using perspective projection" << endl; - } - else { - ((D3DXMATRIX*)new_projection_mat.get_data())->_33 = 1/(farf-nearf); - ((D3DXMATRIX*)new_projection_mat.get_data())->_43 = -nearf/(farf-nearf); + + } else if (false && _current_lens->is_of_type(OrthographicLens::get_class_type())) { + new_projection_mat(2, 2) = 1 / (farf - nearf); + new_projection_mat(3, 2) = -nearf / (farf - nearf); hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)new_projection_mat.get_data()); //dxgsg8_cat.debug() << new_projection_mat << endl; //dxgsg8_cat.debug() << "using ortho projection" << endl; + + } else { + hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION, + (D3DMATRIX*)new_projection_mat.get_data()); + //dxgsg8_cat.debug() << new_projection_mat << endl; + //dxgsg8_cat.debug() << "using matrix projection" << endl; } + return SUCCEEDED(hr); } @@ -3021,17 +3029,19 @@ prepare_texture(Texture *tex) { void DXGraphicsStateGuardian8:: apply_texture(TextureContext *tc) { if (tc==NULL) { - return; // use enable_texturing to disable/enable + // The texture wasn't bound properly or something, so ensure + // texturing is disabled and just return. + enable_texturing(false); + return; } + #ifdef DO_PSTATS add_to_texture_record(tc); #endif -// bind_texture(tc); - -// specify_texture(tc->_texture); - // Note: if this code changes, make sure to change initialization SetTSS code in dx_init as well - // so DX TSS renderstate matches dxgsg state + // Note: if this code changes, make sure to change initialization + // SetTSS code in dx_init as well so DX TSS renderstate matches + // dxgsg state DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc); @@ -3057,7 +3067,6 @@ apply_texture(TextureContext *tc) { // Oops, we can't re-create the texture for some reason. dxgsg8_cat.error() << "Unable to re-create texture " << *dtc->_texture << endl; - release_texture(dtc); enable_texturing(false); return; } @@ -3065,7 +3074,8 @@ apply_texture(TextureContext *tc) { dtc->clear_dirty_flags(); } else { if(_pCurTexContext == dtc) { - return; // tex already set (and possible problem in state-sorting?) + enable_texturing(true); + return; } } @@ -3171,6 +3181,7 @@ apply_texture(TextureContext *tc) { #endif _pCurTexContext = dtc; // enable_texturing needs this + enable_texturing(true); } //////////////////////////////////////////////////////////////////// @@ -3189,30 +3200,34 @@ release_texture(TextureContext *tc) { // copies current display region in framebuffer to the texture // usually its more efficient to do SetRenderTgt void DXGraphicsStateGuardian8:: -copy_texture(TextureContext *tc, const DisplayRegion *dr) { +copy_texture(Texture *tex, const DisplayRegion *dr) { HRESULT hr; int xo, yo, w, h; dr->get_region_pixels(xo, yo, w, h); - DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc); - PixelBuffer *pb = dtc->_tex->_pbuffer; + PixelBuffer *pb = tex->_pbuffer; pb->set_size(0,0,w-xo,h-yo); + TextureContext *tc = tex->prepare_now(get_prepared_objects(), this); + if (tc == (TextureContext *)NULL) { + return; + } + DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc); + IDirect3DSurface8 *pTexSurfaceLev0,*pCurRenderTarget; hr = dtc->_pD3DTexture8->GetSurfaceLevel(0,&pTexSurfaceLev0); if(FAILED(hr)) { dxgsg8_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr); - exit(1); + return; } hr = _pD3DDevice->GetRenderTarget(&pCurRenderTarget); if(FAILED(hr)) { dxgsg8_cat.error() << "GetRenderTgt failed in copy_texture" << D3DERRORSTRING(hr); - exit(1); + return; } - RECT SrcRect; SrcRect.left = xo; @@ -3224,7 +3239,7 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) { hr = _pD3DDevice->CopyRects(pCurRenderTarget,&SrcRect,1,pTexSurfaceLev0,NULL); if(FAILED(hr)) { dxgsg8_cat.error() << "CopyRects failed in copy_texture" << D3DERRORSTRING(hr); - exit(1); + return; } SAFE_RELEASE(pCurRenderTarget); @@ -3238,9 +3253,9 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) { // Description: //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian8:: -copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) { +copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb) { set_read_buffer(rb); - copy_texture(tc, dr); + copy_texture(tex, dr); } //////////////////////////////////////////////////////////////////// @@ -3561,20 +3576,15 @@ void DXGraphicsStateGuardian8::SetTextureBlendMode(TextureApplyAttrib::Mode TexB //////////////////////////////////////////////////////////////////// INLINE void DXGraphicsStateGuardian8:: enable_texturing(bool val) { -// if (_texturing_enabled == val) { // this check is mostly for internal gsg calls, panda already screens out redundant state changes -// return; -// } + _texturing_enabled = val; + + if (!val) { + _pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); - _texturing_enabled = val; - -// assert(_pCurTexContext!=NULL); we're definitely called with it NULL for both true and false -// I'm going to allow enabling texturing even if no tex has been set yet, seems to cause no probs - - if (val == false) { - _pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); - } else { - SetTextureBlendMode(_CurTexBlendMode,true); - } + } else { + nassertv(_pCurTexContext!=NULL); + SetTextureBlendMode(_CurTexBlendMode,true); + } } //////////////////////////////////////////////////////////////////// @@ -3643,7 +3653,6 @@ issue_texture(const TextureAttrib *attrib) { if (attrib->is_off()) { enable_texturing(false); } else { - enable_texturing(true); Texture *tex = attrib->get_texture(); nassertv(tex != (Texture *)NULL); @@ -4494,7 +4503,7 @@ save_frame_buffer(const RenderBuffer &buffer, if (buffer._buffer_type & RenderBuffer::T_back) { // Save the color buffer. sfb->_back_rgba = new Texture; - copy_texture(sfb->_back_rgba->prepare(this), dr, buffer); + copy_texture(sfb->_back_rgba, dr, buffer); } return sfb; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index f31d2bc3a2..e36edea8fe 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -102,8 +102,8 @@ public: virtual void apply_texture(TextureContext *tc); virtual void release_texture(TextureContext *tc); - virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr); - virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr, + virtual void copy_texture(Texture *tex, const DisplayRegion *dr); + virtual void copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb); virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb); diff --git a/panda/src/dxgsg8/dxTextureContext8.cxx b/panda/src/dxgsg8/dxTextureContext8.cxx index 4e8be25f18..cd86802790 100644 --- a/panda/src/dxgsg8/dxTextureContext8.cxx +++ b/panda/src/dxgsg8/dxTextureContext8.cxx @@ -1429,17 +1429,9 @@ IDirect3DTexture8 *DXTextureContext8::CreateTexture(DXScreenData &scrn) { #endif #endif - // Note: user may want to create an empty "texture" that will be written to by rendering and copy operations. - // this will never have a backing store of main memory in panda fmt, and on disk in a file. - // so for this case, you dont want to call FillDDSurf. - // need a better way for user to indicate this usage than lack of ram_image, because it conflicts - // with the multi-open case mentioned below - - if(_texture->has_ram_image()) { - hr = FillDDSurfTexturePixels(); - if(FAILED(hr)) { - goto error_exit; - } + hr = FillDDSurfTexturePixels(); + if(FAILED(hr)) { + goto error_exit; } // PRINT_REFCNT(dxgsg8,scrn.pD3D8); @@ -1458,27 +1450,12 @@ FillDDSurfTexturePixels(void) { HRESULT hr=E_FAIL; assert(IS_VALID_PTR(_texture)); - // It is a mistake to insist that has_ram_image() be true before - // we try to load the texture. This function only indicates - // whether the texture image is already present in main ram or - // not; it has nothing to do with whether get_ram_image() will - // fail. When there is only one GSG in the world, has_ram_image() - // will generally be true whenever the texture has not been loaded - // before, but when there are multiple GSG's (for instance, if we - // close and reopen the main window), then has_ram_image() is - // largely irrelevant to the GSG. - /* - if(!_texture->has_ram_image()) { - dxgsg8_cat.warning() << "CreateTexture: tried to fill surface that has no ram image!\n"; - return S_OK; - } - */ - PixelBuffer *pbuf = _texture->get_ram_image(); if (pbuf == (PixelBuffer *)NULL) { - dxgsg8_cat.fatal() << "CreateTexture: get_ram_image() failed\n"; - // The texture doesn't have an image to load. - return E_FAIL; + // The texture doesn't have an image to load. That's ok; it + // might be a texture we've rendered to by frame buffer + // operations or something. + return S_OK; } assert(IS_VALID_PTR(_pD3DTexture8)); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index a0f0e22f07..a64e534ffc 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -29,6 +29,7 @@ #include "graphicsChannel.h" #include "lens.h" #include "perspectiveLens.h" +#include "orthographicLens.h" #include "ambientLight.h" #include "directionalLight.h" #include "pointLight.h" @@ -1055,17 +1056,17 @@ prepare_lens() { LMatrix4f::convert_mat(CS_yup_left, _current_lens->get_coordinate_system()) * projection_mat; - float vfov = _current_lens->get_vfov(); float nearf = _current_lens->get_near(); float farf = _current_lens->get_far(); //dxgsg9_cat.debug() << new_projection_mat << endl; HRESULT hr; - if (_current_lens->get_type().get_name() == "PerspectiveLens") { -#if 0 + if (false && _current_lens->is_of_type(PerspectiveLens::get_class_type())) { + /* const LMatrix4f mat_temp; + float vfov = _current_lens->get_vfov(); float hfov = _current_lens->get_hfov(); float ar = _current_lens->get_aspect_ratio(); float nearf = _current_lens->get_near(); @@ -1078,25 +1079,32 @@ prepare_lens() { hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)mat_temp.get_data()); dxgsg9_cat.debug() << mat_temp << endl; -#endif - - ((D3DXMATRIX*)new_projection_mat.get_data())->_33 = farf / (farf-nearf); - ((D3DXMATRIX*)new_projection_mat.get_data())->_43 = -nearf * farf / (farf - nearf); + */ + + new_projection_mat(2, 2) = farf / (farf-nearf); + new_projection_mat(3, 2) = -nearf * farf / (farf - nearf); hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)new_projection_mat.get_data()); //dxgsg9_cat.debug() << new_projection_mat << endl; //dxgsg9_cat.debug() << "using perspective projection" << endl; - } - else { - ((D3DXMATRIX*)new_projection_mat.get_data())->_33 = 1/(farf-nearf); - ((D3DXMATRIX*)new_projection_mat.get_data())->_43 = -nearf/(farf-nearf); + + } else if (false && _current_lens->is_of_type(OrthographicLens::get_class_type())) { + new_projection_mat(2, 2) = 1 / (farf - nearf); + new_projection_mat(3, 2) = -nearf / (farf - nearf); hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)new_projection_mat.get_data()); //dxgsg9_cat.debug() << new_projection_mat << endl; //dxgsg9_cat.debug() << "using ortho projection" << endl; + + } else { + hr = _pD3DDevice->SetTransform(D3DTS_PROJECTION, + (D3DMATRIX*)new_projection_mat.get_data()); + //dxgsg9_cat.debug() << new_projection_mat << endl; + //dxgsg9_cat.debug() << "using matrix projection" << endl; } + return SUCCEEDED(hr); } @@ -3037,17 +3045,19 @@ prepare_texture(Texture *tex) { void DXGraphicsStateGuardian9:: apply_texture(TextureContext *tc) { if (tc==NULL) { - return; // use enable_texturing to disable/enable + // The texture wasn't bound properly or something, so ensure + // texturing is disabled and just return. + enable_texturing(false); + return; } + #ifdef DO_PSTATS add_to_texture_record(tc); #endif -// bind_texture(tc); - -// specify_texture(tc->_texture); - // Note: if this code changes, make sure to change initialization SetTSS code in dx_init as well - // so DX TSS renderstate matches dxgsg state + // Note: if this code changes, make sure to change initialization + // SetTSS code in dx_init as well so DX TSS renderstate matches + // dxgsg state DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc); @@ -3073,7 +3083,6 @@ apply_texture(TextureContext *tc) { // Oops, we can't re-create the texture for some reason. dxgsg9_cat.error() << "Unable to re-create texture " << *dtc->_texture << endl; - release_texture(dtc); enable_texturing(false); return; } @@ -3081,7 +3090,8 @@ apply_texture(TextureContext *tc) { dtc->clear_dirty_flags(); } else { if(_pCurTexContext == dtc) { - return; // tex already set (and possible problem in state-sorting?) + enable_texturing(true); + return; } } @@ -3187,6 +3197,7 @@ apply_texture(TextureContext *tc) { #endif _pCurTexContext = dtc; // enable_texturing needs this + enable_texturing(true); } //////////////////////////////////////////////////////////////////// @@ -3205,30 +3216,34 @@ release_texture(TextureContext *tc) { // copies current display region in framebuffer to the texture // usually its more efficient to do SetRenderTgt void DXGraphicsStateGuardian9:: -copy_texture(TextureContext *tc, const DisplayRegion *dr) { +copy_texture(Texture *tex, const DisplayRegion *dr) { HRESULT hr; int xo, yo, w, h; dr->get_region_pixels(xo, yo, w, h); - DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc); - PixelBuffer *pb = dtc->_tex->_pbuffer; + PixelBuffer *pb = tex->_pbuffer; pb->set_size(0,0,w-xo,h-yo); + TextureContext *tc = tex->prepare_now(get_prepared_objects(), this); + if (tc == (TextureContext *)NULL) { + return; + } + DXTextureContext9 *dtc = DCAST(DXTextureContext9, tc); + IDirect3DSurface9 *pTexSurfaceLev0,*pCurRenderTarget; hr = dtc->_pD3DTexture9->GetSurfaceLevel(0,&pTexSurfaceLev0); if(FAILED(hr)) { dxgsg9_cat.error() << "GetSurfaceLev failed in copy_texture" << D3DERRORSTRING(hr); - exit(1); + return; } hr = _pD3DDevice->GetRenderTarget(0, &pCurRenderTarget); if(FAILED(hr)) { dxgsg9_cat.error() << "GetRenderTgt failed in copy_texture" << D3DERRORSTRING(hr); - exit(1); + return; } - RECT SrcRect; SrcRect.left = xo; @@ -3240,8 +3255,8 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) { hr = _pD3DDevice->UpdateSurface(pCurRenderTarget,&SrcRect,pTexSurfaceLev0,NULL); if(FAILED(hr)) { - dxgsg9_cat.error() << "CopyRects failed in copy_texture" << D3DERRORSTRING(hr); - exit(1); + dxgsg9_cat.error() << "UpdateSurface failed in copy_texture" << D3DERRORSTRING(hr); + return; } SAFE_RELEASE(pCurRenderTarget); @@ -3255,9 +3270,9 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) { // Description: //////////////////////////////////////////////////////////////////// void DXGraphicsStateGuardian9:: -copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) { +copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb) { set_read_buffer(rb); - copy_texture(tc, dr); + copy_texture(tex, dr); } //////////////////////////////////////////////////////////////////// @@ -3578,20 +3593,15 @@ void DXGraphicsStateGuardian9::SetTextureBlendMode(TextureApplyAttrib::Mode TexB //////////////////////////////////////////////////////////////////// INLINE void DXGraphicsStateGuardian9:: enable_texturing(bool val) { -// if (_texturing_enabled == val) { // this check is mostly for internal gsg calls, panda already screens out redundant state changes -// return; -// } + _texturing_enabled = val; + + if (!val) { + _pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); - _texturing_enabled = val; - -// assert(_pCurTexContext!=NULL); we're definitely called with it NULL for both true and false -// I'm going to allow enabling texturing even if no tex has been set yet, seems to cause no probs - - if (val == false) { - _pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE); - } else { - SetTextureBlendMode(_CurTexBlendMode,true); - } + } else { + nassertv(_pCurTexContext!=NULL); + SetTextureBlendMode(_CurTexBlendMode,true); + } } //////////////////////////////////////////////////////////////////// @@ -3660,7 +3670,6 @@ issue_texture(const TextureAttrib *attrib) { if (attrib->is_off()) { enable_texturing(false); } else { - enable_texturing(true); Texture *tex = attrib->get_texture(); nassertv(tex != (Texture *)NULL); @@ -4511,7 +4520,7 @@ save_frame_buffer(const RenderBuffer &buffer, if (buffer._buffer_type & RenderBuffer::T_back) { // Save the color buffer. sfb->_back_rgba = new Texture; - copy_texture(sfb->_back_rgba->prepare(this), dr, buffer); + copy_texture(sfb->_back_rgba, dr, buffer); } return sfb; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 4b94fea117..1a8c4cd6e1 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -102,8 +102,8 @@ public: virtual void apply_texture(TextureContext *tc); virtual void release_texture(TextureContext *tc); - virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr); - virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr, + virtual void copy_texture(Texture *tex, const DisplayRegion *dr); + virtual void copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb); virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb); diff --git a/panda/src/dxgsg9/dxTextureContext9.cxx b/panda/src/dxgsg9/dxTextureContext9.cxx index b61d521c12..8edef8eae9 100755 --- a/panda/src/dxgsg9/dxTextureContext9.cxx +++ b/panda/src/dxgsg9/dxTextureContext9.cxx @@ -1429,17 +1429,9 @@ IDirect3DTexture9 *DXTextureContext9::CreateTexture(DXScreenData &scrn) { #endif #endif - // Note: user may want to create an empty "texture" that will be written to by rendering and copy operations. - // this will never have a backing store of main memory in panda fmt, and on disk in a file. - // so for this case, you dont want to call FillDDSurf. - // need a better way for user to indicate this usage than lack of ram_image, because it conflicts - // with the multi-open case mentioned below - - if(_texture->has_ram_image()) { - hr = FillDDSurfTexturePixels(); - if(FAILED(hr)) { - goto error_exit; - } + hr = FillDDSurfTexturePixels(); + if(FAILED(hr)) { + goto error_exit; } // PRINT_REFCNT(dxgsg9,scrn.pD3D9); @@ -1458,27 +1450,12 @@ FillDDSurfTexturePixels(void) { HRESULT hr=E_FAIL; assert(IS_VALID_PTR(_texture)); - // It is a mistake to insist that has_ram_image() be true before - // we try to load the texture. This function only indicates - // whether the texture image is already present in main ram or - // not; it has nothing to do with whether get_ram_image() will - // fail. When there is only one GSG in the world, has_ram_image() - // will generally be true whenever the texture has not been loaded - // before, but when there are multiple GSG's (for instance, if we - // close and reopen the main window), then has_ram_image() is - // largely irrelevant to the GSG. - /* - if(!_texture->has_ram_image()) { - dxgsg9_cat.warning() << "CreateTexture: tried to fill surface that has no ram image!\n"; - return S_OK; - } - */ - PixelBuffer *pbuf = _texture->get_ram_image(); if (pbuf == (PixelBuffer *)NULL) { - dxgsg9_cat.fatal() << "CreateTexture: get_ram_image() failed\n"; - // The texture doesn't have an image to load. - return E_FAIL; + // The texture doesn't have an image to load. That's ok; it + // might be a texture we've rendered to by frame buffer + // operations or something. + return S_OK; } assert(IS_VALID_PTR(_pD3DTexture9)); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index d5dbc117cd..08a9dda76b 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1907,9 +1907,8 @@ static int binary_log_cap(const int x) { // region from the framebuffer into texture memory //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -copy_texture(TextureContext *tc, const DisplayRegion *dr) { - nassertv(tc != NULL && dr != NULL); - Texture *tex = tc->_texture; +copy_texture(Texture *tex, const DisplayRegion *dr) { + nassertv(tex != NULL && dr != NULL); int xo, yo, w, h; @@ -1937,11 +1936,13 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) { PixelBuffer *pb = tex->_pbuffer; pb->set_size(xo,yo,w,h); + TextureContext *tc = tex->prepare_now(get_prepared_objects(), this); + nassertv(tc != (TextureContext *)NULL); bind_texture(tc); GLP(CopyTexImage2D)(GL_TEXTURE_2D, 0, - get_internal_image_format(pb->get_format()), - xo, yo, w, h, pb->get_border()); + get_internal_image_format(pb->get_format()), + xo, yo, w, h, pb->get_border()); // Clear the internal texture state, since we've just monkeyed with it. modify_state(get_untextured_state()); @@ -1953,9 +1954,9 @@ copy_texture(TextureContext *tc, const DisplayRegion *dr) { // Description: //////////////////////////////////////////////////////////////////// void CLP(GraphicsStateGuardian):: -copy_texture(TextureContext *tc, const DisplayRegion *dr, const RenderBuffer &rb) { +copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb) { set_read_buffer(rb); - copy_texture(tc, dr); + copy_texture(tex, dr); } //////////////////////////////////////////////////////////////////// @@ -3969,8 +3970,7 @@ save_frame_buffer(const RenderBuffer &buffer, if (buffer._buffer_type & RenderBuffer::T_back) { // Save the color buffer. sfb->_back_rgba = new Texture; - TextureContext *tc = sfb->_back_rgba->prepare_now(_prepared_objects, this); - copy_texture(tc, dr, buffer); + copy_texture(sfb->_back_rgba, dr, buffer); } return sfb; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 85a51ce0df..c92057e012 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -75,8 +75,8 @@ public: GeomNodeContext *gnc); virtual void release_geom_node(GeomNodeContext *gnc); - virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr); - virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr, + virtual void copy_texture(Texture *tex, const DisplayRegion *dr); + virtual void copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb); virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb); diff --git a/panda/src/gobj/preparedGraphicsObjects.cxx b/panda/src/gobj/preparedGraphicsObjects.cxx index 8756bbf7e2..704003d81b 100644 --- a/panda/src/gobj/preparedGraphicsObjects.cxx +++ b/panda/src/gobj/preparedGraphicsObjects.cxx @@ -196,10 +196,13 @@ prepare_texture_now(Texture *tex, GraphicsStateGuardianBase *gsg) { // all shared anyway). TextureContext *tc = gsg->prepare_texture(tex); - bool prepared = _prepared_textures.insert(tc).second; - nassertr(prepared, tc); + if (tc != (TextureContext *)NULL) { + bool prepared = _prepared_textures.insert(tc).second; + nassertr(prepared, tc); + + _total_texusage_pcollector.add_level(tc->estimate_texture_memory()); + } - _total_texusage_pcollector.add_level(tc->estimate_texture_memory()); return tc; } diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index c510a17b27..349c97da08 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -502,26 +502,27 @@ prepare_now(PreparedGraphicsObjects *prepared_objects, } TextureContext *tc = prepared_objects->prepare_texture_now(this, gsg); - _contexts[prepared_objects] = tc; + if (tc != (TextureContext *)NULL) { + _contexts[prepared_objects] = tc; - // Now that we have a new TextureContext with zero dirty flags, our - // intersection of all dirty flags must be zero. This doesn't mean - // that some other contexts aren't still dirty, but at least one - // context isn't. - _all_dirty_flags = 0; + // Now that we have a new TextureContext with zero dirty flags, our + // intersection of all dirty flags must be zero. This doesn't mean + // that some other contexts aren't still dirty, but at least one + // context isn't. + _all_dirty_flags = 0; - if (!keep_texture_ram && !_keep_ram_image) { - // Once we have prepared the texture, we can generally safely - // remove the pixels from main RAM. The GSG is now responsible - // for remembering what it looks like. + if (!keep_texture_ram && !_keep_ram_image) { + // Once we have prepared the texture, we can generally safely + // remove the pixels from main RAM. The GSG is now responsible + // for remembering what it looks like. - if (gobj_cat.is_debug()) { - gobj_cat.debug() - << "Dumping RAM for texture " << get_name() << "\n"; + if (gobj_cat.is_debug()) { + gobj_cat.debug() + << "Dumping RAM for texture " << get_name() << "\n"; + } + _pbuffer->_image.clear(); } - _pbuffer->_image.clear(); } - return tc; } diff --git a/panda/src/gsgbase/graphicsStateGuardianBase.h b/panda/src/gsgbase/graphicsStateGuardianBase.h index 8fe18d8101..c165148962 100644 --- a/panda/src/gsgbase/graphicsStateGuardianBase.h +++ b/panda/src/gsgbase/graphicsStateGuardianBase.h @@ -165,8 +165,8 @@ public: virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc)=0; virtual void draw_sphere(GeomSphere *geom, GeomContext *gc)=0; - virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr)=0; - virtual void copy_texture(TextureContext *tc, const DisplayRegion *dr, + virtual void copy_texture(Texture *tex, const DisplayRegion *dr)=0; + virtual void copy_texture(Texture *tex, const DisplayRegion *dr, const RenderBuffer &rb)=0; virtual void texture_to_pixel_buffer(TextureContext *tc, PixelBuffer *pb)=0; diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.cxx b/panda/src/wgldisplay/wglGraphicsBuffer.cxx index e8099009a3..041666db0f 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.cxx +++ b/panda/src/wgldisplay/wglGraphicsBuffer.cxx @@ -130,8 +130,7 @@ end_frame() { DisplayRegion dr(this, _x_size, _y_size); RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type()); - TextureContext *tc = get_texture()->prepare_now(_gsg->get_prepared_objects(), _gsg); - _gsg->copy_texture(tc, &dr, buffer); + _gsg->copy_texture(get_texture(), &dr, buffer); } }