make multipass work (sort of) on dx8

This commit is contained in:
David Rose 2004-03-04 15:48:19 +00:00
parent 0732fe4122
commit 0e084fe310
16 changed files with 170 additions and 254 deletions

View File

@ -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.

View File

@ -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);
}

View File

@ -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!!!";
}
////////////////////////////////////////////////////////////////////

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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));

View File

@ -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;

View File

@ -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);

View File

@ -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));

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}
}